问题
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'sBsonDataWriter
using the MongoDB extension method BsonExtensionMethods.ToBsonDocument(), which explains the strange contents of thebsonData
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