1

我在使用 BsonSerializer 序列化 BsonDocuments 时遇到问题。

我正在使用var bsonDoc = collection.Find(...)从 MongoDB 数据库中提取单个文档。然后我尝试使用序列化它 var strongTypedDocument = BsonSerializer.Deserialize<MainSDocument>(bsonDoc);

这是 BsonDocument

   { 
      "MainSPayload" : 
        { 
           "GDeets" : { "Id" : 0, "GSerial" : "XX123XX123" }
        }
   }

这是 C# 类

[JsonObject(MemberSerialization.OptIn)]
[BsonIgnoreExtraElements]
public class MainSDocument
{
    [JsonProperty(Required = Required.Always)]
    public MainState MainSPayload
    {
        get; set;
    }
}

[JsonObject(MemberSerialization.OptIn)]
public class MainState 
{
    [JsonProperty(Required = Required.Always)]
    public GDetails GDeets
    {
        get; set;
    }
}

public class GDetails 
{
    public int Id
    {
        get; set;
    }

    public string GSerial
    {
        get; set;
    }
}

我得到的错误是:FormatException: An error occurred while deserializing the GDetails property of class MainState : Element 'Id' does not match any field or property of class GDetails .'

为什么会这样?为什么该元素与类中Id的 int 元素不匹配?IdGDetails

4

1 回答 1

1

字段的序列化Id有一个特殊的工作流程,可以有效地将这个值转换成服务器端如何表示它:_id. 要解决它,您可以使用:

        BsonClassMap.RegisterClassMap<GDetails>(c =>
        {
            c.AutoMap();
            c.UnmapField(u => u.Id); // remove default _id workflow 
            c.MapField(u => u.Id); // add a simple Id field
        });

或更简单:

        BsonClassMap.RegisterClassMap<GDetails>(c =>
        {
            c.AutoMap();
            c.SetIdMember(null);
        });

更新:有一点更灵活的方式。您可以配置新约定并设置使用它所需的类型:

        var customPack = new ConventionPack();
        customPack.Add(new NoIdMemberConvention());
        ConventionRegistry.Register("NoIdConvention", customPack, t => t == typeof(GDetails));

也可以代替上面的,您只需将 BsonNoId 属性添加到您的类中:

    [BsonNoId]
    public class GDetails
    {
        public int Id
        {
            get; set;
        }

        public string GSerial
        {
            get; set;
        }
    }
于 2021-12-01T13:15:38.407 回答