2014-08-27 161 views
3

我試圖用Json.net反序列化一個對象。我能夠成功地做到這一點,但它更多的是黑客攻擊,所以我正在尋找一種更好/適當的方式來做到這一點。使用Json.Net反序列化Json對象

{ 
"page":"admin", 
"context":"id", 
"records":{ 
      "rCount":6, 
      "1":[ 
       { 
        "name":"Romeo", 
        "dob":"01\/01\/1970" 
       }, 
       { 
        "name":"Harry", 
        "dob":"10\/10\/2012" 
       }, 
       { 
        "name":"Lee", 
        "dob":"17\/10\/2012" 
       }], 
      "2":[ 
       { 
        "name":"Mark", 
        "dob":"01\/01\/1970" 
       }, 
       { 
        "name":"Jack", 
        "dob":"10\/10\/2012" 
       }, 
       { 
        "name":"Json", 
        "dob":"17\/10\/2012" 
       }], 

}} 

這是JSON字符串的問題是與記錄對象。如果它沒有rCount變量,那麼它可以反序列化爲字典,但由於rCount變量,它不能正確反序列化爲字典。應該是對這個對象進行反序列化的正確方式。

這裏是我的解決方案:

class Program 
{ 
static void Main(string[] args) 
{ 
    var recordFile = JsonConvert.DeserializeObject<RecordFile>(Properties.Resources.data); 
} 

public class RecordFile 
{ 
    public string Page { get; set; } 
    public string Context { get; set; } 
    public Records Records { get; set; } 
} 

public class Records 
{ 
    public int RCount { get; set; } 
    [JsonExtensionData] 
    private Dictionary<string, object> _reocordList; 

    public List<Record[]> RecordList 
    { 
     get 
     { 
      if (_reocordList != null && _reocordList.Count > 0) 
      { 
       return _reocordList.Values.Select(record => JsonConvert.DeserializeObject<Record[]>(record.ToString())).ToList(); 
      } 
      return new List<Record[]>(); 
     } 
    } 

} 

public class Record 
{ 
    public string Name { get; set; } 
    public string Dob { get; set; } 
} 
} 
+0

@AndrewWhitaker沒有其他的方式來deseialize它。由於** JsonExtensionDataAttribute **,我正在使用** Dictionary **。 **列表 **或**字典<字符串,記錄[]> **將做這項工作 – 2014-08-27 20:34:14

+0

是的,我意識到,我發佈我的評論後,哈哈。 – 2014-08-27 20:35:04

回答

1

可以使用jObject手動解析JSON:

public class RecordFile 
{ 
    public string Page { get; set; } 
    public string Context { get; set; } 
    public Records Records { get; set; } 
} 

public class Records 
{ 
    public int RCount { get; set; } 
    public IDictionary<string, List<Record>> RecordsDictionary { get; set; } 
} 


public class Record 
{ 
    public string Name { get; set; } 
    public string Dob { get; set; } 
} 

然後:

var jObject = JObject.Parse(\* your json *\); 
var recordFile = new RecordFile 
{ 
    Page = jObject.Value<string>("page"), 
    Context = jObject.Value<string>("context"), 
    Records = new Records 
    { 
     RCount = jObject["records"].Value<int>("rCount"), 
     RecordsDictionary = 
      jObject["records"].Children<JProperty>() 
           .Where(prop => prop.Name != "rCount") 
           .ToDictionary(prop => prop.Name), 
              prop => 
              prop.Value.ToObject<List<Record>>()) 
    } 

}; 

當然可以容易地處理的情況下,當財產不存在時。

1

我假設你想擺脫Records類的完全,像這樣的東西碰得:

public class RecordFile 
{ 
    public string Page { get; set; } 
    public string Context { get; set; } 
    public Dictionary<string, Record[]> Records { get; set; } 
} 

public class Record 
{ 
    public string Name { get; set; } 
    public string Dob { get; set; } 
} 

,因爲你不關於在所有關於JSON的records.rCount屬性,您可以指定一個新的錯誤處理程序來簡單地忽略該屬性:

現在,當遇到有問題的屬性時,解串器只會跳過它。另一種選擇是編寫一個自定義轉換器,但這只是爲了忽略一個屬性而過度使用。

實施例:https://dotnetfiddle.net/3svPqk

1

到目前爲止發佈的其他答案都應該可以工作。爲了完整起見,我將展示如何使用自定義的JsonConverter來解決這個問題,並簡化您的模型。

這裏是轉換器的代碼:

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     JObject jo = JObject.Load(reader); 
     RecordFile rf = new RecordFile(); 
     rf.Page = (string)jo["page"]; 
     rf.Context = (string)jo["context"]; 
     JObject records = (JObject)jo["records"]; 
     rf.RecordCount = (int)records["rCount"]; 
     rf.Records = records.Properties() 
          .Where(p => p.Name != "rCount") 
          .Select(p => p.Value.ToObject<Record[]>()) 
          .ToList(); 
     return rf; 
    } 

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

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

要與轉換工作,改變你的模型類,如下圖所示。 (請注意,RecordFile類具有JsonConverter屬性以將自定義RecordFileConverter鏈接到它。還要注意Records類已刪除,而RCountRecordList屬性已上移至RecordFile類並重命名。)

[JsonConverter(typeof(RecordFileConverter))] 
public class RecordFile 
{ 
    public string Page { get; set; } 
    public string Context { get; set; } 
    public int RecordCount { get; set; } 
    public List<Record[]> Records { get; set; } 
} 

public class Record 
{ 
    public string Name { get; set; } 
    public string Dob { get; set; } 
} 

然後,反序列化爲正常:

var recordFile = JsonConvert.DeserializeObject<RecordFile>(json); 

演示https://dotnetfiddle.net/jz3zUT

+0

非常感謝..非常有幫助 – 2014-08-29 06:19:51

+0

沒問題;很高興我能幫上忙。 – 2014-08-29 07:28:43