4

ASP.NET MVC4に組み込まれているRESTAPIを介してMongoDBコレクション内のすべてのドキュメントを廃止しようとしていますが、localhost:50491 / api/documentと入力するとエラーが発生します。

クラスAcord_Rest_API.Models.DocumentのIdプロパティの逆シリアル化中にエラーが発生しました:BsonTypeObjectIdから文字列を逆シリアル化できません。

私のコントローラーは次のようになります:

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

私の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");
    }
}

ここで編集するのが私の解決策です: ここに画像の説明を入力してください

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; }
}
4

3 に答える 3

6

Mongo Idは「文字列」ではなく、Mongo.Bsonライブラリはそれを文字列に自動的にシリアル化しません。Mongo.Bsonライブラリを使用している場合は、クラスのidプロパティを、そのライブラリで使用できるObjectIdタイプに設定する必要があります。

ここでの問題は、.netシリアライザーが、Idに組み込まれているmongoであるカスタムタイプObjectIdをシリアル化する方法を認識していないことです(理由はわかりません)。[Serializable]としてマークされていないため、ASP.NETでバイパスするか、ASP.NETを持たない別のクラスを作成して、文字列に変換する必要があります。

アプリで使用する文字列が必要な場合は、MongoIdのxmlへのシリアル化を無効にする必要があります(これを実行しようとしている場合)。次に、次のようなプロパティをクラスに追加できます。

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

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

別の方法として、戻りデータを管理するための個別のマップされたクラスを作成します。

編集その場合、「オプトイン」アプローチを使用する必要があります。これには、クラスを次のように装飾することが含まれます。

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

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

..。

DataMemberは、シリアル化のためにそれらのプロパティのみにフラグを立てます。「ドキュメント」オブジェクトにPOCOクラスを使用していますか?もしそうなら、上記はうまくいくはずです。

ただし、公開するために「Document」オブジェクトのマップされたビューを作成することをお勧めします。このような状況では、ほとんどの場合、実際のデータベースエンティティとは少し異なる「契約」が必要になります。

于 2013-01-11T11:10:13.940 に答える
6

より簡単なアプローチは、文字列フィールドをObjectIdとして扱うようにMongoDBに指示することです。BsonType属性を使用することで簡単に行うことができます。

[BsonRepresentation(BsonType.ObjectId)]
public string _id { get; set; }
于 2016-01-19T07:46:16.347 に答える
1

[BsonId]規則が欠落していると思うので、クラスは次のようになります。

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

    [DataMember]
    public string MongoId
    {
        get { return _id.ToString(); }
        set { _id = ObjectId.Parse(value); }
    }
于 2016-08-09T14:16:22.620 に答える