1
votes

I have this bit of code to send a List of Route objects to my View (ASP.Net MVC):

public ActionResult getRouteFromPart(int partId)
{
    List<Route> routes = _routeService.GetRouteByPartType(partId);

    if (routes == null)
    {
        return this.AdvancedJsonResult(null, JsonRequestBehavior.AllowGet);
    }

    return this.AdvancedJsonResult(new
    {
        Routes = routes
    }, JsonRequestBehavior.AllowGet);
}

But I'm getting an exception here in my AdvancedJsonResult class:

if (Data != null)
{
    var settings = new JsonSerializerSettings
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver()
    };

    string result = JsonConvert.SerializeObject(this.Data, this.Formatting, settings);
    response.Write(result);
}

I've tried the "ReferenceLoopHanding.Ignore" trick which silences the exception, but the list still doesn't get passed to the view.

The code works when I change routes to a single object instead of a list, so I think the code just doesn't like working with a list.

I'm new to this project so I'm not sure how to fix this and make it happy with using a List...

Edit: Here's the full Exception message, which happens on the string result = JsonConvert... line.

Self referencing loop detected with type 'System.Data.Entity.DynamicProxies.PartNumber_B135A5D16403B760C3591872ED4C98A25643FD10B51246A690C2F2D977973452'. Path 'routes[0].incomingLots[0].partNumber.partType.partNumbers'.

2
The issue is with the types and data in Route. The code you show seems fine.rene
an aside, AdvancedJsonResult seems to be a method, not a class. Check your json itself for referencing loops.. in particular, the first route -> the first incomingLots -> partNumber -> partType.. there might be part numbers that reference others in a loopSteelSoul

2 Answers

1
votes

The meaning of the error message is that there is a self referencing loop. You have to set the db context that you do not want to get all linked entities when you request some entities. It can be done by adding two lines into DbContext class constructor to disable self referencing loop as shown below:

public YourDbContext() : base("name = YourDbContext")
{       
    //add these lines in order to avoid from "Self referencing loop detected for ..." error
    this.Configuration.LazyLoadingEnabled = false;
    this.Configuration.ProxyCreationEnabled = false;
}

Hope this helps...

1
votes

Well the correct answer for the default Json formater based on Json.net is to set ReferenceLoopHandling to Ignore.

Just add this to the Application_Start in Global.asax:

HttpConfiguration config = GlobalConfiguration.Configuration;

config.Formatters.JsonFormatter
            .SerializerSettings
            .ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;

This is the correct way. It will ignore the reference pointing back to the object.

Other responses focused in changing the list being returned by excluding data or by making a facade object and sometimes that is not an option.

Using the JsonIgnore attribute to restrict the references can be time consuming and if you want to serialize the tree starting from another point that will be a problem.

Copied from this answer.