使用C#解析复杂的JSON结果

我试图解析从Zoho Crm API返回的以下复杂JSON结果:

{ "response": { "result": { "Contacts": { "row": [ { "no":"1", "FL": [ { "content":"555555000000123456", "val":"CONTACTID" }, { "content":"555555000000012345", "val":"SMOWNERID" }, { "content":"John Doe", "val":"Contact Owner" }, { "content":"Pete", "val":"First Name" }, { "content":"Smith", "val":"Last Name" }, { "content":"pete@mail.com", "val":"Email" }, { "content":"5555551000000012346", "val":"SMCREATORID" }, { "content":"Jane Doe", "val":"Created By" }, { "content":"555555000000012347", "val":"MODIFIEDBY" }, { "content":"Doris Doe", "val":"Modified By" }, { "content":"2013-06-14 17:24:10", "val":"Created Time" }, { "content":"2013-06-14 17:24:10", "val":"Modified Time" }, { "content":"2013-06-14 17:28:05", "val":"Last Activity Time" } ] }, { ... } ] } }, "uri":"/crm/private/json/Contacts/getRecords" } 

}

以下是我的Object的外观:

 public class Contact { [JsonProperty(PropertyName = "CONTACTID")] public string ContactID { get; set; } [JsonProperty(PropertyName = "SMOWNERID")] public string OwnerID { get; set; } [JsonProperty(PropertyName = "Contact Owner")] public string ContactOwner { get; set; } [JsonProperty(PropertyName = "First Name")] public string FirstName { get; set; } [JsonProperty(PropertyName = "Last Name")] public string LasName { get; set; } [JsonProperty(PropertyName = "Email")] public string Email { get; set; } [JsonProperty(PropertyName = "SMCREATORID")] public string CreatorID { get; set; } [JsonProperty(PropertyName = "Created By")] public string CreatedBy { get; set; } [JsonProperty(PropertyName = "MODIFIEDBY")] public string ModifiedByID { get; set; } [JsonProperty(PropertyName = "Modified By")] public string ModifiedBy { get; set; } [JsonProperty(PropertyName = "Created Time")] public DateTime CreatedTime { get; set; } [JsonProperty(PropertyName = "Modified Time")] public DateTime ModifiedTime { get; set; } [JsonProperty(PropertyName = "Last Activity Time")] public DateTime LastActivityTime { get; set; } } 

“行”模式重复(没有1,2,3 ……)所以我基本上想要获得的是这种类型的通用对象列表。 我正在尝试使用JSON.NET,但如果它让这更容易,我愿意接受其他建议。

这显然不适用于这种情况:

 var response = JsonConvert.DeserializeObject(jsonString); 

这也不是:

 var deserializedObjects = JsonConvert.DeserializeObject<List>(jsonString); 

这是我使用JavaScriptSerializer解决这个问题的一种解决方法,但它是迄今为止我最糟糕的代码块之一!

  List loContactList = new List(); Contact loContact = null; Dictionary dictionary = new JavaScriptSerializer().Deserialize<Dictionary>(jsonString); var response = (Dictionary)dictionary["response"]; var result = (Dictionary)response["result"]; var contacts = (Dictionary)result["Contacts"]; var row = (ArrayList)contacts["row"]; foreach (var item in row) { var loArrayItem = (Dictionary)item; var fl = (ArrayList)loArrayItem["FL"]; loContact = new Contact(); foreach (var contactitem in fl) { var contactdict = (Dictionary)contactitem; string val = (string)contactdict["val"]; string content = (string)contactdict["content"]; if (val == "CONTACTID") { loContact.ContactID = content; } else if (val == "SMOWNERID") { loContact.OwnerID = content; } else if (val == "Contact Owner") { loContact.ContactOwner = content; } else if (val == "First Name") { loContact.FirstName = content; } else if (val == "Last Name") { loContact.LastName = content; } else if (val == "Email") { loContact.Email = content; } else if (val == "SMCREATORID") { loContact.CreatorID = content; } else if (val == "Created By") { loContact.CreatedBy = content; } else if (val == "MODIFIEDBY") { loContact.ModifiedByID = content; } else if (val == "Modified By") { loContact.ModifiedBy = content; } else if (val == "Created Time") { loContact.CreatedTime = Convert.ToDateTime(content); } else if (val == "Modified Time") { loContact.ModifiedTime = Convert.ToDateTime(content); } else if (val == "Last Activity Time") { loContact.LastActivityTime = Convert.ToDateTime(content); } } loContactList.Add(loContact); } 

我已经浏览了StackOverflow上的其他类似post,但它们似乎都没有为这个问题提供解决方案。 有人有解决方案吗? 我的目标是以更优雅的方式解析这个JSON响应,它不涉及一百万个字典对象和ArrayList! 任何帮助,将不胜感激。

