Содержание
- System.Text.Json.JsonException: A possible object cycle was detected which is not supported
- Option 1 – Use the JsonIgnore attribute to make the serializer ignore the property with the circular reference
- Option 2 – Remove the circular reference
- Option 3 – Use Newtonsoft instead and use ReferenceLoopHandling.Ignore (before .NET 6)
- Option 4 – Create a JsonConverter to customize how the problematic object is serialized
- Option 5 – Use option ReferenceHandler.Preserve (in .NET 5)
- Option 6 – Use option ReferenceHandler.IgnoreCycles (in .NET 6)
- 2 thoughts on “System.Text.Json.JsonException: A possible object cycle was detected which is not supported”
- TheCodeBuzz
- JsonException: A possible object cycle was detected which is not supported.
- JsonException: A possible object cycle was detected which is not supported
- Issue Description
- Resolution
- error: cyclic package dependency: package serde_json v0.7.3 depends on itself #91
- Comments
- Still having : throw new Error(‘Cyclic dependency: ‘+JSON.stringify(node)) #25
- Comments
- Footer
- UnhandledPromiseRejectionWarning: Error: cyclic dependency detected #292
- Comments
System.Text.Json.JsonException: A possible object cycle was detected which is not supported
When you use System.Text.Json.JsonSerializer to serialize an object that has a cycle, you’ll get the following exception:
System.Text.Json.JsonException: A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 0.
This is the same problem I wrote about in this article about Newtonsoft’s object cycle exception, except in this case it’s using System.Text.Json.JsonSerializer instead of Newtonsoft. The possible solutions are similar to the ones shown in that article, but not exactly the same.
First, what is an object cycle? Serializers work by recursively walking through an object’s properties. When it encounters a reference to an object that it already encountered, this means there’s a cycle. The serializer has to deal with this cycle, otherwise it would recurse infinitely and eventually get a StackOverflowException. The JsonSerializer’s default strategy for dealing with cycles is to throw an exception.
Here’s an example of an object with a circular reference. The Child class refers to the Parent class, which refers to the Child class:
Due to the circular reference, the call to JsonSerializer.Serialize() will throw the “object cycle detected” JsonException.
In this article I’ll show five different options for solving this problem. Pick the option that makes the most sense in your specific scenario.
Updated 2022-08-18 to explain the new option in .NET 6.
Table of Contents
Option 1 – Use the JsonIgnore attribute to make the serializer ignore the property with the circular reference
Put the JsonIgnore attribute on the properties with the circular references. This tells the serializer to not attempt to serialize these properties.
The resulting JSON looks like this:
If you choose to not serialize this information, the other side may have trouble deserializing, because the Mom/Dad properties are null.
Option 2 – Remove the circular reference
You may have accidently created this circular reference, or perhaps the property isn’t important to you. In either case, the solution is simple: remove the property.
Exception properties are a common cause of this problem. In this example, I have a Message class with an Exception property.
Next, I’m going to throw an exception, stick it on an object, and try to serialize it:
This results in the circular reference exception.
I can solve by removing the Exception property. Instead, I’ll add a string property to hold the Exception message.
Option 3 – Use Newtonsoft instead and use ReferenceLoopHandling.Ignore (before .NET 6)
In .NET 6, they added an option to System.Text.Json.JsonSerializer for ignoring circular references (see option 6 below). If you’re using a version before .NET 6, you can use Newtonsoft to do this.
First, add the Newtonsoft.Json nuget package. This is using the Package Manager Console:
Then use JsonConvert.SerializeObject() and pass in the ReferenceLoopHandling.Ignore option:
The resulting JSON looks like this:
Option 4 – Create a JsonConverter to customize how the problematic object is serialized
Let’s say you want to solve this circular reference problem without having to change the classes that you’re serializing. These may even be third-party classes that you can’t change. In any case, you can customize the serialization of any object by subclassing JsonConverter and controlling the serialization for that object.
First, add a JsonConverter subclass, like this:
Then use this converter by passing it into the JsonSerializerOptions.Converters list like this:
This outputs the following JSON:
Option 5 – Use option ReferenceHandler.Preserve (in .NET 5)
Starting in .NET 5, they added the ReferenceHandler property to JsonSerializerOption.
You can use it like this:
When you serialize, it adds metadata properties to the JSON. So it looks like this:
This JSON has metadata properties. As long as the deserializer knows how to deal with metadata properties, then it’s not a problem.
Newtonsoft handles metadata properties by default, whereas with System.Text.Json you must specify the ReferenceHandler property when you’re deserializing:
If you don’t specify ReferenceHandler.Preserve here, you’ll get the following exception:
System.Text.Json.JsonException: The JSON value could not be converted
If you’re going to use this option to deal with circular references, make sure the deserializer knows how to deal with metadata properties appropriately.
Option 6 – Use option ReferenceHandler.IgnoreCycles (in .NET 6)
In .NET 6, they added the ReferenceHandler.IgnoreCycles option to System.Text.Json. This allows you to ignore circular references.
Here’s how to use it:
When you serialize with this option, it nulls out circular references. Here’s what this outputs:
If you don’t want nulls to show up like this, you can ignore all null properties with the DefaultIgnoreCondition setting:
2 thoughts on “System.Text.Json.JsonException: A possible object cycle was detected which is not supported”
Option 5: By specifying Preserve for deserialization I avoided “JsonException: The JSON value could not be converted” but all of the received objects have their properties empty (i.e. default(T)). Any thoughts on that?
I’d guess there’s a property name casing mismatch. By default, JsonSerializer is case-sensitive, so if the received JSON has camelCasing and your class has PascalCasing, it will leave the values empty.
Try using using “PropertyNameCaseInsensitive = true” in the options, like this:
var parent2 = JsonSerializer.Deserialize(json, new JsonSerializerOptions()
<
ReferenceHandler = ReferenceHandler.Preserve,
PropertyNameCaseInsensitive = true
>);
If it still doesn’t work, we can discuss details by email if you want.
Источник
TheCodeBuzz
Best Practices for Software Development
JsonException: A possible object cycle was detected which is not supported.
JsonException: A possible object cycle was detected which is not supported
Today in this article, we will cover below aspects,
Issue Description
ASP.NET Core application gives below runtime error,
System.Text.Json.JsonException: A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32.
I got the above error for ASP.NET Core 3.1 with EFCore and but this error could possibly exist for 3.* and above any version.
Resolution
I found this error more due to the default JSON serializer used in ASP.NET Core 3.0 and the above version.
ASP.NET Core 3.0 has removed the dependency on JSON.NET and uses it’s own JSON serializer i.e ‘System.Text.Json‘.
ReferenceLoopHandling is currently not supported in the System.Text.Json serializer. This feature will be supported most probably .NET 5 version in the future.
Below was the codebase used which was producing the error for me and i was able to fix the issue using below measures,
I was able to fix the issue adding the reference to NewtonsoftJson Nuget package,
PM> Install-Package Microsoft.AspNetCore.Mvc.NewtonsoftJson -Version 3.1.2
And update the Startup.cs as below,
Similarly, if you have IRouter based routing enabled for API (While migrating .NET Core 2.2 to 3.* version) using EnableEndpointRouting set as false you will get the same error.
Please try using below logic to fix the issue,
References:
Did I miss anything else in these resolution steps?
Did the above steps resolve your issue? Please sound off your comments below!
Please bookmark this page and share it with your friends. Please Subscribe to the blog to get a notification on freshly published best practices and guidelines for software design and development.
Источник
error: cyclic package dependency: package serde_json v0.7.3 depends on itself #91
This occurs only when I include the preserve_order feature.
The text was updated successfully, but these errors were encountered:
This is caused by linked-hash-map using serde_json for their tests. Cargo does not yet support optional dev-dependencies (rust-lang/cargo#1596) so they declare a regular dependency — which is circular.
I have a PR serde-rs/serde#412 that will add an alternative way for them to test the serde impls without depending on serde_json.
Once that merges, I will make a linked-hash-map PR of https://github.com/dtolnay/linked-hash-map/commit/dabca618762ed31b50bfa5ea92b5bbfc305d57c5 to remove the serde_json dependency.
Switch to serde_test and drop dependency on serde_json contain-rs/linked-hash-map#60 )
Okay, that would be great. Let me know when it’s done, if you could. Thanks.
This is caused by linked-hash-map https://github.com/contain-rs/linked-hash-map using serde_json for their tests. Cargo does not yet support optional dev-dependencies (rust-lang/cargo#1596 rust-lang/cargo#1596) so they declare a regular dependency — which is circular.
I have a PR serde-rs/serde#412 serde-rs/serde#412 that will add an alternative way for them to test the serde impls without depending on serde_json.
Once that merges, I will make a linked-hash-map PR of dtolnay/linked-hash-map@dabca61 https://github.com/dtolnay/linked-hash-map/commit/dabca618762ed31b50bfa5ea92b5bbfc305d57c5 to remove the serde_json dependency.
It looks like the PR has already been merged, just not closed yet?
The first one has merged. I am marking off the steps in my previous comment as they happen.
Источник
Still having : throw new Error(‘Cyclic dependency: ‘+JSON.stringify(node)) #25
I just upgraded to the new Vue CLI which internally uses new Webpack 4 which uses toposort, as soon as I upgraded, this happend.
The text was updated successfully, but these errors were encountered:
Are you reporting this to this repo because of the «circular structure» JSON.stringify error? If not, then this looks like a normal error due to wrong use of toposort. Toposort throws an error if you try to sort circular data.
@marcelklehr yes i’m talking about the «»circular structure» JSON.stringify error». I’m not the one using toposort here, it seems to be a dep of webpack 4 and when the dep is >= 1.0.7 I have this error, when I force toposort to 1.0.6 or under it works
this works without an error, but any time I upgrade something I get this lock with the error mentioned in the console
when I force toposort to 1.0.6 or under it works
However, the exact error you describe cannot happen with v1.0.7 anymore, because line 21 has been changed v1.0.4. v1.0.7
This diff also shows the difference between version 1.0.4 and v1.0.7 which is one test and said change around line 21. I highly doubt that there’s an input that throws an error in v1.0.7 but doesn’t in v1.0.4, but if you like you can create a gist or a repo that I can use to reproduce and debug.
Good morning, everybody.
I’ve got the same issue with toposort recently. While the real problem was in my Vue code (circular dependency in one of the components) toposort failed with «circular structure» in JSON.stringify.
It is turned out that when toposort investigates the circular dependency error it tries to throw out a Error and notify about it, however, it also tries to use JSON.stringify on the incoming json structure.
In my case the json structure was circular too so toposort failed to throw Error and hid the original reason.
This happened on 1.0.4 and 1.0.6.
Hope this helps.
Hey @marcelklehr ,
thank you for the suggestion, the error processing code is much better now. I will update the dependency 🙂
© 2023 GitHub, Inc.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Источник
UnhandledPromiseRejectionWarning: Error: cyclic dependency detected #292
Im currently running into a «UnhandledPromiseRejectionWarning: Error: cyclic dependency detected» when setting up connect-mongo.
Here is my current code:
As for the error logged in the console:
(node:11984) UnhandledPromiseRejectionWarning: Error: cyclic dependency detected
at serializeObject (C:UsersJoãoDesktopGitHubWeb_Project_F-Jnode_modulesbsonlibbsonparserserializer.js:331:34)
at serializeInto (C:UsersJoãoDesktopGitHubWeb_Project_F-Jnode_modulesbsonlibbsonparserserializer.js:934:17)
at serializeObject (C:UsersJoãoDesktopGitHubWeb_Project_F-Jnode_modulesbsonlibbsonparserserializer.js:345:18)
at serializeInto (C:UsersJoãoDesktopGitHubWeb_Project_F-Jnode_modulesbsonlibbsonparserserializer.js:934:17)
at serializeObject (C:UsersJoãoDesktopGitHubWeb_Project_F-Jnode_modulesbsonlibbsonparserserializer.js:345:18)
at serializeInto (C:UsersJoãoDesktopGitHubWeb_Project_F-Jnode_modulesbsonlibbsonparserserializer.js:934:17)
at serializeObject (C:UsersJoãoDesktopGitHubWeb_Project_F-Jnode_modulesbsonlibbsonparserserializer.js:345:18)
at serializeInto (C:UsersJoãoDesktopGitHubWeb_Project_F-Jnode_modulesbsonlibbsonparserserializer.js:934:17)
at serializeObject (C:UsersJoãoDesktopGitHubWeb_Project_F-Jnode_modulesbsonlibbsonparserserializer.js:345:18)
at serializeInto (C:UsersJoãoDesktopGitHubWeb_Project_F-Jnode_modulesbsonlibbsonparserserializer.js:934:17)
at serializeObject (C:UsersJoãoDesktopGitHubWeb_Project_F-Jnode_modulesbsonlibbsonparserserializer.js:345:18)
at serializeInto (C:UsersJoãoDesktopGitHubWeb_Project_F-Jnode_modulesbsonlibbsonparserserializer.js:934:17)
at serializeObject (C:UsersJoãoDesktopGitHubWeb_Project_F-Jnode_modulesbsonlibbsonparserserializer.js:345:18)
at serializeInto (C:UsersJoãoDesktopGitHubWeb_Project_F-Jnode_modulesbsonlibbsonparserserializer.js:934:17)
at serializeObject (C:UsersJoãoDesktopGitHubWeb_Project_F-Jnode_modulesbsonlibbsonparserserializer.js:345:18)
at serializeInto (C:UsersJoãoDesktopGitHubWeb_Project_F-Jnode_modulesbsonlibbsonparserserializer.js:934:17)
(node:11984) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:11984) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Hope you can help. Thanks!
The text was updated successfully, but these errors were encountered:
Источник
If you’re using Object Relational Mapping frameworks like Hibernate, and are using the bi-directional mappings then you can be sure of getting the following errors if you try to generate JSON of the entities involved.
1. If you’re using Jackson
com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError)
2. If you’re using Google’s Gson
java.lang.IllegalStateException: circular reference error
Let’s take a case of two entities Actor, and Movie having a bi-directional relationship and using them we’ll see how to get over the above exceptions when we try to generate JSON.
This solution uses Jackson for generating JSON.
So if you’re using Google’s Gson you’ll have to write an exclusion strategy yourself, and more importantly the rest of the post is useless for you, unless you’re willing to switch to Jackson like I did with such great finesse! 😉
If yes, then you can download Jackson’s libraries and continue reading the post further, rest assured that it’ll be of immense help to you! 🙂
Now, these entities will have a many-to-many relationship amongst them. As one Actor can act in many Movies and one Movie can have many Actors (as it so often happens, and by the way due apologies for being trite and rhetoric!).
Actor.java
@Entity @Table(name="Actor") public class Actor implements Serializable { . . . /* This is the exception-saving-annotation */ @JsonManagedReference @ManyToMany private List<Movie> movies; . . . }
Movie.java
@Entity @Table(name="Movie") public class Movie implements Serializable { . . . /* This is the exception-saving-annotation */ @JsonBackReference @ManyToMany(mappedBy="movies") private List<Actor> actors; . . . }
So all we did was adding two annotations to the fields having a relationship.
- @JsonManagedReference: This annotation should be put on the owner of the relationship, or as you may deem fit.
- @JsonBackReference: This annotation should be used on the other end of the relationship.
Now, having done that it’s extremely easy to generate the JSON.
//com.fasterxml.jackson.databind.ObjectMapper ObjectMapper objectMapper = new ObjectMapper(); //The input argument of the writeValueAsString() function can be a bean, array, list, map or a set. String actorsAsJson = objectMapper.writeValueAsString(actorsList); //actorsList is a variable of type List<Actor> //Voila! You're done!
That’s all for the circular dependency errors.
~ Entity Class Code Snippets by Amit
~Jackson JSON processor
The Quintessential – Life and JavaScript enthusiast!
When you use System.Text.Json.JsonSerializer to serialize an object that has a cycle, you’ll get the following exception:
System.Text.Json.JsonException: A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 0.
This is the same problem I wrote about in this article about Newtonsoft’s object cycle exception, except in this case it’s using System.Text.Json.JsonSerializer instead of Newtonsoft. The possible solutions are similar to the ones shown in that article, but not exactly the same.
First, what is an object cycle? Serializers work by recursively walking through an object’s properties. When it encounters a reference to an object that it already encountered, this means there’s a cycle. The serializer has to deal with this cycle, otherwise it would recurse infinitely and eventually get a StackOverflowException. The JsonSerializer’s default strategy for dealing with cycles is to throw an exception.
Here’s an example of an object with a circular reference. The Child class refers to the Parent class, which refers to the Child class:
Code language: C# (cs)
Parent harry = new Parent() { Name = "Harry" }; Parent mary = new Parent() { Name = "Mary" }; harry.Children = new List<Child>() { new Child() { Name = "Barry", Dad=harry, Mom=mary } }; mary.Children = harry.Children; var json = JsonSerializer.Serialize(harry, new JsonSerializerOptions() { WriteIndented = true }); Console.WriteLine(json);
Due to the circular reference, the call to JsonSerializer.Serialize() will throw the “object cycle detected” JsonException.
In this article I’ll show five different options for solving this problem. Pick the option that makes the most sense in your specific scenario.
Updated 2022-08-18 to explain the new option in .NET 6.
Option 1 – Use the JsonIgnore attribute to make the serializer ignore the property with the circular reference
Put the JsonIgnore attribute on the properties with the circular references. This tells the serializer to not attempt to serialize these properties.
Code language: C# (cs)
public class Child { [System.Text.Json.Serialization.JsonIgnore] public Parent Mom { get; set; } [System.Text.Json.Serialization.JsonIgnore] public Parent Dad { get; set; } public string Name { get; set; } }
The resulting JSON looks like this:
Code language: JSON / JSON with Comments (json)
{ "Children": [{ "Name": "Barry" }], "Name": "Harry" }
If you choose to not serialize this information, the other side may have trouble deserializing, because the Mom/Dad properties are null.
Option 2 – Remove the circular reference
You may have accidently created this circular reference, or perhaps the property isn’t important to you. In either case, the solution is simple: remove the property.
Exception properties are a common cause of this problem. In this example, I have a Message class with an Exception property.
Code language: C# (cs)
public class Message { public string Name { get; set; } public Exception Exception { get; set; } public void Throw() { throw new Exception(); } }
Next, I’m going to throw an exception, stick it on an object, and try to serialize it:
Code language: C# (cs)
try { var msg = new Message() { Name = "hello world" }; msg.Throw(); } catch (Exception ex) { var errorMessage = new Message() { Name = "Error", Exception = ex }; var json = JsonSerializer.Serialize(errorMessage, new JsonSerializerOptions() { WriteIndented = true }); Console.WriteLine(json); }
This results in the circular reference exception.
I can solve by removing the Exception property. Instead, I’ll add a string property to hold the Exception message.
Code language: C# (cs)
public class Message { public string Name { get; set; } public string ExceptionMessage { get; set; } public void Throw() { throw new Exception(); } }
Option 3 – Use Newtonsoft instead and use ReferenceLoopHandling.Ignore (before .NET 6)
In .NET 6, they added an option to System.Text.Json.JsonSerializer for ignoring circular references (see option 6 below). If you’re using a version before .NET 6, you can use Newtonsoft to do this.
First, add the Newtonsoft.Json nuget package. This is using the Package Manager Console:
Install-Package Newtonsoft.Json
Code language: PowerShell (powershell)
Then use JsonConvert.SerializeObject() and pass in the ReferenceLoopHandling.Ignore option:
Code language: C# (cs)
using Newtonsoft.Json; var json = JsonConvert.SerializeObject(harry, Formatting.Indented, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
The resulting JSON looks like this:
Code language: JSON / JSON with Comments (json)
{ "Children": [ { "Mom": { "Name": "Mary" }, "Name": "Barry" } ], "Name": "Harry" }
Option 4 – Create a JsonConverter to customize how the problematic object is serialized
Let’s say you want to solve this circular reference problem without having to change the classes that you’re serializing. These may even be third-party classes that you can’t change. In any case, you can customize the serialization of any object by subclassing JsonConverter and controlling the serialization for that object.
First, add a JsonConverter subclass, like this:
Code language: C# (cs)
public class ChildJsonConverter : JsonConverter<Child> { public override bool CanConvert(Type objectType) { return objectType == typeof(Child); } public override Child Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return null; //Doesn't handle deserializing } public override void Write(Utf8JsonWriter writer, Child value, JsonSerializerOptions options) { writer.WriteStartObject(); writer.WriteString(nameof(value.Name), value.Name); writer.WriteString(nameof(value.Mom), value.Mom?.Name); writer.WriteString(nameof(value.Dad), value.Dad?.Name); writer.WriteEndObject(); } }
Then use this converter by passing it into the JsonSerializerOptions.Converters list like this:
Code language: C# (cs)
var options = new JsonSerializerOptions() { WriteIndented = true }; options.Converters.Add(new ChildJsonConverter()); var json = JsonSerializer.Serialize(harry, options);
This outputs the following JSON:
Code language: JSON / JSON with Comments (json)
{ "Children": [ { "Name": "Barry", "Mom": "Mary", "Dad": "Harry" } ], "Name": "Harry" }
Option 5 – Use option ReferenceHandler.Preserve (in .NET 5)
Starting in .NET 5, they added the ReferenceHandler property to JsonSerializerOption.
You can use it like this:
Code language: C# (cs)
var json = JsonSerializer.Serialize(harry, new JsonSerializerOptions() { WriteIndented = true, ReferenceHandler = ReferenceHandler.Preserve });
When you serialize, it adds metadata properties to the JSON. So it looks like this:
Code language: JSON / JSON with Comments (json)
{ "$id": "1", "Children": { "$id": "2", "$values": [ { "$id": "3", "Mom": { "$id": "4", "Children": { "$ref": "2" }, "Name": "Mary" }, "Dad": { "$ref": "1" }, "Name": "Barry" } ] }, "Name": "Harry" }
This JSON has metadata properties. As long as the deserializer knows how to deal with metadata properties, then it’s not a problem.
Newtonsoft handles metadata properties by default, whereas with System.Text.Json you must specify the ReferenceHandler property when you’re deserializing:
Code language: C# (cs)
var parent = Newtonsoft.Json.JsonConvert.DeserializeObject<Parent>(json); var parent2 = JsonSerializer.Deserialize<Parent>(json, new JsonSerializerOptions() { ReferenceHandler = ReferenceHandler.Preserve });
If you don’t specify ReferenceHandler.Preserve here, you’ll get the following exception:
System.Text.Json.JsonException: The JSON value could not be converted
If you’re going to use this option to deal with circular references, make sure the deserializer knows how to deal with metadata properties appropriately.
Option 6 – Use option ReferenceHandler.IgnoreCycles (in .NET 6)
In .NET 6, they added the ReferenceHandler.IgnoreCycles option to System.Text.Json. This allows you to ignore circular references.
Here’s how to use it:
Code language: C# (cs)
var json = JsonSerializer.Serialize(harry, new JsonSerializerOptions() { WriteIndented = true, ReferenceHandler = ReferenceHandler.IgnoreCycles });
When you serialize with this option, it nulls out circular references. Here’s what this outputs:
Code language: JSON / JSON with Comments (json)
{ "Children": [ { "Mom": { "Children": null, "Name": "Mary" }, "Dad": null, "Name": "Barry" } ], "Name": "Harry" }
If you don’t want nulls to show up like this, you can ignore all null properties with the DefaultIgnoreCondition setting:
Code language: C# (cs)
new JsonSerializerOptions() { WriteIndented = true, ReferenceHandler = ReferenceHandler.IgnoreCycles, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }
Today in this article, we will cover below aspects,
- Issue Description
- Resolution
Issue Description
ASP.NET Core application gives below runtime error,
System.Text.Json.JsonException: A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32.
I got the above error for ASP.NET Core 3.1 with EFCore and but this error could possibly exist for 3.* and above any version.
Resolution
I found this error more due to the default JSON serializer used in ASP.NET Core 3.0 and the above version.
ASP.NET Core 3.0 has removed the dependency on JSON.NET and uses it’s own JSON serializer i.e ‘System.Text.Json‘.
ReferenceLoopHandling is currently not supported in the System.Text.Json serializer. This feature will be supported most probably .NET 5 version in the future.
Below was the codebase used which was producing the error for me and i was able to fix the issue using below measures,
I had Repository Pattern implemented with EFCore context,
public async Task<TEntity> Get(string id) { return await _context.Set<TEntity>().FindAsync(id.ToString()); }
I was able to fix the issue adding the reference to NewtonsoftJson Nuget package,
PM> Install-Package Microsoft.AspNetCore.Mvc.NewtonsoftJson -Version 3.1.2
And update the Startup.cs as below,
Similarly, if you have IRouter based routing enabled for API (While migrating .NET Core 2.2 to 3.* version) using EnableEndpointRouting set as false you will get the same error.
Please try using below logic to fix the issue,
References:
- Create Custom Converters for JSON serialization in .NET with example
Did I miss anything else in these resolution steps?
Did the above steps resolve your issue? Please sound off your comments below!
Happy Coding !!
Please bookmark this page and share it with your friends. Please Subscribe to the blog to get a notification on freshly published best practices and guidelines for software design and development.
Using Jackson to serialize my JPA entities with many-to-many relationship into JSON, I got a wrong JSON response and the application entered in an infinite loop giving as output an infinite recursion Stackoverflow error.
To solve the problem, there are general two ways according to the Jackson documentation.
Approach 1
Before Jackson 2.0, handling of cyclic object graphs was limited to specific case of parent/child(bi-directional) references. Using @JsonManagedReference and @JsonBackReference
Add the @JsonManagedReference in the forward part of the relationship which you want to serialize, and add in the back part of the relationship which will not be serialized. See the following example that Material and Supplier is @ManyToMany relationship.
@Entity
public class Material{
…
@JsonManagedReference
private List<Supplier> costSuppliers = new ArrayList<>();
…
}
@Entity
public class Supplier{
…
@JsonBackReference
private List<Material> costMaterials = new ArrayList<>();
….
}
If we serialize a Material instance to JSON, we will get an Array containing Supplier instances, but the drawback of this approach is that, when we serialize a Supplier instance to JSON, we will not get the Material array instance.
Approach 2
Jackson 2 provides a new annotation @JsonIdentityInfo which is used for indicating that values of annotated type or property should be serializing so that instances either contain additional object identifier, or as a reference that consists of an object id that refers to a full serialization. For the last example will be someting like this:
@Entity
public class Material{
…
private List<Supplier> costSuppliers = new ArrayList<>();
…
}
@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,property = "id")
public class Supplier{
…
private List<Material> costMaterials = new ArrayList<>();
….
}
Thus the cyclic dependency and Stackoverflow issue could be solved. But the drawback is that, just as the Jackson documentation says:
«In practice this is done by serializing the first instance as full object and object identity, and other references to the object as reference values.»
It means that, say, we serialized a Material object which has an Supplier array, however, only the first element of the array is Supplier object, the rest elements in the array is not Supplier object but Supplier reference (general the id). This not what a want, cause generally I want to render the whole properties of the Supplier object, but I need to request the Supplier info again with its reference
Approach 3
Forget @JsonManagedReference, @JsonBackReference, and @JsonIdentityInfo, we just use the simple @JsonIgnoreProperties, see below:
@Entity
public class Material{
…
@JsonIgnoreProperties("costMaterials")
private List<Supplier> costSuppliers = new ArrayList<>();
…
}
@Entity
public class Supplier{
…
@JsonIgnoreProperties("costSuppliers")
private List<Material> costMaterials = new ArrayList<>();
….
}
Simple annotation and simple use, NO infinite recursive Stackoverflow and get all the «Object» information in the serialized JSON
#node.js #mongodb #mongoose #video-intelligence-api
Вопрос:
Я написал сервис, который анализирует видео с помощью Google Cloud Video Intelligence
И я сохраняю результаты анализа в MongoDB с помощью мангуста
Это модель, которую я использую (я все упростил, чтобы избежать путаницы).:
// Video.js
const mongoose = require('mongoose');
const videoSchema = new mongoose.Schema({
analysis_progress: {
percent: { type: Number, required: true },
details: {}
},
status: {
type: String,
enum: ['idle', 'processing', 'done', 'failed'],
default: 'idle'
}
});
module.exports = mongoose.model('Video', videoSchema);
Когда операция анализа заканчивается, я вызываю приведенную ниже функцию и выполняю update
ее следующим образом:
function detectFaces(video, results) {
//Build query
let update = {
$set: {
'analysis_results.face_annotations': results.faceDetectionAnnotations // results is the the test result
}
};
Video.findOneAndUpdate({ _id: video._id }, update, { new: true }, (err, result) => {
if (!err)
return console.log("Succesfully saved faces annotiations:", video._id);
throw err // This is the line error thrown
});
}
И вот какую ошибку я получаю:
Error: cyclic dependency detected
at serializeObject (C:UsersmuratOneDriveMasaüstübycapemedia-analysis-apinode_modulesbsonlibbsonparserserializer.js:333:34)
at serializeInto (C:UsersmuratOneDriveMasaüstübycapemedia-analysis-apinode_modulesbsonlibbsonparserserializer.js:947:17)
...
Решения, которые я пробовал:
- Добавлена
{autoIndex: false}
в конфигурацию бд.
mongoose.connect(process.env.DB_CONNECTION, {useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false, autoIndex: false });
- Удаление
retryWrites=true
из структуры URI Mongo. (У меня уже не было этого параметра в URI подключения)
Итак, я думаю, что источник проблемы в том, что я сохраняю весь результат теста, но у меня нет другого выбора для этого. Мне нужно сохранить все как есть.
Я открыт для любых предложений.
Ответ №1:
Как я и предполагал, проблема заключалась в том, что cyclic dependency
в объекте, который пришел ко мне из Google, было а.
С помощью моего коллеги:
Затем, поскольку JSON.stringify() изменяет объект на простые типы: строка, число, массив, объект, логическое значение, он не способен хранить ссылки на объекты для этого с помощью stringify, а затем анализировать, вы уничтожаете информацию, которую stringify не может преобразовать.
Другим способом было бы узнать, в каком поле содержится циклическая ссылка, а затем отменить или удалить это поле.
Я не мог найти, в каком поле есть cycylic dependency
, поэтому я использовал I JSON.stringfy()
и JSON.parse()
удалил его.
let videoAnnotiations = JSON.stringify(operationResult.annotationResults[0]);
videoAnnotiations = JSON.parse(videoAnnotiations);