英文:
C# deserialize KeyValuePair from JSON
问题
这是问题的绝对最简版本之一(其中的一个子集)。
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""
}
}";
// 我试图找到在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
}
英文:
This is the absolute simplest version of this question (a subset of it).
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
}
}
I can't understand why that can't be deserialized.
Note: I'm obsessing over the KeyValuePair
type but maybe it has to do with the casing of the fields or something else obvious.
Other note : It still fails when I change KeyValuePair<string, Subscription>
to KeyValuePair<string, object>
to make it more permissive.
答案1
得分: 1
首先,你的 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}");
英文:
First of all, your JSON does not conform to default serialization of KeyValuePair<string, Subscription>
, I'd recommend switching the type to Dictionary<string, Subscription>
. As well, default JSON deserializer is unable to deserialize your JSON. I'd recommend using 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}");
Like this you'd get output of Subscription timestamp is XXX
.
答案2
得分: 1
你有两个问题。
public bool HasReadBool => bool.Parse(HasRead);
var deser = JsonSerializer.Deserialize<Dictionary<string, Subscription>>(json, new JsonSerializerOptions(JsonSerializerDefaults.Web));
var kvp = deser.First();
英文:
You have two issues.
string json = @"
{
""305FDF11-25E7-43DE-B09D-DFFC17C79599"": {
""hasRead"": ""true"",
""Timestamp"": ""XXX""
}
}
";
true
is surrounded by quotes. By default that will not deserialise to a boolean but a string. You can change the type of HasRead
in the Subscription
class to fix the issue. If you want a boolean property then you could add something like:
public bool HasReadBool => bool.Parse(HasRead);
2)
You cannot deserialise directly to a KeyValuePair
as that has named Key
and Value
properties. Instead you can deserialise to a Dictionary
:
var deser = JsonSerializer.Deserialize<Dictionary<string, Subscription>>(json,
new JsonSerializerOptions(JsonSerializerDefaults.Web));
If you want to get a KeyValuePair
you can do this: var kvp = deser.First()
答案3
得分: 1
以下是您提供的代码的中文翻译:
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()
{
// 此输入格式是必需的,不能更改。
string json = @"
{
""305FDF11-25E7-43DE-B09D-DFFC17C79599"": {
""hasRead"": ""true"",
""Timestamp"": ""XXX""
}
}
";
// 反序列化JSON字符串为字典
var dict = JsonSerializer.Deserialize<Dictionary<string, Subscription>>(json,
new JsonSerializerOptions(JsonSerializerDefaults.Web));
// 遍历字典并打印每个键值对
foreach (var kvp in dict)
{
Console.WriteLine($"Key: {kvp.Key}");
Console.WriteLine($"HasRead: {kvp.Value.HasRead}");
Console.WriteLine($"TimeStamp: {kvp.Value.TimeStamp}");
}
}
}
希望这有助于您理解代码的中文翻译。
英文:
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}");
}
}
}
答案4
得分: 1
We can use type Dictionary<String,Subscription> to achieve it.
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}");
}
}
}
I tried to print all values.
Output is: -
Key:305FDF11-25E7-43DE-B09D-DFFC17C79599 HasRead:True TimeStamp:XXX
Note: - We should try to match case in JSON and class properties. Else, we will get null/default values. I have modified Timestamp to TimeStamp in JSON string.
英文:
We can use type Dictionary<String,Subscription> to achieve it.
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}");
}
}
}
I tried to print all values.
Output is :-
Key:305FDF11-25E7-43DE-B09D-DFFC17C79599 HasRead:True TimeStamp:XXX
Note :- We should try to match case in json and class properties. Else, We will get null/default values. I have modified Timestamp to TimeStamp in JSON string.
答案5
得分: -1
The default serialization of type KeyValuePair<string, Subscription> looks like this:
{
"key": "305FDF11-25E7-43DE-B09D-DFFC17C79599",
"value":{
"hasRead":true,
"timeStamp":"XXX"
}
}
To change this behavior, you need to write your own converter derived from JsonConverter class.
Also note that true value should be without quotes.
英文:
The default serialization of type KeyValuePair<string, Subscription> looks like this:
{
"key":
"305FDF11-25E7-43DE-B09D-DFFC17C79599",
"value":{
"hasRead":true,
"timeStamp":"XXX"
}
}
To change this behavior you need to write your own converter derrived from JsonConverter class.
Also note that true value should be without quotes.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论