最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Serialize Entity Framework Object using Json.Net - Stack Overflow

programmeradmin2浏览0评论

How do I serialize entity framework object into JavaScript Object (JSON)? I tried using JSON.NET but I am getting the following exception when I try to serialize it.

Exception: Newtonsoft.Json.JsonSerializationException, Message="Self referencing loop"

Hitesh

How do I serialize entity framework object into JavaScript Object (JSON)? I tried using JSON.NET but I am getting the following exception when I try to serialize it.

Exception: Newtonsoft.Json.JsonSerializationException, Message="Self referencing loop"

Hitesh

Share Improve this question asked Jun 24, 2009 at 4:20 HiteshHitesh 4522 gold badges10 silver badges24 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 6

It sounds like you are having the same general problem as the original DataContract serializer, in regards to cyclic references. While objects referencing each other is fairly mon with object graphs in memory, such cyclic references inevitably result in infinite recursions when serialized if the serializer does not specifically account for it. There are few, if any, established standards for dealing with cyclic references in the mon non-binary serialization formats (XML and JSON being the two most prevalent.)

Microsoft solved the cyclic problem for the DataContract serializer in .NET 3.5 SP1 by making use of the ref semantics in xml. To my knowledge, there is no such thing for JSON, which might be why JSON.NET is preventing you from serializing your object graph.

I would make sure you have only references in your object graph that are navigable one-way, rather than both ways (i.e. only from parent to child, not from child to parent.) Those parent/child and child/parent are the most mon types of cyclic references. It may also be that a lower-level child is ultimately referencing the root of the graph, causing an indirect cyclic graph to be created (these tend to be far less mon than the parent/child loops, however.)

Once you eliminate any cyclic references in your object graph, you should be able to serialize.

I had this problem and solved it by adding the Newtonsoft.Json.JsonIgnoreAttribute to the property causing the loop. Obviously, that property won't be serialized. To help with this problem, I typically will have both the foreign reference ID and the foreign class in my entities. I realize this is not intuitive (or super great OO), but it is the way remended by Julia Lerman in her book Programming Entity Framework: Code First. I've found it helps smooth out several problems with Entity Framework.

 public class SomeEntity
 {
      [JsonIgnore]
      public ForeignEntity SomeForeignEntity {get;set;}
      public Guid ForeignEntityId {get;set;}
 }

Update: I forgot to mention I also needed to disable proxies on the DbContext like so:

dataContext.Configuration.ProxyCreationEnabled = false;

If you are writing the code for a service (which seems likely if you are serializing), then this is probably not a problem, but there are some things you lose when the proxy creation is disabled. See here: http://www.sellsbrothers./posts/Details/12665 for more details.

I am using the MS Web Api, so I just disable the the proxy creation when I construct my controller:

public class MailingApiController : ApiController
{
    public MailingApiController()
    {
        PreventDeepSerialization();
    }

    private static void PreventDeepSerialization()
    {
        var dataContext = Injector.Get<IIntertwyneDbContext>();
        dataContext.Configuration.ProxyCreationEnabled = false;
    }
      ....

To get around this I converted my Entities to POCO based Code First. To do this right click inside your edmx window and select:

Add code generation item > Code tab > EF POCO Entity Generator.

Note that you might need to install it with nuget if you don't see it.

At runtime however EF adds proxy classes to those objects for tracking purposes but they tend to mess up with the serialization process. To prevent this we can simply set ProxyCreationEnabled to false as follows:

var context = new YourEntities();
context.Configuration.ProxyCreationEnabled = false;

var results = context.YourEntity.Take(100).ToList();

You can then safely return JSON.NET serialized data by omitting the default reference looping as follows:

return JsonConvert.SerializeObject(results, Formatting.Indented, 
    new jsonSerializerSettings { 
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore 
    });
发布评论

评论列表(0)

  1. 暂无评论