从 Json C# 中反序列化嵌套字典
Deserialize Nested Dictionary in from Json C#
我有一个 class 像这样的东西
public class A{
public Guid userId { get; set; }
public Guid businessId { get; set; }
public Dictionary<int, long> rights { get; set; }
}
我想将这个 json 转换为 class
{
"userId": "dc2af693-72e1-49a7-80aa-6416c6536bdf",
"businessId": "0110eea4-7a47-4a7c-95ea-10547ab49652",
"rights": "{\"19\":1,\"17\":15,\"18\":1,\"23\":1,\"1\":31,\"20\":3,\"3\":1,\"16\":0}",
}
但是当我试图用 NewtonSoft.Json
转换它时
JsonConvert.DeserializeObject<A>(json);
我收到以下错误 无法将 System.string 转换为 System.Dictionary
发生的事情是我的权利被转换为类似这样的字符串
"{"19":1, "17":15, "18":1, ..., "16":0}"
如果我再次反序列化这个字符串,它会如我所愿地工作,有没有更好的方法来做到这一点。
由于 rights
是字符串格式,您可以添加自定义 JsonConverter
将字符串转换为字典
public class A
{
public Guid userId { get; set; }
public Guid businessId { get; set; }
[JsonConverter(typeof(RightsSerializer))]
public Dictionary<int, long> rights { get; set; }
}
这是 RightsSerializer
public class RightsSerializer : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Dictionary<int, long>);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null) return null;
var jt = JToken.Load(reader);
return JsonConvert.DeserializeObject<Dictionary<int, long>>(jt.Value<String>());
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
}
和 DeserializeObject
var json = File.ReadAllText("json1.json");
var result = JsonConvert.DeserializeObject<A>(json);
将 class 更改为这样的内容会有所帮助。尽管您需要使代码比这更好。
public class A
{
public Guid userId { get; set; }
public Guid businessId { get; set; }
//[JsonConverter(typeof(Dictionary<int, long>))]
public string rights { get; set; }
public Dictionary<int, long> rightss => JsonConvert.DeserializeObject<Dictionary<int, long>>(rights);
}
你不能不反序列化两次,但你可以用私有子类隐藏它。
public class A {
public Guid userId {get;set;}
public Guid businessId {get;set;}
public Dictionary<int, long> rights {get;set;}
private class B {
public Guid userId {get;set;}
public Guid businessId {get;set;}
public string rights {get;set;}
}
private B b;
public A (string json) {
var o = new JsonSerializerOptions();
o.AllowTrailingCommas = true;
b = JsonSerializer.Deserialize<B>(json, o);
userId = b.userId;
businessId = b.businessId;
rights = JsonSerializer.Deserialize<Dictionary<int, long>>(b.rights,o);
}
}
fiddle中测试的用法:
我有一个 class 像这样的东西
public class A{
public Guid userId { get; set; }
public Guid businessId { get; set; }
public Dictionary<int, long> rights { get; set; }
}
我想将这个 json 转换为 class
{
"userId": "dc2af693-72e1-49a7-80aa-6416c6536bdf",
"businessId": "0110eea4-7a47-4a7c-95ea-10547ab49652",
"rights": "{\"19\":1,\"17\":15,\"18\":1,\"23\":1,\"1\":31,\"20\":3,\"3\":1,\"16\":0}",
}
但是当我试图用 NewtonSoft.Json
转换它时JsonConvert.DeserializeObject<A>(json);
我收到以下错误 无法将 System.string 转换为 System.Dictionary
"{"19":1, "17":15, "18":1, ..., "16":0}"
如果我再次反序列化这个字符串,它会如我所愿地工作,有没有更好的方法来做到这一点。
由于 rights
是字符串格式,您可以添加自定义 JsonConverter
将字符串转换为字典
public class A
{
public Guid userId { get; set; }
public Guid businessId { get; set; }
[JsonConverter(typeof(RightsSerializer))]
public Dictionary<int, long> rights { get; set; }
}
这是 RightsSerializer
public class RightsSerializer : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Dictionary<int, long>);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null) return null;
var jt = JToken.Load(reader);
return JsonConvert.DeserializeObject<Dictionary<int, long>>(jt.Value<String>());
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
}
和 DeserializeObject
var json = File.ReadAllText("json1.json");
var result = JsonConvert.DeserializeObject<A>(json);
将 class 更改为这样的内容会有所帮助。尽管您需要使代码比这更好。
public class A
{
public Guid userId { get; set; }
public Guid businessId { get; set; }
//[JsonConverter(typeof(Dictionary<int, long>))]
public string rights { get; set; }
public Dictionary<int, long> rightss => JsonConvert.DeserializeObject<Dictionary<int, long>>(rights);
}
你不能不反序列化两次,但你可以用私有子类隐藏它。
public class A {
public Guid userId {get;set;}
public Guid businessId {get;set;}
public Dictionary<int, long> rights {get;set;}
private class B {
public Guid userId {get;set;}
public Guid businessId {get;set;}
public string rights {get;set;}
}
private B b;
public A (string json) {
var o = new JsonSerializerOptions();
o.AllowTrailingCommas = true;
b = JsonSerializer.Deserialize<B>(json, o);
userId = b.userId;
businessId = b.businessId;
rights = JsonSerializer.Deserialize<Dictionary<int, long>>(b.rights,o);
}
}
fiddle中测试的用法: