I am working with the MongoDB C# driver. I have a BsonDocument
with some data which includes some MongoDB-specific types (like ObjectIDs and ISODates). I want t
Through experimentation I discovered that there is an option that makes this method output proper JSON:
BsonDocument myBsonDocument = ... //code that loads a BSON document
myBsonDocument.ToJson(new JsonWriterSettings { OutputMode = JsonOutputMode.RelaxedExtendedJson})
Result:
{ "_id" : { "$oid" : "5fb7a33e73152101d6610e9d" }, "moreProperties" : "moreValues" }
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());
I've ran into the same thing, you can get 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 flatten that.
Here is the way i did it, to skip 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();
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!
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()));
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.
[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()));
}