简体   繁体   English

反序列化错误ASP.NET MongoDB

[英]Deserialization Error ASP.NET MongoDB

I am trying to retireve all the documents in my MongoDB collection via a REST api built in ASP.NET MVC 4 and I have encoutered an error when i enter localhost:50491/api/document: 我试图通过ASP.NET MVC 4中内置的REST api退出MongoDB集合中的所有文档,当我输入localhost时遇到错误:50491 / api / document:

An error occurred while deserializing the Id property of class Acord_Rest_API.Models.Document: Cannot deserialize string from BsonType ObjectId. 反序列化类Acord_Rest_API.Models.Document的Id属性时发生错误:无法从BsonType ObjectId反序列化字符串。

My controller looks like: 我的控制器看起来像:

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();
    }
}

My MongoDB document looks like this? 我的MongoDB文档是这样的吗? 在此输入图像描述

What am I missing here? 我在这里错过了什么?

My class that connects to the DB: 我连接到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");
    }
}

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

MongoConnectionHelper does the connection to the DB, DocumentController has the methods to retrive all the documents and Document contains what you have suggested in your answer. MongoConnectionHelper与DB连接,DocumentController具有检索所有文档的方法,Document包含您在答案中建议的内容。

EDIT here is the Document class: 这里编辑的是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; }
}

The Mongo Id is not a "string" and the Mongo.Bson library will not serialize it to a string automatically. Mongo Id不是“字符串”,Mongo.Bson库不会自动将其序列化为字符串。 If you are using the Mongo.Bson library, you need to set the id property on your class to be a ObjectId type which is available in that library. 如果您使用的是Mongo.Bson库,则需要将类的id属性设置为该库中可用的ObjectId类型。

The problem here is that the .net serializer doesn't know how to serialize the custom type ObjectId that's the mongo built in Id (not sure why). 这里的问题是.net序列化程序不知道如何序列化自定义类型ObjectId,它是在Id中构建的mongo(不知道为什么)。 It is not marked as [Serializable] so you have to get ASP.NET to bypass it or create another class that doesn't have one and convert it to a string. 它没有标记为[Serializable],因此您必须让ASP.NET绕过它或创建另一个没有的类并将其转换为字符串。

If you need a string to use in your app, you should disable the serialization of the MongoId to xml (if that's what you're trying to do), then you can add a property like this to your class: 如果你需要在你的应用程序中使用一个字符串,你应该禁用MongoId到xml的序列化(如果那是你想要做的),那么你可以在你的类中添加这样的属性:

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

public string MongoId
{
    get { return _id.ToString(); }
    set { _id = ObjectId.Parse(value); }
}

The alternative it to create a seperate mapped class to manage the return data. 另一种方法是创建一个单独的映射类来管理返回数据。

EDIT In that case you should use the "opt-in" approach. 编辑在这种情况下,您应该使用“选择加入”方法。 This involves decorating your class to look like the following: 这涉及将您的课程装饰为如下所示:

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

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

... ...

DataMember will flag only those properties for serialization. DataMember将仅标记序列化的属性。 Are you using POCO classes for your "Document" object? 您是否正在为“文档”对象使用POCO类? If so the above should work fine. 如果是这样,上面应该可以正常工作

I would however recommend creating a mapped view of the "Document" object for passing out publically. 但是,我建议创建“Document”对象的映射视图,以便公开传递。 In these situations youalmost always end up wanting a slightly different "contract" to your actual database entity 在这些情况下,您最终总是希望与您的实际数据库实体略有不同的“契约”

A more simple approach is to tell MongoDB to treat string field as ObjectId. 一种更简单的方法是告诉MongoDB将字符串字段视为ObjectId。 You can do it easily by using BsonType attribute. 您可以使用BsonType属性轻松BsonType

[BsonRepresentation(BsonType.ObjectId)]
public string _id { get; set; }

i think that you are missing the [BsonId] convention so your class should look like this: 我认为你错过了[BsonId]约定所以你的类应该是这样的:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM