How do I check that the model is correct for an object read from the database.
var myModelObject = theDB.myDbContext.myModelObject.Find(1234);
Now I would like to control if it is correct according to the rules / attributy in the model... but how?
It is expected that data read from database are correct according to validation rules because that validation rules also defines the mapping. Inconsistency can lead in some cases to exception in object materialization.
If you want to executed validation based on data annotations manually you can use:
using System.ComponentModel.DataAnnotations;
var results = new List<ValidationResult>();
var context = new ValidationContext(myModelObject, null, null);
bool isValid = Validator.TryValidateObject(myModelObject, context, results, true);
Related
My TValue object has foreign key related objects, which has null values when posting; I am having the logic to set the FK objects in the repository. The issue I am facing is that API controller is not getting called when FK objects have all fields null. Please see screenshot. The same code works if I set the value for all but the ID field of the FK objects from the front end.
Is the issue because Json serializer checking for nulls? I have also tried to set the null check ignore option. I am not getting an error on PostAsJsonAsync and the control simply goes to the next line of code
return await result.Content.ReadFromJsonAsync();
without calling the API controller and send an exception
public async Task<SubContract> AddSubContract(SubContract subContract)
{
/* On the injected httpClient, call the PostAsJsonAsync method and pass the subContractObject
* We also need to specifi the api Uri in the parameter list */
JsonSerializerOptions option = new()
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
var result = await httpClient
.PostAsJsonAsync<SubContract>("api/SubContracts", subContract, option);
//Use the content object and ReadFromJsonSync method and typecast it to <SubContract>
return await result.Content.ReadFromJsonAsync<SubContract>();
}
Screenshot
--- Further observations ---
#Serge Thanks for the response. You are right, I am using .Net 6. I have now commented out the nullable but I still have the same issue. Further, I tried to change the function to PostAsync instead of PostAsJsonAsync; below is the new code
// ---- Post Asysc Option -----
var subContractSeralized = JsonSerializer.Serialize(subContract, option);
var stringContent = new StringContent(subContractSeralized,
encoding: System.Text.Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync("api/subcontract", stringContent);
return await response.Content.ReadFromJsonAsync<SubContract>();
I initially thought it was a serialization issue because of the nulls in the nested object but when I debug the new code, I get the below result
subContractSerealized = '{"Id":0,"Name":"Aquatic-Repairs","Status":"In-Progress","WorkTypeId":1002,"WorkType":{"Id":0},"SiteId":3,"Site":{"Id":0},"OrganizationId":3,"Organization":{"Id":0}}'
If you compare this with the Debug screen shot in my first post, you can see that the null value fields in the nested objects are omitted out
Response StatusCode = “Not Found-404”
I am not sure how Response Status code is obtained as the API is not called. I.e. httpClient.PostAsync does not transfer control to the API and my debug breakpoint is not hit.
I tried the same code for an Entity model that has no nested foreign key related objects and it works fine and I am able to add the record to the DB. I have the “Required” validation set on the field properties of the entity models; however, after the API call, I have my repository that is taking care of it. So, I doubt that is an issue. In any case, the code is not even hitting the API and simply returns an 404 NotFound on httpClient.PostAsync.
you must be using Net 6 API, and it causes a validation error. Try to comment Nullable in your API project (your serializer option is not working in this case)
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<!--<Nullable>enable</Nullable>-->
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
I do not have any specific id available in the response JSON body (I can not change the body). That is why I can not use
RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:....
mapping.identificationAttributes = #[#"specificId"];
Is it possible to configure the mapping in such a way that there is no new NSManagedObject created but always the previous one is updated, if such object exists?
I would like to fetch data for ui update from a single response object (of specific class). Yes I can delete the previous instance of the response before the new one is received but the approach required in this question is cleaner and I do not need to keep the reference/id to the response entity.
I am reading the documentation for RKManagedObjectRequestOperation but it is not clear whether this approach is supported by Restkit.
Thank you for comment.
I have made a hack that is not acceptable but it works: I am using a special attribute in each special "singleton" NSManagedObject's subclass: e.g. unique which I use for the identification on the class level:
In RKManagedObjectMappingOperationDataSource there is the condition modified to allow passing entities with the special unique attribute:
// If we have found the entity identification attributes, try to find an existing instance to update
if ([entityIdentifierAttributes count] || [self.managedObjectCache isUniqueEntityClass:entity])...
In RKFetchRequestManagedObjectCache and in RKInMemoryManagedObjectCache there is the new method defined:
- (BOOL) isUniqueEntityClass:(NSEntityDescription*)entity {
__block BOOL isUniqueEntityClass = NO;
[[[entity attributesByName] allKeys] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
isUniqueEntityClass = [obj isEqualToString:#"unique"];
if(isUniqueEntityClass) {
*stop = YES;
return;
}
}];
return isUniqueEntityClass;
}
In the method
- (NSSet *)managedObjectsWithEntity:(NSEntityDescription *)entity
attributeValues:(NSDictionary *)attributeValues
inManagedObjectContext:(NSManagedObjectContext *)managedObjectContext...
isUniqueEntityClass decides if we should use predicate based on attributeValues to fetch the entity or directly fetch the entity without the predicate.
I have all the POCO entities produced from my database. I created an IXXX interface, a XXX class to define the structure of the table I want to return from my service, and a XXX class to do the query and the return part for the interface.
My question is regarding the elements I need to add to this setup in order to return clean JSON from my web service.
I'm a beginner so all points of view are welcome. Thanks!
You can define XXXDto classes which are having a clean format for your client needs. And then map the domain/endity classes to Dto objects and serialize them using WCF.
Or you can create WCF OData services to expose the service as OData source.
try this:
To return Json data [in EF]:
add reference 'System.Runtime.Serialization' to the project
write code like below:
using System.Web.Script.Serialization;
public string getValuesJson()
{
JavaScriptSerializer js = new JavaScriptSerializer();
MyDBEntities ctx = new MyDBEntities();
var myValues = (from m in ctx.TestEntity
where (m.id == 22)
select m).ToList();
return js.Serialize(myValues);
}
you can also check whether Json string is valid or not at http://jsonlint.com/
I know there are a bunch of questions on this already - I'm having a hard time sorting out which ones are related to problems with versions, and which ones are related to jQuery (which I'm not using), etc. I have the MVC4 RC (4.0.20505.0), Visual Studio 2010 Ultimate SP1.
I have a complex type in my model:
public HttpResponseMessage Post([FromUri]Person person)
{
TableStorageHelper personHelper = new TableStorageHelper();
personHelper.Save(personHelper.GetTableNameForType("Person"), person);
var response = Request.CreateResponse<Person>(HttpStatusCode.Created, person);
return response;
}
I am passing in this JSON string - using Fiddler mostly, but also trying from code in another controller (trying to do all testing locally just to verify that I can get values in the object received by the controller):
The JSON:
{"FirstName":"Andy","LastName":"Schultz","PartitionKey":"USW","RowKey":"per-928c8f74-2efd-4fc2-a71c-fb3ea8acc6d7","NickName":null,"FullName":"Andy Schultz","Description":null,"ImageLocation":null,"Region":"USW","CommentsAboutMe":{"Comments":[]},"CommentsByMe":{"Comments":[]}}
All of the properties here do exist in the class.
The code from the other controller:
HttpWebRequest request = HttpWebRequest.Create("http://127.0.0.2:8080/api/persons/") as HttpWebRequest;
request.Method = "POST";
request.ContentType = "text/json";
using (var writer = new StreamWriter(request.GetRequestStream()))
{
Person person = new Person("Andy", "Schultz", "USW");
Formatting formatting = new Formatting();
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
string json = JsonConvert.SerializeObject(person, formatting, settings);
writer.Write(json);
}
Every time, I get an empty Person object in my controller (I'm debugging on the very first line there). Every value is NULL.
You may have noticed the [FromUri] attribute on my controller - I had to do that to get around an error telling me there was no ModelBinder for an undefined type, but I'm not sure that it's correct - I'm not passing any info in the Uri, it's in the body, as you can tell.
Thank you Mike Stall: http://blogs.msdn.com/b/jmstall/archive/2012/04/16/how-webapi-does-parameter-binding.aspx
The [FromUri] attribute did indeed tell my controller to read the uri and not the request body looking for the parameter for my controller method. It wasn't there, so everything was null.
The error that adding that attribute fixed, which said there was no formatter defined for a type of content Undefined, was caused by my improperly declaring the content-type of the request. The correct way was "Content-Type: text/json; charset=utf-8
I have generated a LinqtoSQL mapping xml file, which I have a valid XSD schema that I check to make sure the XML is correct.
Now I want to check that the field type match the Model/Interface
for example:
checking that the nullable fields are nullable
that int are int etc
anyone got any ideas if I can do this?
One way I have found is to just pass in a new object without setting anything:
[Test]
[Rollback]
public void Should_take_a_Document_with_nulls()
{
// Arrange
var repository = GetRepository();
var contact = new Contact();
// Act
repository.Save(contact);
// Assert
}