A circular reference was detected while serializin

2019-01-01 03:22发布

I am trying to do a simple JSON return but I am having issues I have the following below.

public JsonResult GetEventData()
{
    var data = Event.Find(x => x.ID != 0);
    return Json(data);
}

I get a HTTP 500 with the exception as shown in the title of this question. I also tried

var data = Event.All().ToList()

That gave the same problem.

Is this a bug or my implementation?

14条回答
姐姐魅力值爆表
2楼-- · 2019-01-01 04:13

You can notice the properties that cause the circular reference. Then you can do something like:

private Object DeCircular(Object object)
{
   // Set properties that cause the circular reference to null

   return object
}
查看更多
素衣白纱
3楼-- · 2019-01-01 04:17

Its because of the new DbContext T4 template that is used for generating the EntityFramework entities. In order to be able to perform the change tracking, this templates uses the Proxy pattern, by wrapping your nice POCOs with them. This then causes the issues when serializing with the JavaScriptSerializer.

So then the 2 solutions are:

  1. Either you just serialize and return the properties you need on the client
  2. You may switch off the automatic generation of proxies by setting it on the context's configuration

    context.Configuration.ProxyCreationEnabled = false;

Very well explained in the below article.

http://juristr.com/blog/2011/08/javascriptserializer-circular-reference/

查看更多
刘海飞了
4楼-- · 2019-01-01 04:20

It seems that there are circular references in your object hierarchy which is not supported by the JSON serializer. Do you need all the columns? You could pick up only the properties you need in the view:

return Json(new 
{  
    PropertyINeed1 = data.PropertyINeed1,
    PropertyINeed2 = data.PropertyINeed2
});

This will make your JSON object lighter and easier to understand. If you have many properties, AutoMapper could be used to automatically map between DTO objects and View objects.

查看更多
查无此人
5楼-- · 2019-01-01 04:20

JSON, like xml and various other formats, is a tree-based serialization format. It won't love you if you have circular references in your objects, as the "tree" would be:

root B => child A => parent B => child A => parent B => ...

There are often ways of disabling navigation along a certain path; for example, with XmlSerializer you might mark the parent property as XmlIgnore. I don't know if this is possible with the json serializer in question, nor whether DatabaseColumn has suitable markers (very unlikely, as it would need to reference every serialization API)

查看更多
闭嘴吧你
6楼-- · 2019-01-01 04:21
//first: Create a class as your view model

public class EventViewModel 
{
 public int Id{get;set}
 public string Property1{get;set;}
 public string Property2{get;set;}
}
//then from your method
[HttpGet]
public async Task<ActionResult> GetEvent()
{
 var events = await db.Event.Find(x => x.ID != 0);
 List<EventViewModel> model = events.Select(event => new EventViewModel(){
 Id = event.Id,
 Property1 = event.Property1,
 Property1 = event.Property2
}).ToList();
 return Json(new{ data = model }, JsonRequestBehavior.AllowGet);
}
查看更多
墨雨无痕
7楼-- · 2019-01-01 04:23

Avoid converting the table object directly. If relations are set between other tables, it might throw this error. Rather, you can create a model class, assign values to the class object and then serialize it.

查看更多
登录 后发表回答