Неправильная сериализация в C# с использованием JSON.NET

Я пытаюсь взять объект построен так

public class Item
{
   public Guid SourceTypeID {get;set;}
   public Guid BrokerID {get;set;}
   public double Latitude {get;set;}
   public double Longitude {get;set;}
   public DateTime TimeStamp {get;set;}
   public object Payload {get;set;}
}

и сериализуйте его с JSON.NET использование вызова типа:

Item expected = new Item()
{
   SourceTypeID = Guid.NewGuid(),
   BrokerID = Guid.NewGuid(),
   Latitude = 33.657145,
   Longitude = -117.766684,
   TimeStamp = DateTime.Now,
   Payload = new byte[]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
};
string jsonString = JsonConvert.SerializeObject(expected);

элемент полезной нагрузки объекта Item потенциально будет содержать любой примитив списка примитивов C# (плюс несколько других, таких как Guid), или массив этих типов (как в Примере, массив байтов), или "плоский" объект, состоящий из любого из ранее перечисленных "примитивов" (динамически созданных).

когда я выполняю вызов SerializeObject (), строка, которая создается содержит:

{"Payload":"AAECAwQFBgcICQ==","SourceTypeID":"d8220a4b-75b1-4b7a-8112-b7bdae956a45",
 "BrokerID":"951663c4-924e-4c86-a57a-7ed737501dbd",
 "TimeStamp":"/Date(1328202421559-0600)/",
 "Latitude":33.657145,"Longitude":-117.766684}

однако, когда я делаю вызов десериализации, элемент, который производится, частично неверен

Item actual = JsonConvert.DeserializeObject<Item>(jsonString);

actual.SourceTypeID : {00000000-0000-0000-0000-000000000000}
actual.BrokerID : {951663c4-924e-4c86-a57a-7ed737501dbd}
actual.Latitude : 33.657145;
actual.Longitude : -117.766684;
actual.TimeStamp : {2/2/2012 11:07:01 AM}
actual.Payload : null

элемент SourceTypeID (Guid) и элемент полезной нагрузки (объект, содержащий байт []) являются неправильными. Сериализованная строка, похоже, содержит правильное удостоверение для guid, но не для массива байтов.

Я вижу, что альтернативный signatureof SerializeObject is

SerializeObject(object value, params JsonConverter[] converters);

это правильный способ сообщить движку de/serialization о типах, которые он, по-видимому, обрабатывает неправильно? Поскольку я работаю с ограниченным набором "примитивов" в основе моего объекта, если бы я мог создать набор преобразователей для каждого из этих типов, это решило бы мою проблему?

Я хочу избежать изобретения колеса, если это возможно, поскольку кажется, что это будет проблема, которая уже была решена изящно, и я хотел бы использовать что-то как это, если доступно.

2 ответов


Это похоже на фактическую ошибку в JSON.NET - ...

это не идея, но обходным путем может быть двухэтапная сериализация. Во-первых, объект, который фактически сериализуется в / из JSON, будет состоять только из полей / свойств с string тип. Второй объект (тот, который будет использовать ваш серверный код) будет объектом, который преобразуется в сильные типы вручную.

не идеал, но возможно. Кроме того, вы могли бы рассмотреть, используя the DataContractJsonSerializer, что делает довольно хорошую работу по обработке байтовых массивов и guids IME. Даты все еще довольно отстойные, но это в основном вина Javascript.


полезная нагрузка будет десериализована как строка, если вы не разместите атрибут [JsonProperty] с включенным TypeNameHandling, иначе десериализатор не будет знать, как десериализовать ее.

Я не смог дублировать проблему, которую вы получили с некоторыми свойствами, равными null, используя последний исходный код в http://json.codeplex.com/SourceControl/list/changesets