2010-03-06 2 views
10

У меня есть уплощение JSON:Может ли Json.NET десериализовать сплющенную строку JSON с точечной записью?

{ 
    "CaseName" : "John Doe v. State", 
    "CaseDate" : "<some date>", 
    "Client.FirstName" : "John", 
    "Client.LastName" : "Doe", 
    "Client.Email" : "[email protected]" 
    etc... 
} 

Я хочу десериализацию его обратно к этому лицу:

public class Case() 
{ 
    public string CaseName { get; set; } 
    public string CaseDate { get; set; } 
    public Client Client { get; set; } 
} 

где Client.FirstName, Client.LastName и Client.Email являются свойством в Client объекте. Используя Json.NET, есть ли способ заставить его разобрать точечную нотацию и десериализировать этот объект правильно? В настоящее время, используя настройки по умолчанию, он сообщает мне, что Client.FirstName не относится к типу Case.

+0

Это не JSON. – ChaosPandion

+0

Я упростил его, чтобы сделать его более читаемым, но я изменил его, так что теперь это правильный JSON. –

+0

, чтобы развернуть комментарий ChaosPandion - стандартный способ представляет, что вложенные данные (клиент) в Json будут больше похожими на {«CaseName»: «John Doe v. State», «CaseDate»: «», «Клиент» { FirstName ":" John "," LastName ":" Doe "}} Если возможно изменить выведенный Json вместо этого, это будет намного быстрее, чем slpan КасперОн. Зависит, если вы контролируете сериализацию? – MemeDeveloper

ответ

5

Да, вы можете. Вы должны получить класс от JsonConverter и переопределить метод CanConvert на indicae, который вы можете преобразовать в Client.

Затем вы переопределите методы ReadJson и WriteJson для чтения и записи полей литерала JSON.

Для JSON буквального, как это, это более чем вероятно, вам нужно будет создать JsonConverter для Case типа, как вам нужно будет кэшировать все свойства Client объекта во время сериализации, пока вы не достаточно информации, чтобы действительно создать пример Client.

Тогда вы могли бы назвать Add метод на JsonConverterCollection экземпляра выставленного Converters property на JsonSerializer, например, вы используете для выполнения вашей сериализации/десериализации.

Обратите внимание, что если вам нужно сделать, это для целого ряда различных классов, которые могут быть представлены таким образом, то вы можете написать одинJsonConverter реализации, и он просканирует для атрибута на имущество. Если свойство имеет атрибут и предоставляет другой объект со свойствами, он будет ожидать чтения/записи точечной нотации.

Следует отметить, что, хотя вы используете точечную нотацию для идентификатора, это очень редко. Если это возможно, на той стороне, которая строит JSON буквальным, он должен делать это таким образом:

{ 
    CaseName: "John Doe v. State", 
    CaseDate: "<some date>", 
    Client: 
    { 
     FirstName: "John", 
     LastName: "Doe", 
     Email: "[email protected]" 
    } 
} 

Но это при условии, что у вас есть контроль над этой целью. Если вы этого не сделаете, тогда вы не сможете многое сделать.

Если у вас есть контроль, то построение ваших JSON-литералов таким образом приведет к отрицанию необходимости создания пользовательской версии JsonConverter.

+1

Да, я бы предпочел преобразовать его правильно со стороны отправителя (ExtJS), но я не уверен, что это возможно. Решение, которое вы предоставили, является работоспособным, но слишком много работы, учитывая количество объектов и сложность моего графа объектов. Я надеялся на простой флаг или более общий JsonConverter, который будет применяться ко всем свойствам точечной нотации. –

+1

@ Daniel T .: К сожалению, JSON нестандартен, поэтому у Json.NET есть проблемы с ним. Тем не менее, я добавил абзац ответа, чтобы указать, как вы можете написать * one * JsonConverter, в сочетании с атрибутом, чтобы сообщить ему, чтобы читать/писать dot-нотацию, когда ожидалось. – casperOne

0

Хотя полбеды (т.е. не помогает с тем, что ваш объект был уплощенной)

Вы можете иметь дело с точкой обозначения в очень быстрой и грязной способом с простым

MyTargetClass retVal 
= JsonConvert.DeserializeObject<MyTargetClass>(jsonAsString.Replace(".", "_")); 

В комбинации с соответствующими именами свойств «_» на MyTargetClass, например

public class MyTargetClass 
{ 
    public string CaseName {get; set;} 
    public DateTime CaseDate {get; set;} 
    public string Client_FirstName {get; set;} 

    //Other Properties 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^