Convert MongoDB BsonDocument to valid JSON in C #

I am working with the C # MongoDB driver. I have a BsonDocument with some data that includes some MongoDB-specific types (such as ObjectID and ISODates). I want to convert this to a valid general-purpose JSON string. In other words, I cannot 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 for regular strings so that they can be easily parsed. The problem is that a built-in function like .ToJson() (which another StackOverflow answer offers) does not actually convert the document to valid JSON because it supports these special types. My document also contains many levels of arrays and subdocuments, so a simple loop is not enough. What is the best way to convert a BsonDocument that avoids this problem? I would prefer something inline rather than manual recursion through a document to fix all problems.

+8
source share
7 answers

I came across the same, you can get a valid JSON via:

 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 smooth this out.

+14
source

In most cases, I use Json.NET for this .

 JsonConvert.SerializeObject(obj); 

In most cases, this does the trick. If necessary, you can install several JsonSerializerSettings

+3
source

In my opinion, the best option is to use Newtonsoft.Json.Bson.BsonReader . Here is a complete example:

 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 this should handle all cases correctly (dates, identifiers, ...).

+3
source

Here's how I did it to skip the mongodb _id entry.

 var collection = _database.GetCollection<BsonDocument>("test"); var result = await collection.Find(new BsonDocument()) .Project(Builders<BsonDocument>.Projection.Exclude("_id")) .ToListAsync(); var obj = result.ToJson(); 
+1
source

If you need to use this ASP.NET kernel for the case when you return the model with BsonDocument, in order to be able to add dynamic data. You can use this JsonConverter implementation based on MarkKGreenway answer!

  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.cs just add the following.

  services.AddMvc() .AddJsonOptions(options => options.SerializerSettings.Converters.Add(new BsonDocumentJsonConverter())); 
0
source

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()); 
0
source

If the contents of the BSON document is saved as below

 { "Date" : "2019-04-05T07:07:31.979Z", "BSONCONTENT" : { "_t" : "MongoDB.Bson.BsonDocument, MongoDB.Bson", "_v" : { "A" : "XXXX", "B" : 234 } } 

}

then it works with a 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); } 
0
source

Source: https://habr.com/ru/post/1207683/


All Articles