Serialize Entity Framework Objects in JSON

It seems that serializing Entity Framework objects in JSON is not possible using WCF's built-in DataContractJsonSerializer or native ASP.NET code serializer. This is due to link count problems that are rejected as serializers. I also tried Json.NET , which also does not work specifically on the issue of link counting.




Edit: Now Json.NET can serialize and deserialize Entity Framework entities .




My objects are Entity Framework objects that are overloaded to perform additional business functions (for example, authentication, etc.), and I do not want to decorate these classes with platform attributes, etc., since I want to introduce a platform-diagnostic API.

I really wrote about the individual steps that I went through, although in https://blog.programx.co.uk/2009/03/18/wcf-json-serialization-woes-and-a-solution/

Am I missing something obvious?

+43
json entity-framework wcf asp.net-ajax
Mar 18 '09 at 11:53
source share
8 answers

How do I do this by projecting the data I want to serialize into an anonymous type and serializing it. This ensures that only the information that I really want in JSON is serialized, and it is not by chance that I serialize something further down the graph of the object. It looks like this:

var records = from entity in context.Entities select new { Prop1 = entity.Prop1, Prop2 = entity.Prop2, ChildProp = entity.Child.Prop } return Json(records); 

I find anonymous types ideal for this. Obviously, JSON doesn't care what type was used to create it. And anonymous types give you complete flexibility regarding what properties and structure you put in JSON.

+71
Mar 18 '09 at 12:30
source share

Microsoft made a mistake in how they turned EF objects into data contracts. They included base classes and backlinks.

It is best to create equivalent classes of data transfer objects for each of the objects that you want to return. They will include only data, not behavior, and not the EF-specific parts of the object. You must also create methods to translate to and from DTO classes.

Your services will then return the data objects.

+17
Mar 18 '09 at 12:16
source share

My solution was to simply remove the parent link to the child objects.

So, in my model, I selected the connection and changed the "Parent" link to "Internal" rather than "Public".

It may not be the perfect solution for everyone, but it worked for me.

+2
Feb 23 '12 at 12:05
source share

Based on @Craig Stuntz's answer and a similar DTO, for my solution I created a partial model class (in a separate file) and a return object method with the way I want, using only the properties that will be needed.

 namespace TestApplication.Models { public partial class Employee { public object ToObject() { return new { EmployeeID = EmployeeID, Name = Name, Username = Username, Office = Office, PhoneNumber = PhoneNumber, EmailAddress = EmailAddress, Title = Title, Department = Department, Manager = Manager }; } } } 

And then I call it simply on return:

 var employee = dbCtx.Employees.Where(x => x.Name == usersName).Single(); return employee.ToObject(); 

I think the accepted answer is faster and easier, I just use my method to keep all my results consistent and dry.

+2
May 10 '16 at 17:50
source share

Another solution, if you want to improve code consistency, is to use JavaScriptConverter, which will handle circular link dependencies and will not serialize such links.

I wrote about him here:

http://hellowebapps.com/2010-09-26/producing-json-from-entity-framework-4-0-generated-classes/

+1
Sep 26 '10 at 2:53 on
source share

FYI I found an alternative solution

You can set the parent relation to be private so that then the properties are not displayed during translation, removing an infinite loop of properties

+1
May 28 '12 at 10:10
source share

I struggled with this problem for several days,

Decision. Inside the edmx window. - right-click and add code generation element - Select the Code tab - select EF 4x.POCOC Entity Generator

If you do not see it, you will need to install it using nuget, search EF.

The Entity generator will generate the entire complex type and object of the object into simple classes for serialization in json.

+1
Jul 24 '12 at 13:35
source share

I solved this by getting only the object types from the System namespace, and then converting them to a dictionary and then adding them to the list. Works well for me :)

It looks complicated, but it was the only general solution that worked for me ... I use this logic for the helper I create, so for special use, when I need to intercept every type of object in an entity object, maybe someone can adapt it to its use.

 List<Dictionary<string, string>> outputData = new List<Dictionary<string, string>>(); // convert all items to objects var data = Data.ToArray().Cast<object>().ToArray(); // get info about objects; and get only those we need // this will remove circular references and other stuff we don't need PropertyInfo[] objInfos = data[0].GetType().GetProperties(); foreach (PropertyInfo info in objInfos) { switch (info.PropertyType.Namespace) { // all types that are in "System" namespace should be OK case "System": propeties.Add(info.Name); break; } } Dictionary<string, string> rowsData = null; foreach (object obj in data) { rowsData = new Dictionary<string, string>(); Type objType = obj.GetType(); foreach (string propertyName in propeties) { //if You don't need to intercept every object type You could just call .ToString(), and remove other code PropertyInfo info = objType.GetProperty(propertyName); switch(info.PropertyType.FullName) { case "System.String": var colData = info.GetValue(obj, null); rowsData.Add(propertyName, colData != null ? colData.ToString() : String.Empty); break; //here You can add more variable types if you need so (like int and so on...) } } outputData .Add(rowsData); // add a new row } 

"outputData" is safe for JSON encoding ... Hope someone finds this solution useful. It was fun to write :)

+1
Jan 03 '14 at 13:02
source share



All Articles