解析用C#一个复杂的JSON结果复杂、结果、JSON

2023-09-04 13:19:44 作者:你若一直在我便一直爱

我试图解析如下复杂的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,但我接受其他的建议,如果它使这更容易。

分享一个好用的JSON读取工具JsonPath

这并不在此情况下工作,很明显:

  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)。单();
 

您也可以结帐这一点 - 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?)