在 C# 中将 MongoDB BsonDocument 转换为有效的 JSON
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27132968/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert MongoDB BsonDocument to valid JSON in C#
提问by CynicalProgrammer
I am working with the MongoDB C# driver. I have a BsonDocumentwith some data which includes some MongoDB-specific types (like ObjectIDs and ISODates). I want to convert this to a valid general-purpose JSON string. In other words, I can't have something like _id: ObjectId(...)or date: ISODate(...)but would prefer _id: "..."and date: "...". Basically, I want to convert these special types that only MongoDB recognizes to regular strings so they can be parsed more easily. The problem is that a built-in function like .ToJson()(which another StackOverflow answer suggests) doesn't really convert the document to valid JSON at all because it maintains these special types. My document also contains many levels of arrays and sub-documents, so a simple for loop will not suffice. What's the best way to convert a BsonDocumentthat avoids this problem? I would prefer something built-in rather than manually recursing through the document to fix all the issues.
我正在使用 MongoDB C# 驱动程序。我有BsonDocument一些数据,其中包括一些 MongoDB 特定的类型(如 ObjectIDs 和 ISODates)。我想将其转换为有效的通用 JSON 字符串。换句话说,我不能有像_id: ObjectId(...)ordate: ISODate(...)但更喜欢_id: "..."and 的东西date: "..."。基本上,我想将这些只有 MongoDB 识别的特殊类型转换为常规字符串,以便可以更轻松地解析它们。问题是内置函数.ToJson()(另一个 StackOverflow 答案建议)并没有真正将文档转换为有效的 JSON,因为它维护了这些特殊类型。我的文档还包含许多级别的数组和子文档,因此简单的 for 循环是不够的。转换 a 的最佳方法是什么BsonDocument这样可以避免这个问题吗?我更喜欢内置的东西,而不是手动遍历文档来解决所有问题。
回答by drye
I've ran into the same thing, you can get valid JSON via:
我遇到了同样的事情,您可以通过以下方式获得有效的 JSON:
var jsonWriterSettings = new JsonWriterSettings { OutputMode = JsonOutputMode.Strict };
JObject json = JObject.Parse(postBsonDoc.ToJson<MongoDB.Bson.BsonDocument>(jsonWriterSettings));
However it will return something like:
但是它会返回类似的东西:
{"_id":{"$oid":"559843798f9e1d0fe895c831"}, "DatePosted":{"$date":1436107641138}}
I'm still trying to find a way to flatten that.
我仍在努力寻找一种方法来压平它。
回答by sandiejat
MongoDB.Bson (2.5+) has support to map between BsonValues and .Net objects. BsonTypeMapper Class
MongoDB.Bson (2.5+) 支持在 BsonValues 和 .Net 对象之间进行映射。 BsonTypeMapper 类
To map a BsonValue (or BsonDocument) to .Net object use
要将 BsonValue(或 BsonDocument)映射到 .Net 对象,请使用
var dotNetObj = BsonTypeMapper.MapToDotNetValue(bsonDoc);
You can then use your choice of serialization library. For example,
然后,您可以使用您选择的序列化库。例如,
JsonConvert.SerializeObject(dotNetObj);
If you have a List of BsonDocument
如果你有一个 BsonDocument 列表
var dotNetObjList = bsonDocList.ConvertAll(BsonTypeMapper.MapToDotNetValue);
回答by MarkKGreenway
回答by Davide Icardi
In my opinion the best option is to use Newtonsoft.Json.Bson.BsonReader.
Here a complete example:
在我看来,最好的选择是使用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();
}
}
}
I think that this should handle all cases correctly (dates, ids, ...).
我认为这应该正确处理所有情况(日期,ID,...)。
回答by Erkko V?lja
Here is the way i did it, to skip mongodb _id entry.
这是我这样做的方式,跳过 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();
回答by T Brown
My problem had to do with how DotNet Core WebAPI serializes an object to json. If you return a string from a method that is formatted as json, WEBAPI will serialize it to json again. This is only needed if you are working with a generic BsonDocument to save to MongoDb.
我的问题与 DotNet Core WebAPI 如何将对象序列化为 json 有关。如果你从一个格式化为 json 的方法中返回一个字符串,WEBAPI 会再次将它序列化为 json。这仅在您使用通用 BsonDocument 保存到 MongoDb 时才需要。
[HttpGet()]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<string>> GetAsync()
{
return Ok(ret.ToJson());
}
Fix
使固定
[HttpGet()]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<object>> GetAsync()
{
var doc = await _collection.Find(...).FirstOrDefaultAsync();
return Ok(JObject.Parse(doc.ToJson()));
}
回答by Piotr Kula
If you need to use this ASP.NET Core for when you may be returning a model that has BsonDocument to be able to add dynamic data. You can use this JsonConverter implementation based on MarkKGreenway's answer!
如果您需要在返回具有 BsonDocument 的模型以能够添加动态数据时使用此 ASP.NET Core。您可以根据 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);
}
}
Then in your Startup.csjust add the following.
然后在您Startup.cs只需添加以下内容。
services.AddMvc()
.AddJsonOptions(options => options.SerializerSettings.Converters.Add(new BsonDocumentJsonConverter()));
回答by wutzebaer
what about
关于什么
String json = result.toJson(JsonWriterSettings.builder().objectIdConverter(new Converter<ObjectId>() {
@Override
public void convert(ObjectId value, StrictJsonWriter writer) {
writer.writeString(value.toHexString());
}
}).build());
回答by jidh
If the contents of the BSON document is saved as, below
如果将BSON文档的内容另存为,如下
{
"Date" : "2019-04-05T07:07:31.979Z",
"BSONCONTENT" : {
"_t" : "MongoDB.Bson.BsonDocument, MongoDB.Bson",
"_v" : {
"A" : "XXXX",
"B" : 234
}
}
}
}
then it works with generic class.
然后它适用于泛型类。
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);
}

