Return simple objects to entities for serialization

I am trying to use Linq for Sql and EF in my ASP.NET MVC application. After switching to EF, I realized that my XML / JSON serialization output has extra speed.

XML:

<Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <EntityKey> <EntitySetName>Persons</EntitySetName> <EntityContainerName>PersonEntities</EntityContainerName> <EntityKeyValues> <EntityKeyMember> <Key>Id</Key> <Value xsi:type="xsd:int">1</Value> </EntityKeyMember> </EntityKeyValues> </EntityKey> <Id>1</Id> <Name>John</Name> </Test> 

JSON:

 {"Id":1,"Name":"John","EntityState":2,"EntityKey"{"EntitySetName":"Persons","EntityContainerName":"PersonEntities","EntityKeyValues":[{"Key":"Id","Value":1}],"IsTemporary":false}} 

Instead, I would like my conclusion to be:

 {"Id":1, "Name":"John"} 

My EF request to retrieve an object:

 Tests.First(t => t.Id == testId); 
+4
source share
3 answers

You can generate the JSON result in your controller as follows:

 public JsonResult Person(int id) { var person = PersonRepository.FindByID(id); var result = new { Id = person.Id, Name = person.Name }; return Json(result); } 

This will limit the DTO, which is serialized, to contain only the desired values.

Edit: As a paratic answer to your question; you can create a simpler PersonViewModel (DTO) class to which you can map properties. As John Saunders noted in his Automapper answer, this is a good way to simplify copying property values ​​from an EF Person instance:

A modified action method might look like this:

 public JsonResult Person(int id) { var person = PersonRepository.FindByID(id); var dto = Mapper.Map<Person, PersonViewModel>(person); return Json(dto); } 

The only other option I can think of is to use reflection to modify the DataMemberAttributes in the Person object to suppress the EntityKey property.

+7
source

Another approach to working on this is to use the JavascriptSerializer ScriptIgnore attribute and create a partial class for the object in question, add the EntityKey, EntityState properties and add the ScriptIgnore attribute to them:

 public partial class Person { [ScriptIgnore] public new System.Data.EntityKey EntityKey { get; set; } [ScriptIgnore] public new System.Data.EntityState EntityState { get; set; } } 

When the Person class is serialized through a JavascriptSerializer, it ignores these properties. However, this would be impractical because EF uses state information to track objects, and this can lead to chaos.

If there was a way to dynamically add properties, this would eliminate the need to override these properties only to add the [ScriptIgnore] attribute. But, since there is no way to dynamically add attributes, this solution may not be so useful.

+5
source

So far, the best technique I've found involves code generation. I did this in one project that used Factory Service , but you could do the same "manually" using T4 Text Templates .

Also keep an eye on AutoMapper . This is still new enough that I think this is a new technology, but I hope that it will be available soon!

+1
source

All Articles