解析来自 StreamBuilder C# 的 JSON 响应

Posted

技术标签:

【中文标题】解析来自 StreamBuilder C# 的 JSON 响应【英文标题】:Parsing JSON response from StreamBuilder C# 【发布时间】:2020-06-17 09:03:10 【问题描述】:

我从另一个网站收到 JSON 响应,然后从 StreamReader 构建响应:-

using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))

            response = streamReader.ReadToEnd();

我得到的结果是:-

string response = "\"d\":\"[\\\"Animal\\\":\\\"Cat\\\",\\\"Noise\\\":\\\"Meow\\\",\\\"Animal\\\":\\\"Dog\\\",\\\"Noise\\\":\\\"Woof\\\"]\"";

然后我使用 JsonConvert.DeserializeObject(response) 进行反序列化,然后我尝试遍历结果以读取值.. 但无论我尝试什么都不起作用

dynamic jObj = JsonConvert.DeserializeObject(response);
var arr = jObj; //Tried var arr = jObj.d;

@foreach (var item in arr)

 ….

错误目标类型 System.Collections.IEnumerable 不是值类型或非抽象类。 参数名称:targetType

【问题讨论】:

d 实际上有一个数组作为内容,包装成字符串 似乎一个 JSON 数据成为主 JSON 中某个键的值 你在查询什么 API? 【参考方案1】:

您的 JSON 响应包含一个 d 属性,该值是一个包含在字符串本身中的数组。

所以,你应该将d的内容单独解析成数组,Json.Linq的解决方案如下

string response = "\"d\":\"[\\\"Animal\\\":\\\"Cat\\\",\\\"Noise\\\":\\\"Meow\\\",\\\"Animal\\\":\\\"Dog\\\",\\\"Noise\\\":\\\"Woof\\\"]\"";
var json = JObject.Parse(response);
var array = json["d"];

foreach (var item in JArray.Parse(array.ToString()))

    Console.WriteLine(item["Animal"]);

反序列化为dynamic对象的解决方案

dynamic json = JsonConvert.DeserializeObject(response);
var array = json?.d;

foreach (var item in JsonConvert.DeserializeObject(array?.ToString()))

    Console.WriteLine(item?.Animal);

它允许您在不更改源 JSON 的情况下解析响应

【讨论】:

您认为 API 作者将数组包装在字符串中并强制执行额外的反序列化步骤有什么用处吗? @RobertHarvey 就个人而言,我没有看到任何正当理由:) 我猜,OP 无法控制此 API,他可以向 API 作者询问规范和原因。几天前我已经看到similar question,响应来自hangfire,也许OP具有相同的API合约【参考方案2】:

如果您打印了response,您会看到jObj.d 不是一个数组,而是一个字符串。实际上,它看起来像是对象数组的字符串表示形式。

【讨论】:

【参考方案3】:

“d”的值似乎包含另一个 JSON 数据。如果它是正确的并且你不想接触 JSON 格式,这里是解决方案:

    string response = "\"d\":\"[\\\"Animal\\\":\\\"Cat\\\",\\\"Noise\\\":\\\"Meow\\\",\\\"Animal\\\":\\\"Dog\\\",\\\"Noise\\\":\\\"Woof\\\"]\"";

    dynamic jObj = JsonConvert.DeserializeObject(response);

    var arr = JsonConvert.DeserializeObject<D[]>((jObj.d).Value);

    foreach (var item in arr)
    

    

     ........

    public class D
    
        public string Animal  get; set; 
        public string Noise  get; set; 
    

【讨论】:

以上是关于解析来自 StreamBuilder C# 的 JSON 响应的主要内容,如果未能解决你的问题,请参考以下文章

StreamBuilder 未显示来自 firestore 的数据

如何访问 StreamBuilder 中的多个流?

为啥 NotifyParser 的任何更改都不会使用 Provider / ChangeNotifier / Streambuilder 在 UI 中呈现,而是来自服务类

Flutter:显示来自经过身份验证的 Firebase Auth 用户的带有 StreamBuilder 的一些 Firestore 集合

在 Flutter 中使用 streamBuilder 时条件不起作用

C#:来自 System.Type 的动态解析