繁体   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