元素“id”与嵌套类的任何字段或错误属性都不匹配

Hus*_*slu 3 c# mongodb mongodb-.net-driver

我有以下 mongodb 文档架构;

{ 
    "_id" : ObjectId("5c9d34ff781318afb9e8ab43"), 
    "name" : "Name", 
    "slug" : "slug",
    "services" : {
        "subservice" : {
            "id" : NumberInt(37030)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我将我的课程定义为;

public class MainModel
{
    public ObjectId Id { get; set; }

    [BsonElement("name")]
    public string Name { get; set; }

    [BsonElement("slug")]
    public string Slug { get; set; }

    [BsonElement("services")]
    public ServicesDef Services { get; set; }

    public class ServicesDef 
    {
        [BsonElement("subservice")]
        public SubServiceDef SubService{ get; set; }

        public class SubServiceDef 
        {
            [BsonElement("id")]
            public int Id { get; set; }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但不知何故,当我查询文档时;

var result = await Repository.FindAsync(x => x.Slug == slug);
Run Code Online (Sandbox Code Playgroud)

该 services.subservice.id 未正确注册和获取

元素“id”与 SubServiceDef 类的任何字段或属性都不匹配。

卡在这里并寻求建议。

我想我遇到了同样的问题,无法使用“Id”属性反序列化,但似乎还有解决方案。

mic*_*ckl 6

长话短说:这都是关于约定的。MongoDB .NET 驱动程序公开静态类ConventionRegistry,它允许您注册自己的约定(更多在这里)。此外,还有两个“内置”约定__defaults____attributes__. 深入挖掘(驱动程序github),您会发现它注册了一个非常有趣的约定:

new NamedIdMemberConvention(new [] { "Id", "id", "_id" })
Run Code Online (Sandbox Code Playgroud)

这意味着id成员将被视为常规 BSON _id 元素。

如何解决?

您可以摆脱默认约定

ConventionRegistry.Remove("__defaults__");
Run Code Online (Sandbox Code Playgroud)

但是,您将自动放弃所有其他驱动程序约定,这是非常危险的。或者,您可以创建一个始终为空的假属性:

public class SubServiceDef
{
    [BsonElement("id")]
    public int Id { get; set; }

    [BsonId]
    public ObjectId FakeId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

或者你可以只使用BsonNoId属性

指定类的 IdMember 应为 null。

[BsonNoId]
public class SubServiceDef
{
    [BsonElement("id")]
    public int Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

因此,约定将id在类映射中将您设置为 IdMember,但是在后处理期间,此属性将强制 IdMember 为空,并且您的类将成功反序列化

  • @Simons0n 无法想象这可能是生死攸关的问题,但很高兴听到这个消息,注意安全! (2认同)