我正在使用MongoDB C#驱动程序。我有一些BsonDocument
,其中包含一些MongoDB特定类型的数据(如ObjectID和ISODates)。我想将其转换为有效的通用JSON字符串。换句话说,我不能拥有像_id: ObjectId(...)
或date: ISODate(...)
这样的东西,但更喜欢_id: "..."
和date: "..."
。基本上,我想将只有MongoDB识别的特殊类型转换为常规字符串,以便更容易地解析它们。问题是像.ToJson()
这样的内置函数(另一个StackOverflow答案建议)并没有真正将文档转换为有效的JSON,因为它维护了这些特殊类型。我的文档还包含许多级别的数组和子文档,因此简单的for循环是不够的。转换避免这个问题的BsonDocument
的最佳方法是什么?我更喜欢内置的东西而不是手动递归文档来修复所有问题。
我遇到了同样的事情,你可以通过以下方式获得有效的JSON:
var jsonWriterSettings = new JsonWriterSettings { OutputMode = JsonOutputMode.Strict };
JObject json = JObject.Parse(postBsonDoc.ToJson<MongoDB.Bson.BsonDocument>(jsonWriterSettings));
但它会返回如下内容:
{"_id":{"$oid":"559843798f9e1d0fe895c831"}, "DatePosted":{"$date":1436107641138}}
我还在试图找到一种方法来压扁它。
我使用的大部分时间,Json.NET
JsonConvert.SerializeObject(obj);
大部分时间都可以解决问题。如果需要,您可以设置一些JsonSerializerSettings
在我看来,最好的选择是使用Newtonsoft.Json.Bson.BsonReader
。这是一个完整的例子:
public string ToJson(BsonDocument bson)
{
using (var stream = new MemoryStream())
{
using (var writer = new BsonBinaryWriter(stream))
{
BsonSerializer.Serialize(writer, typeof(BsonDocument), bson);
}
stream.Seek(0, SeekOrigin.Begin);
using (var reader = new Newtonsoft.Json.Bson.BsonReader(stream))
{
var sb = new StringBuilder();
var sw = new StringWriter(sb);
using (var jWriter = new JsonTextWriter(sw))
{
jWriter.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
jWriter.WriteToken(reader);
}
return sb.ToString();
}
}
}
我认为这应该正确处理所有情况(日期,ID,......)。
怎么样的:
JsonConvert.SerializeObject(BsonTypeMapper.MapToDotNetValue(bsonDoc));
对于BsonDocument列表
bsonDocList.ConvertAll(BsonTypeMapper.MapToDotNetValue)
这是我做的方式,跳过mongodb _id条目。
var collection = _database.GetCollection<BsonDocument>("test");
var result = await collection.Find(new BsonDocument())
.Project(Builders<BsonDocument>.Projection.Exclude("_id"))
.ToListAsync();
var obj = result.ToJson();
如果您需要使用此ASP.NET Core,则可能会返回具有BsonDocument的模型以便能够添加动态数据。你可以根据MarkKGreenway的答案使用这个JsonConverter实现!
public class BsonDocumentJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(BsonDocument);
}
public override bool CanRead
{
get
{
return false;
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
//string json = (value as BsonDocument).ToJson(); //!NB: this returns BSON not JSON. Why on earth is it called ToJson!?
string json = JsonConvert.SerializeObject(value);
writer.WriteRawValue(json);
}
}
然后在你的Startup.cs
中添加以下内容。
services.AddMvc()
.AddJsonOptions(options => options.SerializerSettings.Converters.Add(new BsonDocumentJsonConverter()));
关于什么
String json = result.toJson(JsonWriterSettings.builder().objectIdConverter(new Converter<ObjectId>() {
@Override
public void convert(ObjectId value, StrictJsonWriter writer) {
writer.writeString(value.toHexString());
}
}).build());
如果BSON文档的内容保存为,如下所示
{
"Date" : "2019-04-05T07:07:31.979Z",
"BSONCONTENT" : {
"_t" : "MongoDB.Bson.BsonDocument, MongoDB.Bson",
"_v" : {
"A" : "XXXX",
"B" : 234
}
}
}
然后它适用于泛型类。
private static T ProcessBsonConversion<T>(BsonDocument data)
{
var content = data.GetElement("_v");
var jsonDataContent= content.Value.AsBsonValue.ToJson();
return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(jsonDataContent);
}