简体   繁体   中英

A possible object cycle was detected when serializing entity-model to JSON

I have a webapi project that written using C# and built on the top of ASP.NET Core/5 framework.

The API return JSON data.

Here is an example of one endpoint

[HttpGet]
public async Task<ActionResult<TModel[]>> QueryAsync(
   [FromQuery(Name = "filter")] string filter = null,
   [FromQuery(Name = "expand")] string expand = null)
{
    IQueryable<TModel> query = GetQuery(filter, expand);

    var models = await query.ToArrayAsync();

    return Ok(models);
}

In the above request, the expand will tell the server which navigation properties to expand. When the user request to expand a property, I get the following error

A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles

Following the instruction from the error, I added the following to the Startup class

services.AddControllers().AddJsonOptions(options =>
{
    options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
    // added this
    options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;
});

The above change did fix the problem! However, it introduced another problem. The new problem is that it changed the structure of the output.

The output went from something like this

{
  // properties
 
  "relations": [
     {
         // relation 1
         "parent": null
     },
     {
         // relation 2
         "parent": null
     }
   ]
}

to something like this

{
  "$id": "1",
  // properties
 
  "relations": {
     "$id": "2",
     "$values": [
         {
             // relation 1 properties
             "$id": "3",
             "parent": {
                 "$ref": 1
             }
         },
         {
            // relation 2 properties
            "$id": "3",
            "parent": {
                 "$ref": 1
             }
         }
     ]
   }
}

Is there a way to not change the structure of the output and instead ignore the circular reference?

There is a similar question here, where one of the answers mentions the same issue you're having: .Net Core 3.0 possible object cycle was detected which is not supported

Some of the things mentioned there:

If you're on .NET 6 you can use

JsonSerializerOptions options = new()
{
    ReferenceHandler = ReferenceHandler.IgnoreCycles,
    WriteIndented = true
};

alternatively, depending on what you need to achieve, you might want to just ignore looping properties altogether.

The proper solution though would be to find out where exactly your references are looping and exclude the property(s) in question from serialization, or supply them in a format that doesn't loop (such as an id or similar)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM