C#从JSON反序列化KeyValuePair

dgenwo3n  于 2023-04-22  发布在  C#
关注(0)|答案(5)|浏览(245)

这是this question的绝对最简单版本(它的子集)。

using System;
using System.Collections.Generic;
using System.Text.Json;

public class Program
{
    public class Subscription
    {
        public bool HasRead { get; set; } = true;
        public string TimeStamp { get; set; } = "";
    }


    public static void Main()
    {
        // this input format is a requirement. It cannot be changed.
        string json = @"
          {
            ""305FDF11-25E7-43DE-B09D-DFFC17C79599"": {
              ""hasRead"": true, // EDIT: Removed the double quotes around the boolean. That was not the core issue.
              ""Timestamp"": ""XXX""
            }
          }
        ";

        // I'm trying to find the correct deserialization type in C#
        var deser = JsonSerializer.Deserialize<KeyValuePair<string, Subscription>>(json,
            new JsonSerializerOptions(JsonSerializerDefaults.Web));

        // System.Text.Json.JsonException: 
        //'The JSON value could not be converted to 
        //System.Collections.Generic.KeyValuePair
    }
}

我不明白为什么不能反序列化。
注意:我对KeyValuePair类型很感兴趣,但也许它与字段的大小写或其他明显的东西有关。
其他注意事项:当我将KeyValuePair<string, Subscription>更改为KeyValuePair<string, object>以使其更宽松时,它仍然失败。

3qpi33ja

3qpi33ja1#

首先,您的JSON不符合KeyValuePair<string, Subscription>的默认序列化,我建议将类型切换为Dictionary<string, Subscription>。此外,默认JSON反序列化器无法反序列化您的JSON。我建议使用Newtonsoft.Json

using Newtonsoft.Json;

string json = @"
          {
            ""305FDF11-25E7-43DE-B09D-DFFC17C79599"": {
              ""hasRead"": ""true"",
              ""Timestamp"": ""XXX""
            }
          }
        ";

var deserialized = JsonConvert.DeserializeObject<Dictionary<string, Subscription>>(json);
var subscription = deserialized["305FDF11-25E7-43DE-B09D-DFFC17C79599"];
Console.WriteLine($"Subscription timestamp is {subscription.TimeStamp}");

像这样,你会得到Subscription timestamp is XXX的输出。

nfg76nw0

nfg76nw02#

你有两个问题。
(1)

string json = @"
      {
        ""305FDF11-25E7-43DE-B09D-DFFC17C79599"": {
          ""hasRead"": ""true"",
          ""Timestamp"": ""XXX""
        }
      }
    ";

true被引号包围。默认情况下,它不会反序列化为布尔值,而是字符串。您可以在Subscription类中更改HasRead的类型来解决这个问题。如果您想要一个布尔值属性,那么您可以添加如下内容:

public bool HasReadBool => bool.Parse(HasRead);

您不能直接反序列化为KeyValuePair,因为它具有命名的KeyValue属性。相反,您可以反序列化为Dictionary

var deser = JsonSerializer.Deserialize<Dictionary<string, Subscription>>(json,
        new JsonSerializerOptions(JsonSerializerDefaults.Web));

如果你想得到一个KeyValuePair,你可以这样做:var kvp = deser.First()

pbwdgjma

pbwdgjma3#

我们可以使用类型**Dictionary〈String,Subscription〉**来实现。

using System.Text.Json;

class JsonTest
{
    public class Subscription
    {
        public bool HasRead { get; set; } = true;
        public string TimeStamp { get; set; } = "";
    }
    public static void Main()
    {
        string json = @"
             {
                 ""305FDF11-25E7-43DE-B09D-DFFC17C79599"": {
                      ""hasRead"": ""true"",
                      ""TimeStamp"": ""XXX""
                  }
             }
             ";

        var deser = JsonSerializer.Deserialize<Dictionary<string, Subscription>>(json);
        foreach(var key in deser.Keys)
        {
            Subscription subscription = deser[key];
            Console.WriteLine($"Key:{key} HasRead:{subscription.HasRead} TimeStamp:{subscription.TimeStamp}");
        }
    }
}

我尝试打印所有值。输出为:-

Key:305FDF11-25E7-43DE-B09D-DFFC17C79599 HasRead:True TimeStamp:XXX

注意:-我们应该尝试在json和类属性中匹配大小写。否则,我们将获得null/default值。我已经将JSON字符串中的Timestamp修改为TimeStamp

hmae6n7t

hmae6n7t4#

using System;
using System.Collections.Generic;
using System.Text.Json;

public class Program
{
    public class Subscription
    {
        public bool HasRead { get; set; } = true;
        public string TimeStamp { get; set; } = "";
    }

    public static void Main()
    {
        // this input format is a requirement. It cannot be changed.
        string json = @"
          {
            ""305FDF11-25E7-43DE-B09D-DFFC17C79599"": {
              ""hasRead"": ""true"",
              ""Timestamp"": ""XXX""
            }
          }
        ";

        // deserialize the JSON string into a dictionary
        var dict = JsonSerializer.Deserialize<Dictionary<string, Subscription>>(json,
            new JsonSerializerOptions(JsonSerializerDefaults.Web));

        // iterate over the dictionary and print each key-value pair
        foreach (var kvp in dict)
        {
            Console.WriteLine($"Key: {kvp.Key}");
            Console.WriteLine($"HasRead: {kvp.Value.HasRead}");
            Console.WriteLine($"TimeStamp: {kvp.Value.TimeStamp}");
        }
    }
}
mftmpeh8

mftmpeh85#

KeyValuePair〈string,Subscription〉类型的默认序列化如下所示:

{
    "key":
      "305FDF11-25E7-43DE-B09D-DFFC17C79599",
    "value":{
     "hasRead":true,
     "timeStamp":"XXX"
    }
}

要改变这种行为,你需要编写你自己的转换器,从JsonConverter类派生。还要注意,true值应该不带引号。

相关问题