簡體   English   中英

反序列化來自 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);

我收到以下錯誤Cannot Cast System.string to System.Dictionary<int,long>發生的事情是我的權利被轉換為類似這樣的字符串

"{"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);
    }
}

和反序列化對象

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);
   }
}

小提琴測試的用法:

小提琴

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM