簡體   English   中英

MongoDB c#使用Newtonsoft Deserialization中的ObjectId轉換錯誤

[英]MongoDB ObjectId conversion error in c# using Newtonsoft Deserialization

我一直在努力將 MongoDB BSON 文檔轉換為 c# 中的列表 object。轉換時,出現以下錯誤

"{"Unexpected character encountered while parsing value: O. Path '_id', line 1, position 10."}"

在 stackoverflow 中搜索類似問題后,我找到了以下鏈接

JSON.NET 序列化 Mongo ObjectId 時發生轉換錯誤

我也跟着。

我的代碼:

示例實體/模型

public class BTMObj
{
    [JsonConverter(typeof(MongoDataSerializer))]
    public ObjectId _id { get; set; }
    public string requestFormat { get; set; }
}

public class MongoDataSerializer : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(ObjectId);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType != JsonToken.String)
        {
            throw new Exception(
                String.Format("Unexpected token parsing ObjectId. Expected String, got {0}.",
                              reader.TokenType));
        }

        var value = (string)reader.Value;
        return String.IsNullOrEmpty(value) ? ObjectId.Empty : new ObjectId(value);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (value is ObjectId)
        {
            var objectId = (ObjectId)value;

            writer.WriteValue(objectId != ObjectId.Empty ? objectId.ToString() : String.Empty);
        }
        else
        {
            throw new Exception("Expected ObjectId value.");
        }
    }
}

public List<T> GetMongoCollection<T>(string collectionName)
{
    try
    {
        List<T> list = new List<T>();
        var client = new MongoClient(Convert.ToString(ConfigurationManager.AppSettings["MONGO_CONNECTION"]));
        var database = client.GetDatabase(Convert.ToString(ConfigurationManager.AppSettings["MONGO_DB"]));
        var collection = database.GetCollection<BsonDocument>(collectionName);
        var documents = collection.Find(new BsonDocument()).ToList();
        foreach (var document in documents)
        {
            try
            {
                list.Add(JsonConvert.DeserializeObject<T>(document.ToJson()));
            }
            catch (Exception ex)
            {

            }
        }
        return list;
    }
    catch (Exception ex)
    {
        throw;
    }
}

調用方法

list = mongoDBOperations.GetMongoCollection<BTMObj>(Collection);

MongoDataSerializer class 覆蓋的方法應該得到調用,但事實並非如此。 我們的需求是獲取 Model 中的 ObjectId 作為字符串。

請幫助解決這個問題。

示例 document.toJson() 值

{
  "_id": ObjectId("611cf42e1e4c89336b6fe2f0"),
  "requestFormat": "json"
}

您只使用了相關代碼的一半

如果你寫這個 JSON:

  "_id": ObjectId("611cf42e1e4c89336b6fe2f0"),
  "requestFormat": "json"
}

正如BsonObject.ToJson()所做的那樣,那不是 JSON。 ObjectId(...)方言,就像Date()NumberLong()NumberInt()NumberDecimal()是使 MongoDB 吐出無效 JSON 的構造,因為它是其內部 BSON 存儲格式的表示

因此,如果您想將其視為 JSON,請寫入有效的 JSON。代碼就在鏈接中:您需要自己序列化 object。 請參閱如何將 BsonDocument object 反序列化回 class

首先確保 Mongo C# 驅動程序將 BSON 反序列化到您的 POCO 中:

// Prefer using statically-typed extension methods such as 
// _collection.FindAs<MyType>()
var deserialized = BsonSerializer.Deserialize<BTMobj>(document);

然后使用轉換器將 object 序列化為 JSON:

var json = JsonConvert.SerializeObject(deserialized);

您的 output 將變得非常可解析:

  "_id": "611cf42e1e4c89336b6fe2f0",
  "requestFormat": "json"
}

當您再次嘗試將其反序列化為BsonObjectId時,您的類型的元數據(屬性)將告訴解析器將“611cf42e1e4c89336b6fe2f0”解析為BTMobj

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM