代码之家  ›  专栏  ›  技术社区  ›  JoshG

如何在C#中解析复杂的嵌套JSON字符串?

  •  1
  • JoshG  · 技术社区  · 4 年前

    我有一个丑陋的JSON字符串,它是从API返回的,看起来像这样(这是 Console.Write 在字符串上):

    {"d":"\"\\\"\\\\\\\"[{\\\\\\\\\\\\\\\"foo\\\\\\\\\\\\\\\":15,\\\\\\\\\\\\\\\"bar\\\\\\\\\\\\\\\":null}]\\\\\\\"\\\"\\n\""}
    

    我试图以最简单的方式将其解析为C#对象,这样我就可以访问以下属性 foo bar 。但我很难做到这一点。

    我尝试了多种解析方法,包括:

    // code to get the response string
    client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
    var serializedData = "{data: 'data'}";
    var responseString = client.UploadString(url, "POST", serializedData);
    
    // parse the response string
    dynamic obj = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString);
    

    这使我能够访问以下值 d ,这是我需要解析的实际字符串。然后,我尝试使用 JArray.Parse(obj["d"]) ,但我得到一个错误,说 obj["d"] 不是数组。

    不幸的是,我无法访问API本身,因此无法修改它序列化返回数据的方式。

    有什么建议吗?

    2 回复  |  直到 4 年前
        1
  •  3
  •   Krishna Varma    4 年前

    您可以替换所有 New Line , Backslash , Double quotes 格式化JSON

    var formattedJson =  jsonString.Replace(@"\n", string.Empty)
                                   .Replace(@"\", string.Empty)
                                   .Replace("\"\"", string.Empty);
    Console.WriteLine(formattedJson);
    

    输出

    {
        "d": [
            {
                "foo": 15,
                "bar": null
            }
        ]
    }
    

    转换为JArray。

    var jArray = JArray.Parse(JObject.Parse(formattedJson)["d"].ToString());
    Console.WriteLine($"{jArray[0]["foo"]} {jArray[0]["bar"]}");
    

    输出

    15
    
        2
  •  2
  •   Grx70    4 年前

    问题在于 "d" 是一个表示字符串的字符串。。。代表一个数组。你可以称之为JSON序列化“incention”。

    处理此问题的方法是将值反序列化相应的次数。如果你确定该值永远不会是一个实际的字符串,你可以这样做,而不必知道该值被序列化了多少次:

    var myObject = JObject.Parse(s);
    var d = myObject["d"];
    while(d.Type == JTokenType.String)
        d = JToken.Parse(d.ToObject<string>());
    myObject["d"] = d;
    

    在此程序之后 myObject 表示此数据:

    {
      "d": [
        {
          "foo": 15,
          "bar": null
        }
      ]
    }
    
        3
  •  0
  •   Cueball 6118    4 年前

    很好地替换转义字符,但我不会依赖console.write命令作为最终的输出来检查。以下是其他几种方法:-

    1. 使用Postman进行API调用,这样您就可以看到原始结果。这将(希望)以易于阅读的格式显示它,然后您可以定义要反序列化的类。
    2. 将原始响应写入.json文件。在一个好的编辑器(如VS Code或VS本身)中打开该文件,查看数据在接收时的实际结构。

    另外,我建议使用RestSharp和Newtonsoft进行REST调用。Json进行序列化/反序列化。