【问题标题】:Unable to convert JSON string from API call into Dictionary无法将 API 调用中的 JSON 字符串转换为字典
【发布时间】:2017-06-28 13:26:47
【问题描述】:

早上好!我仍在学习如何处理 REST API 调用并通常处理 HTTP 请求,所以请提供任何反馈:)

我正在尝试对 Web 服务进行 GET 调用,它应该返回一个 JSON 字符串,它是一组信息,它应该是以类似字典的方式返回的 SQL 记录。

但是,我遇到了几个问题,不知道我是否正确地解决了问题:

  1. 调用网络服务。将其定义为“GET”调用。
  2. 处理响应并使用 StreamReader 读取它。
  3. 使用 NewtonSoft JSON 方法,将响应反序列化为字典格式。
  4. 根据自己的喜好使用字典。

    // Call the Web Service
                    string url = "{URL HERE}"; 
    
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                    request.Method = "GET";
                    request.ContentType = "application/json";
                    request.ContentLength = 0;
                        //Dictionary<string, string> dataList = null;
    
                    try
                    {
                        WebResponse response = request.GetResponse();
                        Stream responseStream = response.GetResponseStream();
                        StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
                        var json = reader.ReadToEnd();
    
                        //Dictionary<string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
    
                        var data = JsonConvert.DeserializeObject<List<KeyValuePair<string, List<KeyValuePair<string, string>>>>>(json);
                        var dataDictionary = data.ToDictionary(
                             x => x.Key,
                             x => x.Value.ToDictionary(y => y.Key, y => y.Value));
    
                        //dataList = (Dictionary<string, string>) dataDictionary;
    
                        var test = dataDictionary["Key"];
    

调用排序中的 JSON 字符串是什么样的:

  • "[{\"Number\":4,\"FieldABC\":\"ABC\"}]"

我尝试过的其他解决方案:

  1. 改用字典数据类型。
  2. 各种其他方法调用,如代码中注释掉的方法。
  3. 另一个 SO 帖子建议使用 ToDictionary() 调用。

我遇到的错误:

  • {“值不能为空。\r\n参数名称:源”} System.Exception {System.ArgumentNullException}

  • 无法将 JSON 字符串转换为 JSON 对象。

我是否误解了如何处理来自 HTTP 请求的响应?还是我混淆/滥用数据类型?非常感谢任何帮助!


更新:有了以下所有答案,解决方案最终成为所有 cmets 的组合!首先,我使用 json2csharp.com 创建对象。然后,使用下面推荐的更新后的 HTTP 调用,我将 JSON 反序列化为 Lists 类型,以便我得到一个长度为 1 的列表,我可以从中访问我的信息。谢谢大家!

【问题讨论】:

  • 尝试做,JsonConvert.DeserializeObject&lt;JObject&gt;,然后你就可以遍历 JSON 树了。
  • 首先,找出 JSON 的实际外观。创建一个具有完全相同属性的类并首先将它们设为字符串,因为这永远不会失败。然后使用 JsonConvert.DeserializeObject&lt;List&lt;YourClass&gt;&gt;(responseString); 从收到的 json 字符串创建对象列表。使用Dictionary 的问题在于它由KeyValue-pairs 组成,其中Dictionary 中的密钥必须是唯一的。如果不是这种情况,转换将失败。
  • @Callum,我尝试将代码更改为:var values = JsonConvert.DeserializeObject(json);,并收到错误“无法区分类型的对象”Newtonsoft.Json.Linq。 JArray' 来输入 'Newtonsoft.Json.Linq.JObject'。是否需要“遍历 JSON 树”之前的步骤(抱歉,我对术语不熟悉)。
  • 那么把JObject改成JArray ....
  • @Bunnynut JSON 字符串类似于具有更多字段的“[{\"Number\":4,\"FieldABC\":\"ABC\"}]"。为了阅读目的,帖子中的示例进行了简化。我还缺少另一个 JSON 对象吗?还是我应该将该字符串转换为其他字符串?

标签: c# json dictionary


【解决方案1】:

所以当我使用http://json2csharp.com/ 来使用你的 JSON 时,我会得到:

public class ClassName
{
    public int Number { get; set; }
    public string FieldABC { get; set; }
}

使用HttpClient,这样更容易:

using (var client = new HttpClient())
{
    var response = await client.GetAsync(progressUrl);
    var yourObject == JsonConvert.DeserializeObject<ClassName>(await response .Content.ReadAsStringAsync());
}

继续剩下的……

您也可以使用HttpClientExtensions Class

干杯!

【讨论】:

  • 感谢大家的帮助!所有这些 cmets 真的教会了我很多关于 JSON 和其他编码实践的知识。不幸的是,我无法标记所有内容或支持所有内容,但 json2csharp 的链接确实对我的大型对象有所帮助。我会更新我的帖子:)
  • @Roelant 一些小修复:var yourObject == 应该是 var yourObject =response .Content(空格)应该是 response.Content
【解决方案2】:

首先制作一个与响应字符串完全匹配的 POCO。像这样的:

public class MyResponseObject {

    public int Number { get; set; }

    public string FieldABC { get; set; }

    // other properties here
}

假设您收到了[{\"Number\":4,\"FieldABC\":\"ABC\"}] 建议的这些对象的数组,那么您可以使用反序列化它

JsonConvert.DeserializeObject<List<MyResponseObject>>(json);

如果它是一个更复杂的对象,那么您可以在主对象中包含其他嵌套对象:

public class MyNestedObject {

    public string NestedName { get; set; }

    public bool IsEnabled { get;  set; }

}


public class MyResponseObject {

    public List<MyNestedObject> NestedObjects { get; set; }

}

一旦你有了List&lt;MyResponseObject&gt;,你可能会发现你根本不需要字典,或者如果你需要,你可以利用许多 Linq Enumerable 方法而不必担心 JSON。

【讨论】:

    【解决方案3】:

    使用HttpClient代替HttpWebRequest,如下:

            using (var httpClient = new System.Net.Http.HttpClient())
            {
                httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
    
                var response = await httpClient.GetAsync(url);
                var data = await response.Content.ReadAsStringAsync();
                Dictionary<string, string> ValueList = JsonConvert.DeserializeObject<Dictionary<string, string>>(data);
            }
    

    【讨论】:

    • 虽然这可能会回答问题,但仅代码的答案是不受欢迎的。还请向 OP 提供解释以解释您的答案。 How to Answer
    猜你喜欢
    • 1970-01-01
    • 2021-10-22
    • 1970-01-01
    • 2014-07-06
    • 2016-12-06
    • 2017-04-27
    • 1970-01-01
    • 2021-11-04
    相关资源
    最近更新 更多