2015-04-17 5 views
2

Я новичок в Json.NET, и мне нужна помощь десериализовать следующие действия JSONDeserialize JSON массив с различными типами

{ 
    "items": [ 
     [10, "file1", "command 1"], 
     [20, "file2", "command 2"], 
     [30, "file3", "command 3"] 
    ] 
} 

к этому

IList<Item> Items {get; set;} 

class Item 
{ 
    public int Id  {get; set} 
    public string File {get; set} 
    public string Command {get; set} 
} 

Содержание в формате JSON всегда в том же порядке.

+0

Что вы проблемно с JSON.NET? –

+0

Но если я попытаюсь десериализовать список , JSON.NET жалуется, что он не может заполнить массив – magol

+0

ok Позвольте мне попробовать с этим кодом, пожалуйста, подождите. –

ответ

4

Вы можете использовать пользовательские JsonConverter для преобразования каждого ребенка массива в JSON к Item. Вот код, который нужно будет для преобразователя:

class ItemConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return (objectType == typeof(Item)); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     JArray array = JArray.Load(reader); 
     return new Item 
     { 
      Id = (int)array[0], 
      File = (string)array[1], 
      Command = (string)array[2] 
     }; 
    } 

    public override bool CanWrite 
    { 
     get { return false; } 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

С выше конвертер, вы можете десериализации в ваши классы легко, как показано ниже:

class Program 
{ 
    static void Main(string[] args) 
    { 
     string json = @" 
     { 
      ""items"": [ 
       [10, ""file1"", ""command 1""], 
       [20, ""file2"", ""command 2""], 
       [30, ""file3"", ""command 3""] 
      ] 
     }"; 

     Foo foo = JsonConvert.DeserializeObject<Foo>(json, new ItemConverter()); 

     foreach (Item item in foo.Items) 
     { 
      Console.WriteLine("Id: " + item.Id); 
      Console.WriteLine("File: " + item.File); 
      Console.WriteLine("Command: " + item.Command); 
      Console.WriteLine(); 
     } 
    } 
} 

class Foo 
{ 
    public List<Item> Items { get; set; } 
} 

class Item 
{ 
    public int Id { get; set; } 
    public string File { get; set; } 
    public string Command { get; set; } 
} 

Выход:

Id: 10 
File: file1 
Command: command 1 

Id: 20 
File: file2 
Command: command 2 

Id: 30 
File: file3 
Command: command 3 

Fiddle: https://dotnetfiddle.net/RXggvl

0

Для десериализации ваш JSON должен быть, как этот

{ 
    "items": [ 
     {Id: 10, File: "file1", Command: "command 1"}, 
     {Id: 20, File: "file2", Command: "command 2"}, 
     {Id: 30, File: "file3", Command: "command 3"} 
    ] 
} 

Это будет отображать variables Id, File and Command to properties Id, File and Command соответственно при десериализации

Вы можете десериализации его, используя следующий код

public List<Item> DeserializeJSON(string jsonString) 
{ 
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(List<Item>)); 
    MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)); 
    var obj = (List<Item>)ser.ReadObject(stream); 
    return obj; 
} 
+0

Да, если JSON формируется таким образом, это не проблема. Но теперь это не так. Можно ли каким-либо образом заставить JSON.NET преобразовывать данные из массива в свойства? – magol

+0

@magol, так как это строка, и ваш класс не является сложным, можно проанализировать строку и сохранить ее в коллекции списков вручную без использования сериализатора. Но этот тип решения не будет общим, и он будет специфичен только для этой строки json – Kira

0

Вы можете сделать это используя промежуточный тип, чтобы захватить преобразование из Json и карту, которая соответствует вашему классу Item после войны DS. Таким образом, первыми мы имеем промежуточный класс:

public class IntermediateType 
{ 
    public object[][] items { get; set; } 
} 

И теперь мы можем получить результаты, как это:

var json = "{\"items\": [ [10, \"file1\", \"command 1\"], [20, \"file2\", \"command 2\"], [30, \"file3\", \"command 3\"] ]}"; 

var result = JsonConvert 
    .DeserializeObject<IntermediateType>(json) 
    .items 
    .Select(o => new Item 
    { 
     Id = int.Parse(o[0].ToString()), 
     File = (string)o[1], 
     Command = (string)o[2] 
    }); 
Смежные вопросы