[CSHARP-4573] Serializing a PROCO containing a JsonObject fails. Created: 17/Mar/23  Updated: 27/Oct/23  Resolved: 17/Mar/23

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: 2.19.0
Fix Version/s: None

Type: Bug Priority: Unknown
Reporter: Sam Stonew Assignee: Robert Stam
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Documentation Changes Summary:

1. What would you like to communicate to the user about this feature?
2. Would you like the user to see examples of the syntax and/or executable code and its output?
3. Which versions of the driver/connector does this apply to?


 Description   

Summary

When trying to insert a document into MongoDB using the C# Driver with a Typed document we receive a recursive error because it is not able to serialize (and deserialize) the data

 

Please provide the version of the driver. If applicable, please provide the MongoDB server version and topology (standalone, replica set, or sharded cluster).

Driver v2.19.0

Server Standalone. I don't know what is the version of the Mongo server, but I'm using the latest docker image to this day for development.

How to Reproduce

 

using System.Text.Json;
using System.Text.Json.Nodes;
using MongoDB.Driver;
 
var database = new MongoClient().GetDatabase("testdatabase");
JsonObject json = JsonSerializer.Deserialize<JsonObject>("{\"name\":\"Jane Doe\",\"favorite-game\":\"Stardew Valley\",\"subscriber\":false}")!;
var doc = new DocumentError()
{
    CorrelationId = "testcor",
    Error = json
};
database.GetCollection<DocumentError>("test").InsertOne(doc);
 
public class DocumentError
{
    public string CorrelationId { get; set; }    
    public JsonObject Error { get; set; }
} 

 

 

Additional Background

.NET 7, using Microsoft System.Text.Json.Nodes

A work around who is really not performant and is not an option for what we are developing is converting "DocumentError" to a json string, to afterward convert it into a bsondocument. 

While this work, for deserializing (getting the data) we need to get it in a BsonDocument and foreach create a new instance of "DocumentError" via a constructor to make it work.



 Comments   
Comment by Robert Stam [ 17/Mar/23 ]

The way our POCO mapping works is that when serializing a POCO we recursively serialize each of its properties (or public fields). For this to work there can't be any circular references, or the serialization gets into an infinite loop. We throw an exception when the depth gets too deep to prevent infinite loops.

Unfortunately for your use case, the Json.NET POCOs contain infinite loops. For example, the Parent property points to the parent, and when we attempt to serialize the Parent one of its properties is the node you started from, at which point the same Parent will get serialized again, which is the cause of the infinite loop.

There is nothing we can do on our side to handle this.

The easiest work around is what you already suggested, which is using Json.NET to serialize the JsonObject to a string, after which you can either work with the string or Parse it into something else.

Alternatively, you could write custom serializers for Json.Net objects. It's possible that instead of writing custom serializers you could create custom class maps and register those (which might allow the standard BsonClassMapSerializer to work without getting into an infinite loop), but I haven't actually tried that.

I'm sorry I don't have better news for you, but we just can't support this scenario out of the box.

Comment by Sam Stonew [ 17/Mar/23 ]

The Error:

An error occurred while serializing the Error property of class DocumentError: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: An error occurred while serializing the Parent property of class System.Text.Json.Nodes.JsonNode: Maximum serialization depth exceeded (does the object being serialized have a circular reference?).'
 

Generated at Wed Feb 07 21:48:38 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.