You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#结合MongoDB时,如何更新包含JObject的POCO对象并解决序列化异常问题?

Solution for MongoDB Serialization/Deserialization Error with JObject

This is a common pitfall when mixing MongoDB's default serialization with Newtonsoft.Json's JObject/JArray types. Let's break down why this happens and walk through actionable fixes:

The core issue is that MongoDB's C# driver treats JObject and JArray as regular .NET objects by default. During serialization, it adds type discriminator fields (_t and _v) to track the exact .NET type. When deserializing, the driver tries to reconstruct these types using this discriminator data, which clashes with how Newtonsoft.Json's JToken types work—resulting in the ArgumentException you encountered.

Here are three reliable solutions to resolve this:

MongoDB's native BsonDocument is purpose-built to map directly to BSON structures, eliminating serialization conflicts entirely. This is the cleanest approach if you don't strictly need JObject.

Update Your Model

Modify the RoofDesign record to use BsonDocument? instead of JObject?:

using MongoDB.Bson;

public record RoofDesign {
    public int CountOfPanels { get; init; }
    public RoofDesignImages? Images { get; init; }
    public BsonDocument? EditorData { get; init; }
}

Handle Frontend Input

When receiving JSON from the frontend, parse it directly into a BsonDocument:

// Example: Convert frontend JSON string to BsonDocument
var editorDataJson = "{\"additionalProp1\": [null], \"additionalProp2\": [null], \"additionalProp3\": [null]}";
var editorData = BsonDocument.Parse(editorDataJson);

The MongoDB driver will serialize BsonDocument into clean, native BSON without extra type fields, and deserialization will work seamlessly.

2. Use MongoDB's Newtonsoft.Json Serializer Package

If you need to keep using JObject, configure the MongoDB driver to use Newtonsoft.Json for serialization instead of its default serializer. This ensures proper handling of JToken types.

Install the Package

Add the MongoDB.Driver.NewtonsoftJson NuGet package to your project.

Configure the Mongo Client

Update your MongoDB client initialization to enable Newtonsoft.Json serialization:

using MongoDB.Driver;
using MongoDB.Driver.NewtonsoftJson;

var mongoSettings = MongoClientSettings.FromConnectionString("your-mongodb-connection-string");
// Enable Newtonsoft.Json serialization for proper JObject handling
mongoSettings.UseNewtonsoftJson();

var mongoClient = new MongoClient(mongoSettings);

This setup tells the driver to use Newtonsoft.Json's serializer, which understands JObject and JArray natively—no more _t/_v fields, and deserialization will work as expected.

3. Implement a Custom JObject Serializer

If you can't use the Newtonsoft.Json package, create a custom BSON serializer to handle JObject directly.

Create the Custom Serializer

using MongoDB.Bson.Serialization;
using MongoDB.Bson;
using Newtonsoft.Json.Linq;

public class JObjectSerializer : IBsonSerializer<JObject>
{
    public Type ValueType => typeof(JObject);

    public JObject Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        // Convert BSON document to JObject
        var bsonDoc = BsonDocumentSerializer.Instance.Deserialize(context, args);
        return JObject.Parse(bsonDoc.ToJson());
    }

    public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, JObject value)
    {
        // Convert JObject to BSON document
        var bsonDoc = BsonDocument.Parse(value.ToString());
        BsonDocumentSerializer.Instance.Serialize(context, args, bsonDoc);
    }

    // Explicit interface implementations for non-generic IBsonSerializer
    object IBsonSerializer.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        return Deserialize(context, args);
    }

    void IBsonSerializer.Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
    {
        Serialize(context, args, (JObject)value);
    }
}

Register the Serializer

Add the serializer to your MongoDB driver settings during initialization:

var mongoSettings = MongoClientSettings.FromConnectionString("your-connection-string");
var serializerRegistry = new SerializerRegistry(
    new List<IBsonSerializer> { new JObjectSerializer() }
);
mongoSettings.SerializerRegistry = serializerRegistry;

var mongoClient = new MongoClient(mongoSettings);

This custom serializer converts between JObject and BsonDocument during serialization/deserialization, bypassing the driver's default type handling.


内容的提问来源于stack exchange,提问作者Brian Kessler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 07:54:06