谢谢,皮特

更新7/2/13:

根据Manvik的建议,我整理了以下额外的解决方案:

  public class ResponseActual { [JsonProperty("response")] public Response2 Response { get; set; } } public class Response2 { [JsonProperty("result")] public Result Result { get; set; } [JsonProperty("uri")] public string Uri { get; set; } } public class Result { [JsonProperty("Contacts")] public Contacts Contacts { get; set; } } public class Contacts { [JsonProperty("row")] public IList Row { get; set; } } public class Row { [JsonProperty("no")] public string No { get; set; } [JsonProperty("FL")] public IList FL { get; set; } } public class FL { [JsonProperty("content")] public string Content { get; set; } [JsonProperty("val")] public string Val { get; set; } } List loContactList = new List(); Contact loContact = null; ResponseActual respone = JsonConvert.DeserializeObject(jsonString); foreach (var row in respone.Response.Result.Contacts.Row) { loContact = new Contact(); var rowItem = row.FL.ToList(); try { loContact.ContactID = rowItem.Where((s, t) => s.Val == "CONTACTID").Select(x => x.Content).Single(); } catch { } try { loContact.OwnerID = rowItem.Where((s, t) => s.Val == "SMOWNERID").Select(x => x.Content).Single(); } catch { } try { loContact.ContactOwner = rowItem.Where((s, t) => s.Val == "Contact Owner").Select(x => x.Content).Single(); } catch { } try { loContact.FirstName = rowItem.Where((s, t) => s.Val == "First Name").Select(x => x.Content).Single(); } catch { } try { loContact.LastName = rowItem.Where((s, t) => s.Val == "Last Name").Select(x => x.Content).Single(); } catch { } try { loContact.Email = rowItem.Where((s, t) => s.Val == "Email").Select(x => x.Content).Single(); } catch { } try { loContact.CreatorID = rowItem.Where((s, t) => s.Val == "SMCREATORID").Select(x => x.Content).Single(); } catch { } try { loContact.CreatedBy = rowItem.Where((s, t) => s.Val == "Created By").Select(x => x.Content).Single(); } catch { } try { loContact.ModifiedByID = rowItem.Where((s, t) => s.Val == "MODIFIEDBY").Select(x => x.Content).Single(); } catch { } try { loContact.ModifiedBy = rowItem.Where((s, t) => s.Val == "Modified By").Select(x => x.Content).Single(); } catch { } try { loContact.CreatedTime = Convert.ToDateTime(rowItem.Where((s, t) => s.Val == "Created Time").Select(x => x.Content).Single()); } catch { } try { loContact.ModifiedTime = Convert.ToDateTime(rowItem.Where((s, t) => s.Val == "Modified Time").Select(x => x.Content).Single()); } catch { } try { loContact.LastActivityTime = Convert.ToDateTime(rowItem.Where((s, t) => s.Val == "Last Activity Time").Select(x => x.Content).Single()); } catch { } loContactList.Add(loContact); } 

使用以下类使用JSON.Net进行反序列化

 public class ResponseActual { [JsonProperty("response")] public Response2 Response { get; set; } } public class Response2 { [JsonProperty("result")] public Result Result { get; set; } [JsonProperty("uri")] public string Uri { get; set; } } public class Result { [JsonProperty("Contacts")] public Contacts Contacts { get; set; } } public class Contacts { [JsonProperty("row")] public IList Row { get; set; } } public class Row { [JsonProperty("no")] public string No { get; set; } [JsonProperty("FL")] public IList FL { get; set; } } public class FL { [JsonProperty("content")] public string Content { get; set; } [JsonProperty("val")] public string Val { get; set; } } //To De-serialize ResponseActual respone = JsonConvert.DeserializeObject(jSON_sTRING) //Get the contacts list List contacts = respone.Response.Result.Contacts.Row[0].FL.ToList(); //Now Get the required value using LINQ var value = contacts.Where((s, e) => s.Val =="Email").Select(x=>x.Content).Single(); 

您也可以签出这个 – 使用Newtonsoft将JSON反序列化为.NET对象(或者LINQ to JSON可能?)

您需要在反序列化对象中包含以下JSON部分类型:

 { "response": { "result": { "Contacts": { "row": [ { "no":"1", "FL": 

class级类型:“联系”不足。

 you can use this code: dynamic dictionary = (JsonConvert.DeserializeObject>(jsonstring))["response"]; var result = dictionary.result; var contact= result.Contacts; var row= contact.row; foreach (var item in row) { var no= item.no; } 

我能问你一件事吗? 你是那个导出JSON的人吗? 我问这个是因为格式很奇怪,它确实妨碍了你的代码。

更简单的格式允许您以直接方式序列化字符串。