How do I avoid a circular reference while serializ

2019-06-02 21:23发布

I have an MVC-3 (RC1) application using Entity Framework 4.

I wish to return a JSON object from a controller action. This object is referenced by other objects, which obviously return the reference.

I thus receive the following circular reference error:

Server Error in '/' Application.

A circular reference was detected while serializing an object of type 'Application.Models.ReferenceObject'.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: A circular reference was detected while serializing an object of type 'Application.Models.ReferenceObject'.

NB: Application & ReferenceObject are obviously replacements for the actual namespace / object.

According to Stack Overflow: Circular reference exception when serializing LINQ to SQL classes, this can be overcome using JSON.Net; however I would like to avoid this and instead try to exclude the offending reference properties from the object being serialized.

What do I mean?

I want to do something like this:

IList<ReferenceObject> list = Repository.GetReferenceObjects();
return Json(list.**<method>**("ObjectsReferencingThis"));

where **<method>** is some method that does the opposite to the ObjectQuery(Of T).Include method and ObjectsReferencingThis is the property that is causing the circular reference.

NB: I do not wish to remove these properties or create POCOs as this only affects the Json serialization.

Anyone able to help please?

:)

2条回答
Root(大扎)
2楼-- · 2019-06-02 21:35

I had a similar problem when worked on one of my previous project. Here is what I ended up doing:

IList<Product> list = Repository.GetProducts();
  var collection = products.Select(product => new
        {
            id = product.Id,
            name = product.Name,
            detailUrl = product.DetailUrl,
            imageLargeUrl = product.ThumbNailUrl,
            tagtitle = product.Name.ToUpper(),
            tagheader = "Words our cherished patrons use to describe this product",
            tagwords = from tag in product.Tags group tag by tag.Name into words select new { name =          words.Key, weight = words.Count() }
        });

 var result = new {id = inquiry.Id, products = collection, };
 return this.Jsonp(result);

Here is how the result Json would look like:

{
"id" : 2,
"products" : [{
    "id" : "3605970008857",
    "name" : "TITLE1",
    "detailUrl" : "http://www.urlhere.com",
    "tagwords" : [{
        "name" : "roses",
        "weight" : 1
    },
    {
        "name" : "cotton",
        "weight" : 1
    },
    {
        "name" : "happy",
        "weight" : 1
    }]
},
{
    "id" : "3605970019891",
    "name" : "TITLE2",
    "detailUrl" : "http://www.urlhere.com",
    "tagwords" : []
}],

}

You can also add any other properties from you referenced objects to the result as you wish,to be shown in your Json object :)

查看更多
Rolldiameter
3楼-- · 2019-06-02 21:42

I made a very trivial solution which is not recommended if you have very big list

letters=UserOperations.GetDepartmentLettersForSecretary(pageNumber, pageSize,(Session["User"] as User).DepartmentID.Value, (Session["User"] as User).ID);

foreach (Letter letter in letters)
{
    letter.LetterStatus.Letters = null;
}

the problem of circular reference in my case is in LetterStatus.Letters so I Iterated through the list and assigned it to null

as I told you its not recommended if you have very big list

查看更多
登录 后发表回答