2012-05-22 3 views
1

Я пытаюсь использовать JSON.NET для десериализации ответа от стороннего веб-сервиса. Это полный код моего (надуманный) пример, показывающий, что я пытаюсь сделать:Deserializing массив значений enum с JSON.NET

namespace JsonNetTests 
{ 
public enum Parameter 
{ 
    Alpha = 1, 
    Bravo = 2, 
    Charlie = 3, 
    Delta = 4 
} 

public class ResponseElement 
{ 
    public int Id { get; set; } 

    public string Name { get; set; } 

    [JsonProperty(ItemConverterType = typeof(StringEnumConverter))] 
    public Parameter[] Parameters { get; set; } 
} 

public class ResponseBody 
{ 
    public string Locale { get; set; } 
    public string[] Errors { get; set; } 
    public ResponseElement[] ResponseElements { get; set; } 
} 

[TestFixture] 
public class JsonNetTest 
{ 
    [Test] 
    public void TestEnumArray() 
    { 
     string jsonResponse = @" 
{""ResponseBody"": { 
""Locale"": ""en-US"", 
""Errors"": [], 
""ResponseElements"": [{ 
    ""Id"": 1, 
    ""Name"": ""ABC"", 
    ""Parameters"" : { 
     ""Parameter"" : ""Alpha"" 
    }, 
    }, { 
    ""Id"": 2, 
    ""Name"": ""BCD"", 
    ""Parameters"" : { 
     ""Parameter"" : ""Bravo"" 
    }, 
    } 
] 
}} 
"; 

     JObject rootObject = JObject.Parse(jsonResponse); 
     JToken rootToken = rootObject.SelectToken("ResponseBody"); 

     JsonSerializerSettings settings = new JsonSerializerSettings(); 
     settings.MissingMemberHandling = MissingMemberHandling.Error; 

     ResponseBody body = JsonConvert.DeserializeObject<ResponseBody>(rootToken.ToString(), settings); 

     foreach (var element in body.ResponseElements) 
     { 
      Console.WriteLine(string.Format("{0}: {1}", element.Id, element.Name)); 
      foreach (var parameter in element.Parameters) 
      { 
       Console.WriteLine(string.Format("\t{0}", parameter)); 
      } 
     } 
    } 
} 
} 

я получаю следующее исключение:

Newtonsoft.Json.JsonSerializationException: Невозможно десериализации объект JSON (то есть { «name»: «value»}) в тип «JsonNetTests.Parameter []». десериализованный тип должен быть обычным типом .NET (т. Е. Не примитивным типом типа integer, а не типом коллекции, подобным массиву или списку) или типом словаря (например, словарем). Чтобы заставить дескриптор объектов JSON добавить JsonObjectAttribute к типу. Путь 'ResponseElements [0] .Parameters.Parameter', строка 9, позиция 21.

Я пытался использовать атрибут ItemConverterType, чтобы указать, как массив должен быть deserialised:

[JsonProperty(ItemConverterType = typeof(StringEnumConverter))] 

Но это не помогает или. Может ли кто-нибудь посоветовать?

ответ

0

Вы пытаетесь ввести объект в массив. ResponseElement.Parameters - это массив перечислений, где вы json-код использует объект для описания каждого параметра.

Ваш JSON выглядит следующим образом:

// some json 
"Parameters" : { 
    "Parameter" : "Alpha" 
}, 
// more json 

Но, чтобы перевести его в массив перечислений он должен выглядеть следующим образом:

// some json 
"Parameters" : [ "Alpha", "Bravo" ], 
// more json 

Если вы не можете изменить JSON, вы можете изменить модель как так:

public enum ParameterEnum 
{ 
    Alpha = 1, 
    Bravo = 2 
} 

public ParameterContainer 
{ 
    [JsonProperty(ItemConverterType = typeof(StringEnumConverter))] 
    public ParameterEnum Parameter {get;set;} 
} 

public class ResponseElement 
{ 
    public int Id { get; set; } 

    public string Name { get; set; } 

    public ParameterContainer[] Parameters { get; set; } 
} 

Эффективно, вы сериализации JSON в массив ParameterContain которые будут раскрывать их значения.

+0

Благодарим за отзыв! Тип, к которому я пытаюсь десериализоваться, - это не мое решение. Он автоматически генерируется на основе WSDL веб-службы третьей стороны. Они предоставляют как SOAP nad JSON версии их API, так и я хотел бы повторно использовать классы из SOAP Reference.cs. –

+0

Я мог бы написать свои собственные классы для десериализации, но я стараюсь избегать этого, потому что классы третьей стороны HUGE (совсем не такие, как мой упрощенный пример), у них есть 30+ свойств, большинство из которых сложны. Есть ли способ достичь десериализации без изменения JSON (невозможно) или прокси-класса, просто используя атрибуты (или, возможно, пользовательский конвертер)? –

+0

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

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