2015-06-04 2 views
1

У меня есть служба WCF REST, которая имеет ресурс, который содержит несколько типизированных полей, а затем поле, которое может быть массивом объектов. Я хочу, чтобы поле в нашей службе сериализовало это поле, как если бы оно было строкой. Пример:Сериализация и десериализация части объекта JSON как строки с WCF

[DataContract] 
public class User 
{ 
    [DataMember] 
    public long ID; 

    [DataMember] 
    public string Logon; 

    [DataMember] 
    public string Features; 
} 

Когда пользователи нашего API POST новый объект User, я хотел бы, чтобы они были в состоянии сделать что-то использовать, как это, как тело:

{ 
    "ID" : 123434, 
    "Logon" : "MyLogon", 
    "Features" : [ 
      { "type": "bigFeature", "size": 234, "display":true }, 
      { "type": "smFeature", "windowCount": 234, "enableTallness": true} 
    ] 
} 

вместо

{ 
    "ID" : 123434, 
    "Logon" : "MyLogon", 
    "Features" : "[ 
      { \"type\": \"bigFeature\", \"size\": 234, \"display\":true }, 
      { \"type\": \"smFeature\", \"windowCount\": 234, \"enableTallness\": true} 
    ]" 
} 

На стороне обслуживания я собираюсь сохранить массив «Особенности» в текстовом блоге JSON в базе данных, и когда я верну вызов объекта в GET, я бы хотел, чтобы он был в оба конца.

+0

Итак, вы хотите взять строку JSON, а затем сможете ее сериализовать/десериализовать через вызов функции? – Pseudonym

+0

Нет, я хотел использовать DataContract и DataMember для определения данных, но я хотел бы, чтобы одно из полей фактически было массивом JSON, что позволило бы содержать любой объект JSON. Это позволило бы мне конвертировать туда и обратно. – bpeikes

+0

Какой сериализатор вы используете - 'DataContractJsonSerializer' или Json.NET? – dbc

ответ

1

Если вы готовы перейти на Json.NET, вы можете сериализовать Features строку как частное JToken прокси собственности:

[DataContract] 
public class User 
{ 
    [DataMember] 
    public long ID; 

    [DataMember] 
    public string Logon; 

    string _features = null; 

    [IgnoreDataMember] 
    public string Features 
    { 
     get 
     { 
      return _features; 
     } 
     set 
     { 
      if (value == null) 
       _features = null; 
      else 
      { 
       JToken.Parse(value); // Throws an exception on invalid JSON. 
       _features = value; 
      } 
     } 
    } 

    [DataMember(Name="Features")] 
    JToken FeaturesJson 
    { 
     get 
     { 
      if (Features == null) 
       return null; 
      return JToken.Parse(Features); 
     } 
     set 
     { 
      if (value == null) 
       Features = null; 
      else 
       Features = value.ToString(Formatting.Indented); // Or Formatting.None, if you prefer. 
     } 
    } 
} 

Обратите внимание, что для того, чтобы сериализовать Features строку без побега, его должен быть действительным JSON, иначе ваш внешний JSON будет поврежден. Я применяю это в настройщике. Вы можете использовать JArray вместо JToken, чтобы обеспечить соблюдение требования о том, чтобы строка представляла массив JSON, если хотите.

Обратите внимание, что форматирование строки не сохраняется во время сериализации.

+0

Я попытался использовать JToken в качестве DataMember, но получаю исключение Deserialization: «Тип Newtonsoft.Json.Linq.JToken» - это рекурсивный контракт с данными коллекций, который не поддерживается. Рассмотрите возможность изменения определения коллекции Newtonsoft.Json .Linq.JToken ', чтобы удалить ссылки на себя. ", Мне кажется, мне нужно переключиться с использования DataContractJsonSerializer в Newtonsoft, но я не нашел хороший пример того, как это сделать. – bpeikes

+0

@ bpeikes - Да, вам нужно будет переключиться. См. Http://stackoverflow.com/questions/3118504/how-to-set-json-net-as-the-default-serializer-for-wcf-rest-service или http://stackoverflow.com/questions/11003016/c-sharp-wcf-rest-how-do-you-use-json-net-serializer-вместо-default-dat или https://code.msdn.microsoft.com/windowsdesktop/Supporting-different -data-b0351c9a. – dbc

+0

В первой статье требуется изменить все ваши DataContracts, чтобы вернуть Message или Stream, что я не люблю. Второй указывает на эту статью, которую я видел некоторое время назад, но код никогда не был скомпилирован правильно: http: //blogs.msdn.com/b/carlosfigueira/archive/2011/05/03/wcf-extensibility-message-formatters.aspx – bpeikes

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