Преобразование Newtosoft JObject напрямую в BsonDocument - PullRequest
2 голосов
/ 29 мая 2020

Попробуйте преобразовать JObject в BsonDocument, используя этот пример https://www.newtonsoft.com/json/help/html/WriteJTokenToBson.htm (BsonWriter устарело, поэтому я использую 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());

вывод:

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

Ожидаемый результат:

{"name": "value"}

Как это исправить?

UPD : у меня есть JObject, и я хочу преобразовать его непосредственно в BSONDocument, избегать сериализации в строку и синтаксический анализ строки

Ответы [ 2 ]

2 голосов
/ 30 мая 2020

Вы можете записать JObject в поток BSON, используя BsonDataWriter Newtonsoft, например:

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;

Затем вы можете проанализировать записанный поток с помощью MongoDB. NET Драйвер так:

// 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);            
}

И проверяем действительность созданного документа так:

// 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

Примечания:

  • Когда вы делаете var bsonData = writer.ToBsonDocument();, вы на самом деле сериализуете BsonDataWriter Newtonsoft с использованием метода расширения MongoDB BsonExtensionMethods.ToBsonDocument(), что объясняет странное содержание документа bsonData в вашем тестовом коде.

    Вместо этого сериализованный BSON можно получить из потока, в который он был только что записан.

  • Если вы собираетесь немедленно перечитать поток, вы можете оставьте его открытым, установив JsonWriter.CloseOutput = false. После записи установите позицию потока на 0.

  • Хотя ваш подход позволяет избежать накладных расходов на сериализацию и синтаксический анализ строки JSON, вы по-прежнему сериализуете и десериализуете двоичный поток BSON.

Демо скрипка здесь .

0 голосов
/ 29 мая 2020

Если у вас уже есть строка json, вы можете просто создать из нее bson-документ

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

Если у вас строго есть JObject, вы можете сериализовать JObject, а затем проанализировать результат для Документ BSON

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