Десериализовать словарь JSON

У меня есть универсальное приложение, в котором я общаюсь с REST API. Любой ответ от REST я десериализую с помощью DataContractJsonSerializer.

У меня проблема с ответом, который содержит словарь. Этот словарь мне не нужно десериализовать - мой класс не содержит этого словаря. В Win RT работает, а в Win Phone не работает. Я получаю эту ошибку:

The dictionary cannot be deserialized because the member 'key of dictionary' was found more than once in the input.

Я не понимаю, почему это работает в Win RT, а не в Win Phone.

//редактировать - добавить образец JSON

{
  "ResultType": 0,
  "Message": "",
  "Exception": null,
  "Result": {
    "property": 1,
    "property2": 2,
    "property3": "2015-01-31T13:56:43.5337609+01:00",
    "GeneratedQuestions": {
      "className": [
        {
          "innerProperty": 1,
          "innerProperty2": 2,
          "innerProperty3": "sample",
          "innerProperty4": [
            {
              "prop1": 1,
              "prop2": 2,
              "prop3": 3,
              "prop4": "sample text",
            }
          ]
        },
        {
          "innerProperty": 1,
          "innerProperty2": 2,
          "innerProperty3": "sample2",
          "innerProperty4": []
        },
        {
          "innerProperty": 1,
          "innerProperty2": 2,
          "innerProperty3": "sample3",
          "innerProperty4": []
        }
      ]
    }
  }
}

код для десериализации json

 protected T DeserializeJson<T>(string json)
            where T : class
        {
            T type;
            DataContractJsonSerializer jsonSerialized = new DataContractJsonSerializer(typeof(T), new DataContractJsonSerializerSettings { DateTimeFormat = new System.Runtime.Serialization.DateTimeFormat("dd.mm.yyyy HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture) });

            using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
            {
                try
                {
                    ms.Position = 0;
                    type = jsonSerialized.ReadObject(ms) as T;
                }
                catch
                {
                    type = default(T);
                }
            }

            return type;
        }

Упрощенная версия модели:

[DataContract]
public class SampleClass
{
     [DataMember(Name = "ResultType")
     public string ResultType { get; set; }

     [DataMember(Name = "Message")
     public string Message{ get; set; }

     [DataMember(Name = "Exception")
     public Exception Exception{ get; set; }

     [DataMember(Name = "Result")
     public ResultModel Result{ get; set; }
}

public class ResultModel
{
     [DataMember(Name = "property")
     public int Property { get; set; }

     [DataMember(Name = "property2")
     public int Property2 { get; set; }

     [DataMember(Name = "property3")
     public string Property3 { get; set; }
}

person Flow    schedule 31.01.2015    source источник
comment
Пожалуйста, покажите нам json.   -  person khlr    schedule 31.01.2015
comment
Я добавил упрощенную версию JSON. У меня проблема с GeneratedQuestions — это словарь, и он мне не нужен.   -  person Flow    schedule 31.01.2015
comment
Не могли бы вы дополнительно опубликовать свою модель, которую вы десериализуете, в (T)?   -  person khlr    schedule 31.01.2015
comment
Я добавил упрощенную версию JSON. Эти модели мне нужно заполнить, и мне нужно игнорировать сгенерированные вопросы.   -  person Flow    schedule 31.01.2015
comment
1) Воспроизводится ли эта проблема после добавления [DataContract] к ResultModel и удаления GeneratedQuestions из ResultModel? 2) GeneratedQuestions не словарь, это класс, содержащий одно свойство: public List<ClassName> className { get; set; }. Разместите свой JSON на json2csharp.com, чтобы понять, что я имею в виду.   -  person dbc    schedule 31.01.2015
comment
Привет, да, эта проблема возникает, когда я добавляю [DataContract] в ResultModel и удаляю GeneratedQuestions. Это действительно не словарь, но в SOAP тот же метод возвращает словарь, и я автоматически реализую модель со словарем. Мой плохой, Большое спасибо за вашу заметку и полезную страницу, которую вы прислали.   -  person Flow    schedule 02.02.2015


Ответы (1)


Я думаю, что ошибка заключается в отсутствующем атрибуте [DataContract] в ResultModel, который сообщает сериализатору сериализовать все общедоступные члены:

Примените атрибут IgnoreDataMemberAttribute, чтобы отказаться от поведения DataContractSerializer по умолчанию. По умолчанию DataContractSerializer сериализует все общедоступные типы. Все общедоступные свойства чтения/записи и поля типа сериализуются. Вы можете изменить поведение по умолчанию, применив атрибуты DataContractAttribute и DataMemberAttribute к типам и членам.

Так что либо поместите этот атрибут [DataContract] в ResultModel, либо отметьте GeneratedQuestions как [IgnoreDataMember].

Ну, последнее не вариант для вас, поскольку у вас нет этого свойства в вашей модели. Просто упомянем второй вариант.

person khlr    schedule 31.01.2015
comment
Я добавил [IgnoreDataMember], но он все еще не работает. Спасибо за ваш дополнительный совет. - person Flow; 31.01.2015
comment
А как же [DataContract]? - person khlr; 31.01.2015
comment
[DataContract] Я тоже добавил, но забыл написать на свой вопрос (теперь он там) - person Flow; 31.01.2015