Convert Newtosoft JObject directly to BsonDocument

家住魔仙堡 提交于 2021-01-27 19:45:12

问题


Try to convert JObject to BsonDocument using this example https://www.newtonsoft.com/json/help/html/WriteJTokenToBson.htm (BsonWriter obsolete, so I use BsonDataWriter)

var jObject = JObject.Parse("{\"name\":\"value\"}");

using var writer = new BsonDataWriter(new MemoryStream());
jObject.WriteTo(writer);

var bsonData = writer.ToBsonDocument();

Console.WriteLine(bsonData.ToJson());

output:

{ "CloseOutput" : true, "AutoCompleteOnClose" : true, "Formatting" : 0, "DateFormatHandling" : 0, "DateTimeZoneHandling" : 3, "StringEscapeHandling" : 0, "FloatFormatHandling" : 0, "DateFormatString" : null
, "Culture" : { "Name" : "", "UseUserOverride" : false }, "DateTimeKindHandling" : 1 }

Expected output is:

{"name": "value"}

How can I fix it?

UPD: I have a JObject, and I want to convert it directly to BSONDocument, avoid serialization to string and string parsing


回答1:


You can write a JObject to a BSON stream using Newtonsoft's BsonDataWriter like so:

var json = "{\"name\":\"value\"}";
var jObject = JObject.Parse(json);

using var stream = new MemoryStream(); // Or open a FileStream if you prefer
using (var writer = new BsonDataWriter(stream) { CloseOutput = false })
{
    jObject.WriteTo(writer);
}
// Reset the stream position to 0 if you are going to immediately re-read it.
stream.Position = 0;

Then, you can parse the written stream with the MongoDB .NET Driver like so:

// Parse the BSON using the MongoDB driver
BsonDocument bsonData;
using (var reader = new BsonBinaryReader(stream))
{
    var context = BsonDeserializationContext.CreateRoot(reader);
    bsonData = BsonDocumentSerializer.Instance.Deserialize(context);            
}

And check the validity of the created document like so:

// Verify that the BsonDocument is semantically identical to the original JSON.
// Write it to JSON using the MongoDB driver
var newJson = bsonData.ToJson();

Console.WriteLine(newJson); // Prints { "name" : "value" }

// And assert that the old and new JSON are semantically identical
Assert.IsTrue(JToken.DeepEquals(JToken.Parse(json), JToken.Parse(newJson))); // Passes

Notes:

  • When you do var bsonData = writer.ToBsonDocument(); you are actually serializing Newtonsoft's BsonDataWriter using the MongoDB extension method BsonExtensionMethods.ToBsonDocument(), which explains the strange contents of the bsonData document in your test code.

    Instead, the serialized BSON can be obtained from the stream to which it was just written.

  • If you are going to immediately re-read the stream, you can keep it open by setting JsonWriter.CloseOutput = false. Set the stream position to 0 after writing.

  • While your approach avoids the overhead of serializing and parsing a JSON string, you are still serializing and deserializing a BSON binary stream.

Demo fiddle here.




回答2:


If you have the json string already, you can simply create a bson document out of it

var document= BsonDocument.Parse("{\"name\":\"value\"}");

If you strictly have a JObject, you can Serialize the JObject and then parse the result to a BSONDocument

var document = BsonDocument.Parse(Newtonsoft.Json.JsonConvert.SerializeObject(jObject));


来源:https://stackoverflow.com/questions/62080252/convert-newtosoft-jobject-directly-to-bsondocument

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!