将 JSON 反序列化为 List<List<KeyValuePair>> 结果为空

Posted

技术标签:

【中文标题】将 JSON 反序列化为 List<List<KeyValuePair>> 结果为空【英文标题】:Desrialize JSON into List<List<KeyValuePair>> result is null 【发布时间】: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 - 查看 实际上 是否代表您正在接收的数据的结构 创建一个对象,设置一些值,序列化为文本,然后看看你得到了什么。然后你可以找出不匹配的地方。比在 *** 上询问要快得多。或者只是在 Visual Studio 中使用“将 JSON 粘贴为类” 好的,感谢您的编辑。我无法重现您的问题。看看这个:dotnetfiddle.net/00vjcb 还要确保您使用的是 NewtonSoft。 System.Text.Json 有奇怪的失败模式,大部分时间都是沉默的。 【参考方案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();

【讨论】:

以上是关于将 JSON 反序列化为 List<List<KeyValuePair>> 结果为空的主要内容,如果未能解决你的问题,请参考以下文章

将 JSON 数组反序列化为 List<T> C# 时出错

如何将 JSON 反序列化为具有多个 List<T> 参数的 .NET 对象?

使用 Json.NET 将异构 JSON 数组反序列化为协变 List<>

Gson 将 List<String> 反序列化为 realmList<RealmString>

将 JSON 反序列化为对象

将 JSON 反序列化为对象