3
votes

I am getting this error "Self referencing loop detected" while serializing using 'Json.NET'

I have a Book model

public class Book
{
    public Book()
    {
        BookPersonMap = new List<BookPersonMap>();
    }

    public int BookId { get; set; }

    public virtual ICollection<BookPersonMap> BookPersonMap { get; private set; }

    (And many other virtual Icollections)
}

And this is the BookPerson Mapping class:

public class BookPersonMap
{
    public int BookId { get; set; }

    public string PersonName { get; set; }

    public int PersonTypeId { get; set; }

    public virtual Book Book { get; set; } // Foreign keys

    public virtual PersonType PersonType { get; set; }
}

When I try to Serialize the Book object it throws:

"Self referencing loop detected for property 'Book' with type 'System.Data.Entity.DynamicProxies.Book_57F0FA206568374DD5A4CFF53C3B41CFDDC52DBBBA18007A896 08A96E7A783F8'. Path 'BookPersonMap[0]'."

I have tried the things suggested in some of the similar posts Example:

  1. PreserveReferencesHandling = PreserveReferencesHandling.Objects in Serializer settings returned a string with length 3 million!

  2. ReferenceLoopHandling = ReferenceLoopHandling.Ignore in Serializer settings : "An exception of type 'System.OutOfMemoryException' occurred in Newtonsoft.Json.dll but was not handled in user code"

  3. ^ Same luck with "ReferenceLoopHandling.Serialize"

  4. MaxDepth = 1 : Infinite loop again.

Putting [JsonIgnore] on the virtual properties is working but it is a tedious task (because of numerous FK references) and not efficent, since if I miss one property and it will throw exception.

What is missing from above Json settings for them be not working?

4
Have you looked at this question?Codeman
@Pheonixblade9 Yes. That is what I mentioned in the question. None of the JsonSerializerSettings mentioned here on the msdn site except for [JsonIgnore] actually work.adiga

4 Answers

1
votes
services.AddMvc().AddJsonOptions(opt => {
    opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});                                               
0
votes

I have found the best way to solve this type of error is to flatten your model using a view model.

Put a break point on your object before it is serialized and start drilling into the child properties. You will probably find that you can go on indefinitely.

This is what the serializer is choking on.

0
votes

Create a Constructor for your controller and put on it this line of code : db.Configuration.ProxyCreationEnabled = false; //db is the instance of the context.

0
votes

For asp.net mvc 5 use this

Add the code below to your Application_Start method inside globax.asax file or startup file.

protected void Application_Start()
    {
       ..
        GlobalConfiguration.Configuration.Formatters.JsonFormatter
                    .SerializerSettings
                    .ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
}

Disable lazy loading and ensure your controller does not return

Json(..obj)

rather it should return

Ok(..obj)