【问题标题】:MongoDB ObjectId conversion error in c# using Newtonsoft Deserializationc#中使用Newtonsoft反序列化的MongoDB ObjectId转换错误
【发布时间】:2021-10-05 07:40:06
【问题描述】:

我一直在努力将 MongoDB BSON 文档转换为 C# 中的 List 对象。 转换时,我得到以下错误

"{"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 作为字符串。

请帮忙解决这个问题。

示例 document.toJson() 值

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

【问题讨论】:

  • 请分享document.ToJson()的值
  • @viveknuna - 添加了 document.ToJson() 值

标签: c# mongodb-query json.net mongodb-.net-driver newtonscript


【解决方案1】:

你只使用了half of the relevant code

如果你写这个 JSON:

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

正如BsonObject.ToJson() 所做的那样,那不是 JSON。 ObjectId(...) 方言,就像 Date()NumberLong()NumberInt()NumberDecimal() 是使 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

【讨论】:

  • 对我来说 var deserialized = BsonSerializer.Deserialize(document);不起作用,因为来自 mongodb 的每个值我都需要将其作为 JSON 获取,并且上面的 Mongo 对象类型(整数)值不会转换为 c# 对象类型。这就是我将它用作 JsonConvert.Deserialize 的原因。所以就像我在 BSON 文档中的一个键有一个 int 值,它没有被转换为 c# 字符串。
  • 您的问题是 Mongo 的 ToJson(),您无法将其提供给正确的 JSON 解析器。这是它自己的方言。
猜你喜欢
  • 2015-02-16
  • 1970-01-01
  • 2018-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多