反序列化错误ASP.NET MongoDB

Mik*_*nes 4 c# rest mongodb 10gen-csharp-driver mongodb-.net-driver

我试图通过ASP.NET MVC 4中内置的REST api退出MongoDB集合中的所有文档,当我输入localhost时遇到错误:50491/api/document:

反序列化类Acord_Rest_API.Models.Document的Id属性时发生错误:无法从BsonType ObjectId反序列化字符串.

我的控制器看起来像:

public class DocumentController : ApiController
{
    public readonly MongoConnectionHelper<Document> docs;

    public DocumentController()
    {
        docs = new MongoConnectionHelper<Document>();
    }

    public IList<Document> getAllDocs()
    {
        var alldocs = docs.collection.FindAll();
        return alldocs.ToList();
    }
}
Run Code Online (Sandbox Code Playgroud)

我的MongoDB文档是这样的吗? 在此输入图像描述

我在这里错过了什么?

我连接到DB的类:

public class MongoConnectionHelper<T> where T: class
{
    public MongoCollection<T> collection { get; private set; }

    public MongoConnectionHelper()
    {
        string connectionString = "mongodb://127.0.0.1";
        var server = MongoServer.Create(connectionString);
        if (server.State == MongoServerState.Disconnected)
        {
            server.Connect();
        }
        var conn = server.GetDatabase("Acord");
        collection = conn.GetCollection<T>("Mappings");
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑这里是我的解决方案: 在此输入图像描述

MongoConnectionHelper与DB连接,DocumentController具有检索所有文档的方法,Document包含您在答案中建议的内容.

这里编辑的是Document类:

[DataContract]
public class Document
{
    public ObjectId _id { get; set; }

    [DataMember]
    public string MongoId
    {
        get { return _id.ToString(); }
        set { _id = ObjectId.Parse(value); }
    }
    public IList<string> alldocs { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

Gat*_*ats 6

Mongo Id不是"字符串",Mongo.Bson库不会自动将其序列化为字符串.如果您使用的是Mongo.Bson库,则需要将类的id属性设置为该库中可用的ObjectId类型.

这里的问题是.net序列化程序不知道如何序列化自定义类型ObjectId,它是在Id中构建的mongo(不知道为什么).它没有标记为[Serializable],因此您必须让ASP.NET绕过它或创建另一个没有的类并将其转换为字符串.

如果你需要在你的应用程序中使用一个字符串,你应该禁用MongoId到xml的序列化(如果那是你想要做的),那么你可以在你的类中添加这样的属性:

[XmlIgnore]
public ObjectId _id { get; set; }

public string MongoId
{
    get { return _id.ToString(); }
    set { _id = ObjectId.Parse(value); }
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是创建一个单独的映射类来管理返回数据.

编辑在这种情况下,您应该使用"选择加入"方法.这涉及将您的课程装饰为如下所示:

[DataContract]
public class Document
{
    public ObjectId _id { get; set; }

    [DataMember]
    public string MongoId
    {
        get { return _id.ToString(); }
        set { _id = ObjectId.Parse(value); }
    }
Run Code Online (Sandbox Code Playgroud)

...

DataMember将仅标记序列化的属性.您是否正在为"文档"对象使用POCO类?如果是这样,上面应该可以正常工作

但是,我建议创建"Document"对象的映射视图,以便公开传递.在这些情况下,您最终总是希望与实际的数据库实体略有不同的"契约"


Ofi*_*fir 6

一种更简单的方法是告诉MongoDB将字符串字段视为ObjectId。您可以通过使用BsonType属性轻松地做到这一点。

[BsonRepresentation(BsonType.ObjectId)]
public string _id { get; set; }
Run Code Online (Sandbox Code Playgroud)