2013-04-03 41 views
9

Với json sau:Deserialize mảng các cặp giá trị key sử dụng Json.NET

[ {"id":"123", ... "data":[{"key1":"val1"}, {"key2":"val2"}], ...}, ... ] 

là một phần của một cái cây lớn, làm thế nào tôi có thể deserialize các "dữ liệu" bất động sản thành:

List<MyCustomClass> Data { get; set; } 

hoặc

List<KeyValuePair> Data { get; set; } 

hoặc

Dictionary<string, string> Data { get; set; } 

sử dụng Json.NET? Hoặc là phiên bản sẽ làm (tôi thích Danh sách MyCustomClass mặc dù). Tôi đã có một lớp có chứa các thuộc tính khác, như sau:

public class SomeData 
{ 
    [JsonProperty("_id")] 
    public string Id { get; set; } 
    ... 
    public List<MyCustomClass> Data { get; set; } 
} 

trong đó "MyCustomClass" chỉ bao gồm hai thuộc tính (Khóa và giá trị). Tôi nhận thấy có một lớp KeyValuePairConverter có vẻ như nó sẽ làm những gì tôi cần, nhưng tôi đã không thể tìm thấy một ví dụ về cách sử dụng nó. Cảm ơn.

Trả lời

16

Cách đơn giản nhất là mảng deserialize các cặp khóa-giá trị IDictionary<string, string>:

 

public class SomeData 
{ 
    public string Id { get; set; } 

    public IEnumerable<IDictionary<string, string>> Data { get; set; } 
} 

private static void Main(string[] args) 
{ 
    var json = "{ \"id\": \"123\", \"data\": [ { \"key1\": \"val1\" }, { \"key2\" : \"val2\" } ] }"; 

    var obj = JsonConvert.DeserializeObject<SomeData>(json); 
} 
 

Nhưng nếu bạn cần deserialize rằng đến lớp của riêng bạn, nó có thể trông giống như rằng:

 

public class SomeData2 
{ 
    public string Id { get; set; } 

    public List<SomeDataPair> Data { get; set; } 
} 

public class SomeDataPair 
{ 
    public string Key { get; set; } 

    public string Value { get; set; } 
} 

private static void Main(string[] args) 
{ 
    var json = "{ \"id\": \"123\", \"data\": [ { \"key1\": \"val1\" }, { \"key2\" : \"val2\" } ] }"; 

    var rawObj = JObject.Parse(json); 

    var obj2 = new SomeData2 
    { 
     Id = (string)rawObj["id"], 
     Data = new List<SomeDataPair>() 
    }; 

    foreach (var item in rawObj["data"]) 
    { 
     foreach (var prop in item) 
     { 
      var property = prop as JProperty; 

      if (property != null) 
      { 
       obj2.Data.Add(new SomeDataPair() { Key = property.Name, Value = property.Value.ToString() }); 
      } 

     } 
    } 
} 
 

Thấy rằng tôi khề rằng Valuestring và tôi gọi phương thức ToString(), có thể có một lớp phức tạp khác.

+1

Danh sách các từ điển công trình; cảm ơn vì điều đó. Kể từ khi thay đổi tôi đang cố gắng thực hiện là một phần của một thư viện lớn hơn tôi đang cố gắng tránh phải viết khởi tạo đối tượng tùy chỉnh. Tôi đang tìm kiếm bằng văn bản một công cụ chuyển đổi tùy chỉnh cho lớp của tôi (SomeData2 trong ví dụ của bạn). Nếu tôi không thể làm cho nó hoạt động thì tôi sẽ sử dụng phương pháp Danh sách Từ điển của bạn. Cảm ơn. – pbz

+0

Cảm ơn rất nhiều vì câu trả lời này. Tôi đã có cùng một loại json với mảng với giá trị quan trọng. Tôi chỉ sử dụng IEnumerable công cộng > Data {get; bộ; } cho lĩnh vực đó và làm việc như quyến rũ .. toàn bộ json của tôi đã được phân tích tốt! .. – maths

1

tôi đã kết thúc làm điều này:

[JsonConverter(typeof(MyCustomClassConverter))] 
public class MyCustomClass 
{ 
    internal class MyCustomClassConverter : JsonConverter 
    { 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     JObject jObject = JObject.Load(reader); 

     foreach (var prop in jObject) 
     { 
     return new MyCustomClass { Key = prop.Key, Value = prop.Value.ToString() }; 
     } 

     return null; 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return typeof(MyCustomClass).IsAssignableFrom(objectType); 
    } 
    } 

    public string Key { get; set; } 
    public string Value { get; set; } 
} 
Các vấn đề liên quan