Как сериализовать GUID как собственный UUID в BSON с помощью JSON.NET

JSON.NET, похоже, не хочет сериализовать GUID как собственные UUID BSON, а вместо этого выводит GUID в виде строк.

Я протестировал создание BSON как из JObject (проверив перед сериализацией, что JValue.Type == JTokenType.Guid), так и из анонимного типа (new { myUuid = new Guid() }), но безуспешно в любом случае.

Как заставить JSON.NET сериализовать идентификаторы GUID как собственные идентификаторы UUID BSON (16-байтовое двоичное значение; подтип = 0x04)?

Пример кода:

var source = new
{
    myInteger = 123L,
    myFloat = 10.0f,
    myString = "hello",
    myUuid = Guid.NewGuid(),
    myBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7 },
    myDatetime = DateTime.UtcNow,
};

MemoryStream buffer = new MemoryStream();
BsonWriter writer = new BsonWriter(buffer);
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(writer, source);
byte[] myBson = buffer.ToArray();

person DuckMaestro    schedule 18.12.2012    source источник


Ответы (1)


Проблема связана с этой реализацией WriteValue на BsonWriter (в версии 4.5.0.0):

public override void WriteValue(Guid value)
{
  base.WriteValue(value);
  this.AddToken((BsonToken) new BsonString((object) value.ToString(), true));
}

Обратите внимание на вторую строку, она записывает Guid в виде строки, вот почему вы видите результаты, которые вы есть.

Используя следующий пример:

[TestMethod]
public void TestMethod1()
{
    var source = new
    {
        myUuid = Guid.NewGuid(),
    };

    using (var buffer = new MemoryStream())
    using (var writer = new BsonWriter(buffer))
    {
        var serializer = new JsonSerializer();
        serializer.Serialize(writer, source);
        byte[] myBson = buffer.ToArray();
    }
}

Я ожидаю, что байты, начинающиеся с индекса 12, будут (согласно spec):

  • \0x05 для указания типа двоичного файла
  • Четырехбайтовый int (со значением 16, длина двоичных данных)
  • \0x04 для указания подтипа UUID
  • 16 байтов для представления содержимого Guid/UUID.

Очевидно, это ошибка, и я зарегистрировал ее в системе отслеживания ошибок для Json.NET.

person casperOne    schedule 18.12.2012