【问题标题】:Desrialize JSON into List<List<KeyValuePair>> result is null将 JSON 反序列化为 List<List<KeyValuePair>> 结果为空
【发布时间】:2021-01-14 05:59:53
【问题描述】:

我从 API 获得 JSON 结果

{"Data":[[{"Key":"Proudct","Value":"PC"},{"Key":"Address","Value":"USA"},{"Key":"Tel","Value":"123456777"}]]}

我的模型课:

public class MyData
{
   public List<List<KeyValuePair<string, string>>> Data {get; set;}
   //public List<List<Dictionary<string, string>>> Data {get; set;}
}

我的功能

public async Task<MyData> GetDataAsync()
{ 
    var response = await _httpClient.GetAsync("apiURL");

    if (response.StatusCode == HttpStatusCode.OK)
    {
        string result = await response.Content.ReadAsStringAsync();
        var data = JsonConvert.DeserializeObject<MyData>(result);
       return data
    }

    return new MyData();
}

除非我将 KeyValuePair 更改为 Dictionary 类型,否则结果始终为 null。我不能使用字典,因为“键”有时不会是唯一的,我不知道为什么 List 不能按预期工作!!

提前致谢

【问题讨论】:

  • 您将Result 作为属性名称,但将Data 作为JSON 键。
  • 提示:在以后的问题中,请确保完全包含您的 JSON 数据。似乎您缺少一对周围的{}。此外,尝试手动构建您的 List&lt;List&lt;KeyValuePair&lt;string, string&gt;&gt;&gt; 的实例并将其序列化为 JSON - 查看 实际上 是否代表您正在接收的数据的结构
  • 创建一个对象,设置一些值,序列化为文本,然后看看你得到了什么。然后你可以找出不匹配的地方。比在 stackoverflow 上询问要快得多。或者只是在 Visual Studio 中使用“将 JSON 粘贴为类”
  • 好的,感谢您的编辑。我无法重现您的问题。看看这个:dotnetfiddle.net/00vjcb
  • 还要确保您使用的是 NewtonSoft。 System.Text.Json 有奇怪的失败模式,大部分时间都是沉默的。

标签: c# asp.net-web-api json.net


【解决方案1】:

在您的原始帖子中,您向我们提供了如下所示的示例 JSON:

{
    "Data": [[{
                "Key": "Proudct",
                "Value": "PC"
            }, {
                "Key": "Address",
                "Value": "USA"
            }, {
                "Key": "Tel",
                "Value": "123456777"
            }
        ]]
}

这可以满足您的需要!但是当我(在 cmets 中)要求您提供从 API 返回的实际 JSON 时,您提供的是以下内容:

{
    "Data": [[{
                "Käyttäjä": "Timo Kaisla"
            }, {
                "Kustannuspaikka": "5150014"
            }, {
                "Henkilö nro": "49417"
            }
        ]]
}

这不起作用。你可能会明白为什么。您最初提供的 JSON 和实际的 JSON 不一样。现在我可以看到两组 JSON,这完全可以理解为什么实际的 JSON 可以序列化为字典而不是键值对。

下面的代码会从您从 API 调用返回的 JSON 中为您获取 List&lt;KeyValuePair&lt;string, string&gt;&gt;

public class MyData
{
    public List<List<Dictionary<string, string>>> Data {get; set;}
}

static void Main()
{
    // Using your actual JSON from the api:
    string data = "{\"Data\": [[{\"Käyttäjä\": \"Timo Kaisla\" },{\"Kustannuspaikka\": \"5150014\"},{\"Henkilö nro\": \"49417\"}]]}";

    // Deserialize to MyData
    MyData myData = JsonConvert.DeserializeObject<MyData>(data);

    // Extract the inner List to a List<Dictionary>
    List<Dictionary<string, string>> dictionary = myData.Data[0];

    // Create our finished object
    List<KeyValuePair<string, string>> keyvaluepairs = new List<KeyValuePair<string, string>>();

    // Loop over the List<Dictionary> and convert to List<KeyValuePair<>>
    foreach (var x in dictionary)
    {
        var key = x.ToList()[0].Key;
        var value = x.ToList()[0].Value;
        KeyValuePair<string, string> keyvaluepair = new KeyValuePair<string, string>(key, value);
        keyvaluepairs.Add(keyvaluepair);
    }            
}

到此代码完成时,keyvaluepairs 将拥有您正在寻找的 List&lt;KeyValuePair&lt;string, string&gt;&gt;

当然有一种更简单的方法可以做到这一点(使用 LINQ),但这会将其分解,以便您可以看到正在发生的事情。

【讨论】:

    【解决方案2】:

    这可能是一个显而易见的解决方案,但您是否考虑过使用在线 JSON 到 C Sharp 转换器,例如 https://app.quicktype.io

    我决定试一试,得到了这个非常简单的类文件。

    namespace YourProjectName
    {
        using System;
        using System.Collections.Generic;
    
        using System.Globalization;
        using Newtonsoft.Json;
        using Newtonsoft.Json.Converters;
    
        public partial class Temperatures
        {
            [JsonProperty("Data")]
            public List<List<Datum>> Data { get; set; }
        }
    
        public partial class Datum
        {
            [JsonProperty("Key")]
            public string Key { get; set; }
    
            [JsonProperty("Value")]
            public string Value { get; set; }
        }
    
        public partial class Temperatures
        {
            public static Temperatures FromJson(string json) => JsonConvert.DeserializeObject<Temperatures>(json, YourProjectName.Converter.Settings);
        }
    
        public static class Serialize
        {
            public static string ToJson(this Temperatures self) => JsonConvert.SerializeObject(self, YourProjectName.Converter.Settings);
        }
    
        internal static class Converter
        {
            public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
            {
                MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
                DateParseHandling = DateParseHandling.None,
                Converters =
                {
                    new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
                },
            };
        }
    }
    

    一旦您将它包含在项目的文件中,您就可以像这样简单地使用它。

    using YourProjectName;
    
    var temperatures = Temperatures.FromJson(jsonString);
    

    使其更符合您的代码。

    public async Task<MyData> GetDataAsync()
    { 
        var response = await _httpClient.GetAsync("apiURL");
    
        if (response.StatusCode == HttpStatusCode.OK)
        {
            string result = await response.Content.ReadAsStringAsync();
            var data = Temperatures.FromJson(result );
           return data
        }
    
        return new MyData();
    }
    

    【讨论】:

      猜你喜欢
      • 2017-05-21
      • 2018-10-06
      • 2021-06-14
      • 2015-06-07
      • 1970-01-01
      • 2018-01-09
      • 2014-02-08
      • 1970-01-01
      • 2017-02-28
      相关资源
      最近更新 更多