解析用C#一个复杂的JSON结果 [英] Parsing a complex JSON result with C#
问题描述
我试图解析如下复杂的JSON结果,这是从百会CRM API返回:
{
响应:
{
结果:
{
联系人:
{
行:
[
{
无:1,
FL:
[
{
内容:555555000000123456,
VAL:的ContactID
},
{
内容:555555000000012345,
VAL:SMOWNERID
},
{
内容:李四,
VAL:联络代理
},
{
内容:皮特,
VAL:名
},
{
内容:史密斯夫妇,
VAL:姓
},
{
内容:pete@mail.com
VAL:电子邮件
},
{
内容:5555551000000012346,
VAL:SMCREATORID
},
{
内容:李四,
VAL:创建者
},
{
内容:555555000000012347,
VAL:MODIFIEDBY
},
{
内容:多丽丝·多伊,
VAL:修改者
},
{
内容:2013年6月14日17点24分10秒,
VAL:创建时间
},
{
内容:2013年6月14日17点24分10秒,
VAL:修改时间
},
{
内容:2013年6月14日十七时28分05秒,
VAL:最近活动时间
}
]
},
{
...
}
]
}
},
URI:/ CRM /私营/ JSON /联系人/ getRecords
}
}
下面是我的物体的外观:
公共类联系
{
[JsonProperty(属性名=的ContactID)
公共字符串的ContactID {获得;组; }
[JsonProperty(属性名=SMOWNERID)]
公共字符串OWNERID {获得;组; }
[JsonProperty(属性名=联络代理)]
公共字符串ContactOwner {获得;组; }
[JsonProperty(属性名=名)]
公共字符串名字{获得;组; }
[JsonProperty(属性名=姓)
公共字符串LasName {获得;组; }
[JsonProperty(属性名=电子邮件)
公共字符串电子邮件{获得;组; }
[JsonProperty(属性名=SMCREATORID)]
公共字符串的CreatorID {获得;组; }
[JsonProperty(属性名=创建者)]
公共字符串CreatedBy {获得;组; }
[JsonProperty(属性名=MODIFIEDBY)]
公共字符串ModifiedByID {获得;组; }
[JsonProperty(属性名=修改者)]
公共字符串ModifiedBy {获得;组; }
[JsonProperty(属性名=创建时间)
公开日期时间CreatedTime {获得;组; }
[JsonProperty(属性名=修改时间)
公开日期时间ModifiedTime {获得;组; }
[JsonProperty(属性名=最近活动时间)
公开日期时间LastActivityTime {获得;组; }
}
行图案重复(1号,2,3 ...),所以什么,我只想尽力去得到的是这种类型的对象泛型列表。我试图用JSON.NET,但我接受其他的建议,如果它使这更容易。
这并不在此情况下工作,很明显:
VAR响应= JsonConvert.DeserializeObject<联系与GT;(jsonString);
而且也没有这样的:
VAR deserializedObjects = JsonConvert.DeserializeObject<列表<联系与GT;>(jsonString);
下面是一种变通方法我已经把使用JavaScriptSerializer解析这一点,但它是迄今为止我最糟糕的code有史以来块一个!
名单,其中,联系与GT; loContactList =新的名单,其中,联系与GT;();
联系loContact = NULL;
字典<字符串,对象> 。词典=新JavaScriptSerializer()反序列化<字典<字符串,对象>>(jsonString);
VAR响应=(词典<字符串,对象>)字典[回应];
VAR的结果=(词典<字符串,对象>)响应[结果]。
VAR接触=(词典<字符串,对象>)的结果[联系人];
VAR行=(ArrayList中)接触[行];
的foreach(行VAR项)
{
VAR loArrayItem =(词典<字符串,对象>)的项目;
变种FL =(ArrayList中)loArrayItem [FL];
loContact =新联系();
的foreach(在佛罗里达州VAR contactitem)
{
VAR contactdict =(词典<字符串,对象>)contactitem;
字符串VAL =(字符串)contactdict [VAL];
字符串内容=(字符串)contactdict [内容];
如果(VAL ==的ContactID)
{
loContact.ContactID =内容;
}
否则,如果(VAL ==SMOWNERID)
{
loContact.OwnerID =内容;
}
否则,如果(VAL ==联络代理)
{
loContact.ContactOwner =内容;
}
否则,如果(VAL ==名)
{
loContact.FirstName =内容;
}
否则,如果(VAL ==姓)
{
loContact.LastName =内容;
}
否则,如果(VAL ==电子邮件)
{
loContact.Email =内容;
}
否则,如果(VAL ==SMCREATORID)
{
loContact.CreatorID =内容;
}
否则,如果(VAL ==创建者)
{
loContact.CreatedBy =内容;
}
否则,如果(VAL ==MODIFIEDBY)
{
loContact.ModifiedByID =内容;
}
否则,如果(VAL ==修改者)
{
loContact.ModifiedBy =内容;
}
否则,如果(VAL ==创建时间)
{
loContact.CreatedTime = Convert.ToDateTime(内容);
}
否则,如果(VAL ==修改时间)
{
loContact.ModifiedTime = Convert.ToDateTime(内容);
}
否则,如果(VAL ==最近活动时间)
{
loContact.LastActivityTime = Convert.ToDateTime(内容);
}
}
loContactList.Add(loContact);
}
我已经通过计算器等类似的帖子消失了,没有人似乎提供了一个解决这个问题。有没有人有一个解决方案?我的目标是在分析一个更优雅的方式,不涉及上百万字典对象和ArrayList这JSON响应!任何帮助将是AP preciated。
谢谢, 皮特
更新13年7月2日:
根据Manvik的建议下,我放在一起以下附加解决方案:
公共类ResponseActual
{
[JsonProperty(回应)
市民响应2响应{获得;组; }
}
公共类响应2
{
[JsonProperty(结果)]
公开结果结果{获得;组; }
[JsonProperty(URI)]
公共字符串乌里{获得;组; }
}
公共类结果
{
[JsonProperty(联系人)
公开联系方式联系方式{获得;组; }
}
公共类联系方式
{
[JsonProperty(行)]
公众的IList<行>行{获得;组; }
}
公共类行
{
[JsonProperty(无)]
公共字符串否{获得;组; }
[JsonProperty(FL)]
公众的IList< FL> FL {获得;组; }
}
公共类FL
{
[JsonProperty(内容)]
公共字符串内容{获得;组; }
[JsonProperty(VAL)]
公共字符串的Val {获得;组; }
}
名单<联系与GT; loContactList =新的名单,其中,联系与GT;();
联系loContact = NULL;
ResponseActual respone = JsonConvert.DeserializeObject< ResponseActual>(jsonString);
的foreach(在respone.Response.Result.Contacts.Row VAR行)
{
loContact =新联系();
变种rowItem = row.FL.ToList();
尝试{loContact.ContactID = rowItem.Where&其中; FL>((S,T)=> s.Val ==的ContactID)选择(X => x.Content)。。单(); }
抓住 { }
尝试{loContact.OwnerID = rowItem.Where&其中; FL>((S,T)=> s.Val ==SMOWNERID)选择(X => x.Content)。。单(); }
抓住 { }
尝试{loContact.ContactOwner = rowItem.Where< FL>((S,T)=> s.Val ==联络代理),选择(X => x.Content)。单(); }
抓住 { }
尝试{loContact.FirstName = rowItem.Where< FL>((S,T)=> s.Val ==名),选择(X => x.Content)。单(); }
抓住 { }
尝试{loContact.LastName = rowItem.Where< FL>((S,T)=> s.Val ==姓),选择(X => x.Content)。单(); }
抓住 { }
尝试{loContact.Email = rowItem.Where< FL>((S,T)=> s.Val ==电子邮件)选择(X => x.Content)。单(); } 抓住 { }
尝试{loContact.CreatorID = rowItem.Where&其中; FL>((S,T)=> s.Val ==SMCREATORID),选择(X => x.Content)。单(); }
抓住 { }
尝试{loContact.CreatedBy = rowItem.Where< FL>((S,T)=> s.Val ==创建者),选择(X => x.Content)。单(); }
抓住 { }
尝试{loContact.ModifiedByID = rowItem.Where&其中; FL>((S,T)=> s.Val ==MODIFIEDBY),选择(X => x.Content)。单(); }
抓住 { }
尝试{loContact.ModifiedBy = rowItem.Where&其中; FL>((S,T)=> s.Val ==修改者),选择(X => x.Content)。单(); }
抓住 { }
尝试{loContact.CreatedTime = Convert.ToDateTime(rowItem.Where< FL>((S,T)=> s.Val ==创建时间)选择(X => x.Content)。单() ); }
抓住 { }
尝试{loContact.ModifiedTime = Convert.ToDateTime(rowItem.Where< FL>((S,T)=> s.Val ==修改时间)选择(X => x.Content)。单() ); }
抓住 { }
尝试{loContact.LastActivityTime = Convert.ToDateTime(rowItem.Where< FL>((S,T)=> s.Val ==最近活动时间)选择(X => x.Content)。单( )); }
抓住 { }
loContactList.Add(loContact);
}
使用下面的类使用反序列JSON.Net
公共类ResponseActual
{
[JsonProperty(回应)
市民响应2响应{获得;组; }
}
公共类响应2
{
[JsonProperty(结果)]
公开结果结果{获得;组; }
[JsonProperty(URI)]
公共字符串乌里{获得;组; }
}
公共类结果
{
[JsonProperty(联系人)
公开联系方式联系方式{获得;组; }
}
公共类联系方式
{
[JsonProperty(行)]
公众的IList<行>行{获得;组; }
}
公共类行
{
[JsonProperty(无)]
公共字符串否{获得;组; }
[JsonProperty(FL)]
公众的IList< FL> FL {获得;组; }
}
公共类FL
{
[JsonProperty(内容)]
公共字符串内容{获得;组; }
[JsonProperty(VAL)]
公共字符串的Val {获得;组; }
}
//反序列化
ResponseActual respone = JsonConvert.DeserializeObject< ResponseActual>(jSON_sTRING)
//获取联系人列表
名单< FL>联系人= respone.Response.Result.Contacts.Row [0] .FL.ToList();
//现在获取使用LINQ所需的值
VAR值= contacts.Where< FL>((S,E)=> s.Val ==电子邮件),选择(X => x.Content)。单();
您也可以结帐这一点 - <一href="http://stackoverflow.com/questions/4749639/deserializing-json-to-net-object-using-newtonsoft-or-linq-to-json-maybe">deserializing JSON使用NewtonSoft到.NET对象(或LINQ到JSON也许?)
I am trying to parse the following complex JSON result, which is returned from the Zoho Crm API:
{
"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"
}
}
Here is how my Object looks:
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; }
}
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.
This doesn't work in this case obviously:
var response = JsonConvert.DeserializeObject<Contact>(jsonString);
And neither does this:
var deserializedObjects = JsonConvert.DeserializeObject<List<Contact>>(jsonString);
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!
List<Contact> loContactList = new List<Contact>();
Contact loContact = null;
Dictionary<string, object> dictionary = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(jsonString);
var response = (Dictionary<string, object>)dictionary["response"];
var result = (Dictionary<string, object>)response["result"];
var contacts = (Dictionary<string, object>)result["Contacts"];
var row = (ArrayList)contacts["row"];
foreach (var item in row)
{
var loArrayItem = (Dictionary<string, object>)item;
var fl = (ArrayList)loArrayItem["FL"];
loContact = new Contact();
foreach (var contactitem in fl)
{
var contactdict = (Dictionary<string, object>)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);
}
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.
Thanks, Pete
Update 7/2/13:
Based on Manvik's suggestion, I put together the following additional solution:
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> Row { get; set; }
}
public class Row
{
[JsonProperty("no")]
public string No { get; set; }
[JsonProperty("FL")]
public IList<FL> FL { get; set; }
}
public class FL
{
[JsonProperty("content")]
public string Content { get; set; }
[JsonProperty("val")]
public string Val { get; set; }
}
List<Contact> loContactList = new List<Contact>();
Contact loContact = null;
ResponseActual respone = JsonConvert.DeserializeObject<ResponseActual>(jsonString);
foreach (var row in respone.Response.Result.Contacts.Row)
{
loContact = new Contact();
var rowItem = row.FL.ToList();
try { loContact.ContactID = rowItem.Where<FL>((s, t) => s.Val == "CONTACTID").Select(x => x.Content).Single(); }
catch { }
try { loContact.OwnerID = rowItem.Where<FL>((s, t) => s.Val == "SMOWNERID").Select(x => x.Content).Single(); }
catch { }
try { loContact.ContactOwner = rowItem.Where<FL>((s, t) => s.Val == "Contact Owner").Select(x => x.Content).Single(); }
catch { }
try { loContact.FirstName = rowItem.Where<FL>((s, t) => s.Val == "First Name").Select(x => x.Content).Single(); }
catch { }
try { loContact.LastName = rowItem.Where<FL>((s, t) => s.Val == "Last Name").Select(x => x.Content).Single(); }
catch { }
try { loContact.Email = rowItem.Where<FL>((s, t) => s.Val == "Email").Select(x => x.Content).Single(); } catch { }
try { loContact.CreatorID = rowItem.Where<FL>((s, t) => s.Val == "SMCREATORID").Select(x => x.Content).Single(); }
catch { }
try { loContact.CreatedBy = rowItem.Where<FL>((s, t) => s.Val == "Created By").Select(x => x.Content).Single(); }
catch { }
try { loContact.ModifiedByID = rowItem.Where<FL>((s, t) => s.Val == "MODIFIEDBY").Select(x => x.Content).Single(); }
catch { }
try { loContact.ModifiedBy = rowItem.Where<FL>((s, t) => s.Val == "Modified By").Select(x => x.Content).Single(); }
catch { }
try { loContact.CreatedTime = Convert.ToDateTime(rowItem.Where<FL>((s, t) => s.Val == "Created Time").Select(x => x.Content).Single()); }
catch { }
try { loContact.ModifiedTime = Convert.ToDateTime(rowItem.Where<FL>((s, t) => s.Val == "Modified Time").Select(x => x.Content).Single()); }
catch { }
try { loContact.LastActivityTime = Convert.ToDateTime(rowItem.Where<FL>((s, t) => s.Val == "Last Activity Time").Select(x => x.Content).Single()); }
catch { }
loContactList.Add(loContact);
}
Use the below classes for de-serializing using 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> Row { get; set; }
}
public class Row
{
[JsonProperty("no")]
public string No { get; set; }
[JsonProperty("FL")]
public IList<FL> 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<ResponseActual>(jSON_sTRING)
//Get the contacts list
List<FL> contacts = respone.Response.Result.Contacts.Row[0].FL.ToList();
//Now Get the required value using LINQ
var value = contacts.Where<FL>((s, e) => s.Val =="Email").Select(x=>x.Content).Single();
You may also checkout this - deserializing JSON to .net object using NewtonSoft (or linq to json maybe?)
这篇关于解析用C#一个复杂的JSON结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!