2017-02-22 9 views
-1

Как я могу разобрать объект JSON ниже, используя DataContractJsonSerializer в C#?Как разбирать массив объектов json, содержащий смешанные примитивные типы, используя DataContractJsonSerializer?

мне нужно будет определить класс для хранения ниже данных в формате JSON, который включает в себя массив массивов примитивов смешанных типов (строка и целое число):

Body: 
    { 
     "status": "failure", 
     "staticdata": [ 
     [ 
      "2013-06-01", 
      123 
     ], 
     [ 
      "2013-06-02", 
      234 
     ], 
     [ 
      "2013-06-03", 
      345 
     ],  
     ... 
     ] 
    } 

Я попробовал ответ ниже и попытался прочитала DataContractJsonSerializer,

DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(RootObject)); 

object objResponse = jsonSerializer.ReadObject(response); 

RootObject jsonResponse = objResponse as RootOject; 

foreach (object[] sd in jsonResponse.staticdata) 
{ 
    foreach (object o in sd) 
    { 
     //Value val = v as Value; 
     Value val = (Value)Convert.ChangeType(o, typeof(Value)); 
      log.Info("date: " + val.date); 
      log.Info("crashCount: " + val.longValue); 
    } 
} 

но в converttype от объекта к стоимости происходит сбой, я-то здесь отсутствует.

Значение ниже класса:

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

    [DataMember(Name = "longValue")] 
    public long longValue{ get; set; } 
} 

модифицированный код чтения значений (IgnoreDataMember значений), а затем может в состоянии прочитать, как показано ниже: это правильный подход?

object objResponse = jsonSerializer.ReadObject(response); 

RootObject jsonResponse = objResponse as RootOject; 

foreach (Value in jsonResponse.Values) 
{ 
      log.Info("date: " + val.date); 
      log.Info("longValue: " + val.longValue); 
} 
+0

См http://stackoverflow.com/questions/9034220/parse-an-array-as-a-json-string- using-datacontractjsonserializer-wp7 – Stuart

+0

http://stackoverflow.com/questions/27174549/how-to-use-datacontractjsonserializer-to-parse-a-nested-json-object http://stackoverflow.com/questions/9034220/ parse-a-array-as-a-json-string-using-datacontractjsonserializer-wp7 и т. д. ... 3 секунды онлайн-поиска –

+0

Почему вы не используете Json.Net? Это намного проще – NicoRiff

ответ

2

Если вы просто хотите, чтобы десериализации ваш JSON, вы можете использовать инструмент генерации кода, как http://json2csharp.com/ или Paste JSON As Classes и получить следующую модель данных, которая работает отлично с DataContractJsonSerializer:

public class RootObject 
{ 
    public string status { get; set; } 
    public List<List<object>> staticdata { get; set; } 
} 

object потому что DataContractJsonSerializer автоматически распознает и сериализует известные примитивные типы, такие как string и int.

Но то, что вы можете захотеть, чтобы десериализации вашего "staticdata" массива в список классов, такие, как это:

public class Value 
{ 
    public string Date { get; set; } 
    public int IntValue { get; set; } 
} 

Если да, то вы можете использовать суррогатную собственность в типе RootObject сделать преобразование :

[DataContract] 
public class RootObject 
{ 
    [DataMember] 
    public string status { get; set; } 

    [DataMember] 
    object[][] staticdata 
    { 
     get 
     { 
      if (Values == null) 
       return null; 
      return Values.Select(v => new object[] { v.Date, v.IntValue }).ToArray(); 
     } 
     set 
     { 
      if (value == null) 
       return; 
      Values = value.Select(a => new Value 
       { 
        Date = a.Length < 1 ? null : (string)Convert.ChangeType(a[0], typeof(string), CultureInfo.InvariantCulture), 
        IntValue = a.Length < 2 ? 0 : (int)Convert.ChangeType(a[1], typeof(int), CultureInfo.InvariantCulture) 
       } 
       ).ToList(); 
     } 
    } 

    [IgnoreDataMember] 
    public List<Value> Values { get; set; } 
} 

Update

В обновленной вопрос вы задали, , но в converttype от объекта до Value рушится, я что-то упустил?

Ваша проблема заключается в том, что вы пытаетесь использовать Convert.ChangeType() для преобразования object в Value, но этот метод только для примитивных типов данных, которые могут быть преобразованы из и строк. От docs:

ChangeType - универсальный метод преобразования, который преобразует объект, заданный значением, в значение conversionType. Параметр value может быть объектом любого типа, а тип conversionType также может быть объектом типа, который представляет любой базовый или пользовательский тип. Для успешного преобразования значение должно реализовать интерфейс IConvertible, потому что метод просто переносит вызов на соответствующий метод IConvertible.

Как ваш Value типа не реализует этот интерфейс, преобразование не удается.

Вместо этого вы должны использовать Convert.ChangeType для отдельных записей в вложенных массивах. Учитывая ваш RootObject выглядит следующим образом:

public class RootObject 
{ 
    public string status { get; set; } 
    public object [][] staticdata { get; set; } 
} 

Вы должны сделать:

using System.Linq; 

DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(RootObject)); 
var jsonResponse = (RootObject)jsonSerializer.ReadObject(response); 

var query = jsonResponse.staticdata 
    // For each object [] array in the outer array 
    .Select(a => new Value 
     { 
      // Convert the inner array to a Value, using the first element for the date and the second element for the longValueand the second element for the longValue 
      date = a.Length < 1 ? null : (string)Convert.ChangeType(a[0], typeof(string), CultureInfo.InvariantCulture), 
      longValue = a.Length < 2 ? 0 : (long)Convert.ChangeType(a[1], typeof(long), CultureInfo.InvariantCulture) 
     }); 

foreach (var val in query) 
{ 
    log.Info("date: " + val.date); 
    log.Info("crashCount: " + val.longValue); 
} 
+0

@ user1174114 - ответ обновлен. – dbc

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