简体   繁体   English

MongoDB c#使用Newtonsoft Deserialization中的ObjectId转换错误

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

I have been working to convert MongoDB BSON documents to List object in c#. While converting, i get below error我一直在努力将 MongoDB BSON 文档转换为 c# 中的列表 object。转换时,出现以下错误

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

After searching for similar issues in stackoverflow, i found below link在 stackoverflow 中搜索类似问题后,我找到了以下链接

JSON.NET cast error when serializing Mongo ObjectId JSON.NET 序列化 Mongo ObjectId 时发生转换错误

and i followed the same.我也跟着。

My Code:我的代码:

Sample Entity/Model示例实体/模型

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

Call to Method调用方法

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

MongoDataSerializer class overridden methods should get call which is not the case. MongoDataSerializer class 覆盖的方法应该得到调用,但事实并非如此。 Our need is to get ObjectId as string in Model.我们的需求是获取 Model 中的 ObjectId 作为字符串。

Please help in resolving this issue.请帮助解决这个问题。

Sample document.toJson() value示例 document.toJson() 值

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

You only used half of the relevant code .您只使用了相关代码的一半

If you write this JSON:如果你写这个 JSON:

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

As BsonObject.ToJson() does, then that's not JSON. The ObjectId(...) dialect, just as Date() , NumberLong() , NumberInt() and NumberDecimal() are constructs that make MongoDB spit out invalid JSON, because it's a representation of its internal BSON storage format.正如BsonObject.ToJson()所做的那样,那不是 JSON。 ObjectId(...)方言,就像Date()NumberLong()NumberInt()NumberDecimal()是使 MongoDB 吐出无效 JSON 的构造,因为它是其内部 BSON 存储格式的表示

So if you want to treat it as JSON, write valid JSON. The code is right there in the link: you need to serialize the object yourself.因此,如果您想将其视为 JSON,请写入有效的 JSON。代码就在链接中:您需要自己序列化 object。 See How to deserialize a BsonDocument object back to class .请参阅如何将 BsonDocument object 反序列化回 class

First make sure the Mongo C# driver deserializes the BSON into your POCO:首先确保 Mongo C# 驱动程序将 BSON 反序列化到您的 POCO 中:

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

Then serialize that object to JSON using your converter:然后使用转换器将 object 序列化为 JSON:

var json = JsonConvert.SerializeObject(deserialized);

Your output will then become the very parseable:您的 output 将变得非常可解析:

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

And your type's metadata (attributes) will tell the parser to parse "611cf42e1e4c89336b6fe2f0" as a BsonObjectId when you try to deserialize it into a BTMobj again.当您再次尝试将其反序列化为BsonObjectId时,您的类型的元数据(属性)将告诉解析器将“611cf42e1e4c89336b6fe2f0”解析为BTMobj

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

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