使用Newtonsoft反序列化的C#中的MongoDB对象ID转换错误 [英] MongoDB ObjectId conversion error in c# using Newtonsoft Deserialization

查看:0
本文介绍了使用Newtonsoft反序列化的C#中的MongoDB对象ID转换错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直致力于将MongoDB bson文档转换为C#中的列表对象。 转换时,出现以下错误

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

在Stackoverflow中搜索类似问题后,我发现以下链接

JSON.NET cast error when serializing 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类被覆盖的方法应该得到调用,但情况并非如此。 我们需要在Model中以字符串形式获取OBJECTID。

请帮助解决此问题。

文档示例.toJson()值

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

推荐答案

您只使用了half of the relevant code

如果您编写此JSON:

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

BsonObject.ToJson()一样,那就不是JSON。与[2-2]、[2-3]、[2-4]和NumberDecimal()一样,ObjectId(...)方言是使MongoDB产生无效JSON构造,因为它是其内部BSON存储格式的表示形式。

因此,如果希望将其视为JSON,请编写有效的JSON。代码就在链接中:您需要自己序列化对象。请参阅How to deserialize a BsonDocument object back to class

首先确保Mongo C#驱动程序将BSON反序列化为您的POCO:

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

然后使用您的转换器将该对象序列化为JSON:

var json = JsonConvert.SerializeObject(deserialized);

您的输出将变得非常可解析:

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

当您再次尝试将其反序列化为BTMobj时,类型的元数据(属性)将告诉解析器将";611cf42e1e4c89336b6fe2f0";解析为BsonObjectId

这篇关于使用Newtonsoft反序列化的C#中的MongoDB对象ID转换错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