使用嵌套数组反序列化JSON以从值生成字符串

本文关键字:字符串 JSON 嵌套 数组 反序列化 | 更新日期: 2023-09-27 18:28:05

在我的应用程序中,我有一个List<Users>

[{
"Id": "1",
"Name": "last, first",
"Skills": [{"SN":"20","SL":"12"},{"SN":"197","SL":"09"}]
},
{
"Id": "2",
"Name": "Black, Jack",
"Skills": [{"SN":"40","SL":"07"},{"SN":"199","SL":"05"}]
},
{
"Id": "3",
"Name": "Rooney, Wayne",
"Skills": [{"SN":"40","SL":"11"},{"SN":"201","SL":"07"}]
}]

我需要将这些数据转换成一个字符串,格式如下:

"1/last,first/20-1297-09;2/Black,Jack/40-0799-05;3/Rooney,Wayne/40-11211-07"

我试图序列化这个对象以获得一个JSON字符串:

public IHttpActionResult ImportUsers([FromBody]IEnumerable<Users> newUsers)
{
    string agents = JsonConvert.SerializeObject(newUsers);
    return Ok(agents);
}

并得到一个结果:

"[{''"Id''":''"1''",''"Name''":"最后,first''",''"Skills''":[{''"SN''":''"20''","SL''":''"12''"},{''"SN''":"197''",''"SL''":"09''"}]},Jack","Skills":[{''"SN":''"40",''"SL":''"07"},{''"SN":''"199",''"SL":''"05"}]},Wayne",''"Skills":[{''"SN''":''"40''",''"SL''":''"11''"},{''"SN''":"201''",''"SL":''"07''"}]}]"

然后我试图反序列化这个字符串,以获得每个变量的值

var dict = JsonConvert.DeserializeObject<dynamic>(agents);
            List<string> results = new List<string>();
            foreach (var d in dict)
            {                
                var skills = d["Skills"];                
                string skill = string.Join(",", skills);
                string list = d["Id"] + "/" + d["Name"] + "/" + skill;
                results.Add(list);
            }
            string result = string.Join(";", results);

并得到这个字符串:

"1/last,first/{''r''n''r''n ''"SN''":''"20''",''r''n''r''n ''"SL''":"12''"''r''n},{''r''n''"SN''":''"197''",''"SL''":"09''"''r''n};2/黑色,杰克/{'' r''n ''"SN ''":''"40''",'' r''n ''"SL''":''"07''"''r''n},{''r''n ''"SN''":"199''",''r''n ''"SL ''":''"05''"''r''n};3/鲁尼/"SN":"40","SL":''"11''"''r''n},{''"SN''":''"201''",''"SL''":"07''"''r''n}"

所以这更像是我需要的,但我对技能列表中的值仍然有问题。如何从中获取值,就像在Id和Name列中一样?也许我需要再次反序列化这一部分,或者使用一些正则表达式来实现我需要的字符串?

使用嵌套数组反序列化JSON以从值生成字符串

您的预期结果不是有效的json。那么更好的方法是在没有第三方库的情况下通过c#格式化结果字符串。

简洁的方法是使用字符串函数:

public IHttpActionResult ImportUsers([FromBody] IEnumerable<User> newUsers)
{
    var agents = string.Join(";", newUsers.Select(GetFormattedUserString));
    return Ok(agents);
}
private string GetFormattedUserString(User user)
{
    return string.Concat(user.Id, "/", user.Name, "/", string.Join(",", user.Skills.Select(skill => string.Concat(skill.SN, "-", skill.SL))));
}

高效且不太容易理解(在我看来)的方法是使用StringBuilder:

public IHttpActionResult ImportUsers([FromBody] IEnumerable<User> newUsers)
{
    var sb = new StringBuilder();
    foreach (var user in newUsers)
    {
        sb.Append(user.Id);
        sb.Append("/");
        sb.Append(user.Name);
        sb.Append("/");
        for (int i = 0; i < user.Skills.Length; i++)
        {
            sb.Append(user.Skills[i].SN);
            sb.Append("-");
            sb.Append(user.Skills[i].SL);
            if (i != user.Skills.Length)
                sb.Append(",");
        }
        sb.Append(";");
    }
    var result = sb.ToString();
    return Ok(result);
}

您可以稍微修改代码以使其工作。为了以您想要的方式获得技能,您可以嵌套另一个foreach循环,该循环将以请求的格式创建技能列表:

var dict = JsonConvert.DeserializeObject<dynamic>(agents);
List<string> results = new List<string>();
foreach (var d in dict)
{
    List<string> skills = new List<string>();
    foreach (var s in d["Skills"])
    {
        skills.Add(s["SN"].ToString() + "-" + s["SL"].ToString());
    }
    string skill = string.Join(",", skills);
    string list = d["Id"] + "/" + d["Name"] + "/" + skill;
    results.Add(list);
}
string result = string.Join(";", results);