1

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

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

在stackoverflow中搜索类似问题后,我发现下面的链接

序列化 Mongo ObjectId 时出现 JSON.NET 转换错误

我也跟着。

我的代码:

示例实体/模型

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 类覆盖的方法应该被调用,但事实并非如此。我们需要在模型中获取 ObjectId 作为字符串。

请帮助解决此问题。

示例 document.toJson() 值

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

1 回答 1

1

您只使用了一半的相关代码

如果您编写此 JSON:

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

同样BsonObject.ToJson(),那不是 JSON。方言,ObjectId(...)就像,和是使 MongoDB 吐出无效 JSON 的结构,因为它是其内部 BSON 存储格式的表示Date()NumberLong()NumberInt()NumberDecimal()

因此,如果您想将其视为 JSON,请编写有效的 JSON。代码就在链接中:您需要自己序列化对象。请参阅如何将 BsonDocument 对象反序列化回类

首先确保 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"
}

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

于 2021-10-05T08:29:48.257 回答