Note that there are some explanatory texts on larger screens.

plurals
  1. POParsing a complex JSON result with C#
    primarykey
    data
    text
    <p>I am trying to parse the following complex JSON result, which is returned from the Zoho Crm API:</p> <pre><code>{ "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" } </code></pre> <p>}</p> <p>Here is how my Object looks:</p> <pre><code>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; } } </code></pre> <p>The "row" pattern repeats (no 1, 2, 3 ...) so what I am basically trying to get is a Generic List of Objects of this type. I am trying to using JSON.NET, but I am open to other suggestions if it makes this any easier. </p> <p>This doesn't work in this case obviously:</p> <pre><code>var response = JsonConvert.DeserializeObject&lt;Contact&gt;(jsonString); </code></pre> <p>And neither does this:</p> <pre><code>var deserializedObjects = JsonConvert.DeserializeObject&lt;List&lt;Contact&gt;&gt;(jsonString); </code></pre> <p>Here is a workaround I have put together to parse this using JavaScriptSerializer, but it is by far one of my worst code blocks ever! </p> <pre><code> List&lt;Contact&gt; loContactList = new List&lt;Contact&gt;(); Contact loContact = null; Dictionary&lt;string, object&gt; dictionary = new JavaScriptSerializer().Deserialize&lt;Dictionary&lt;string, object&gt;&gt;(jsonString); var response = (Dictionary&lt;string, object&gt;)dictionary["response"]; var result = (Dictionary&lt;string, object&gt;)response["result"]; var contacts = (Dictionary&lt;string, object&gt;)result["Contacts"]; var row = (ArrayList)contacts["row"]; foreach (var item in row) { var loArrayItem = (Dictionary&lt;string, object&gt;)item; var fl = (ArrayList)loArrayItem["FL"]; loContact = new Contact(); foreach (var contactitem in fl) { var contactdict = (Dictionary&lt;string, object&gt;)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); } </code></pre> <p>I have gone through other similar posts on StackOverflow and none of them seem to provide a solution for this problem. Does anyone have a solution for this? My goal is to parse this JSON response in a more elegant way, which doesn't involve a million dictionary objects and ArrayList! Any help would be appreciated.</p> <p>Thanks, Pete</p> <p><strong>Update 7/2/13:</strong></p> <p>Based on Manvik's suggestion, I put together the following additional solution:</p> <pre><code> 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&lt;Row&gt; Row { get; set; } } public class Row { [JsonProperty("no")] public string No { get; set; } [JsonProperty("FL")] public IList&lt;FL&gt; FL { get; set; } } public class FL { [JsonProperty("content")] public string Content { get; set; } [JsonProperty("val")] public string Val { get; set; } } List&lt;Contact&gt; loContactList = new List&lt;Contact&gt;(); Contact loContact = null; ResponseActual respone = JsonConvert.DeserializeObject&lt;ResponseActual&gt;(jsonString); foreach (var row in respone.Response.Result.Contacts.Row) { loContact = new Contact(); var rowItem = row.FL.ToList(); try { loContact.ContactID = rowItem.Where&lt;FL&gt;((s, t) =&gt; s.Val == "CONTACTID").Select(x =&gt; x.Content).Single(); } catch { } try { loContact.OwnerID = rowItem.Where&lt;FL&gt;((s, t) =&gt; s.Val == "SMOWNERID").Select(x =&gt; x.Content).Single(); } catch { } try { loContact.ContactOwner = rowItem.Where&lt;FL&gt;((s, t) =&gt; s.Val == "Contact Owner").Select(x =&gt; x.Content).Single(); } catch { } try { loContact.FirstName = rowItem.Where&lt;FL&gt;((s, t) =&gt; s.Val == "First Name").Select(x =&gt; x.Content).Single(); } catch { } try { loContact.LastName = rowItem.Where&lt;FL&gt;((s, t) =&gt; s.Val == "Last Name").Select(x =&gt; x.Content).Single(); } catch { } try { loContact.Email = rowItem.Where&lt;FL&gt;((s, t) =&gt; s.Val == "Email").Select(x =&gt; x.Content).Single(); } catch { } try { loContact.CreatorID = rowItem.Where&lt;FL&gt;((s, t) =&gt; s.Val == "SMCREATORID").Select(x =&gt; x.Content).Single(); } catch { } try { loContact.CreatedBy = rowItem.Where&lt;FL&gt;((s, t) =&gt; s.Val == "Created By").Select(x =&gt; x.Content).Single(); } catch { } try { loContact.ModifiedByID = rowItem.Where&lt;FL&gt;((s, t) =&gt; s.Val == "MODIFIEDBY").Select(x =&gt; x.Content).Single(); } catch { } try { loContact.ModifiedBy = rowItem.Where&lt;FL&gt;((s, t) =&gt; s.Val == "Modified By").Select(x =&gt; x.Content).Single(); } catch { } try { loContact.CreatedTime = Convert.ToDateTime(rowItem.Where&lt;FL&gt;((s, t) =&gt; s.Val == "Created Time").Select(x =&gt; x.Content).Single()); } catch { } try { loContact.ModifiedTime = Convert.ToDateTime(rowItem.Where&lt;FL&gt;((s, t) =&gt; s.Val == "Modified Time").Select(x =&gt; x.Content).Single()); } catch { } try { loContact.LastActivityTime = Convert.ToDateTime(rowItem.Where&lt;FL&gt;((s, t) =&gt; s.Val == "Last Activity Time").Select(x =&gt; x.Content).Single()); } catch { } loContactList.Add(loContact); } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload