Search code examples
c#jsonjson.net

JSON Deserialise where part is like a dictionary


I have JSON coming from an API that looks like this:

{
    "GetJsonResult": {
        "EntityName": "account",
        "FailureReason": "",
        "Counter": 0,
        "MoreRecords": false,
        "OptionSetName": "sic_organisationtitlewad",
        "Success": true,
        "OptionSetsClean": "[{\"Mr\":100000000},{\"Mrs\":100000003},{\"Miss\":100000002},{\"Ms\":100000004},{\"Prof\":100000001},{\"Sir\":907510000}]",
        "OptionSets": [
            {
                "Mr": 100000000
            },
            {
                "Mrs": 100000003
            },
            {
                "Miss": 100000002
            },
            {
                "Ms": 100000004
            },
            {
                "Prof": 100000001
            },
            {
                "Sir": 907510000
            }
        ],
        "Entities": null
    }
}

I have a class definition like this:

public class GetJsonResult
{
    [JsonProperty("EntityName")]
    public string EntityName { get; set; }

    [JsonProperty("FailureReason")]
    public string FailureReason { get; set; }

    [JsonProperty("Counter")]
    public int Counter { get; set; }

    [JsonProperty("MoreRecords")]
    public bool MoreRecords { get; set; }

    [JsonProperty("OptionSetName")]
    public string? OptionSetName { get; set; }

    [JsonProperty("Success")]
    public bool Success { get; set; }

    [JsonProperty("OptionSetsClean")]
    public Dictionary<string, int>? OptionSetsClean { get; set; }

    [JsonProperty("OptionSets")]
    public object OptionSets { get; set; }

}

And use "JsonConvert.DeserializeObject" to process the data.

I want to get the data in "OptionSetsClean" or in "OptionSets" (they contain the same data) to be converted to something like a Dictionary or List. However, I can't figure a way of doing that.


Solution

  • as an option you can have a custom converter to convert to dictionary and parce string

    void Main()
    {
        var j = File.ReadAllText("C:\\1\\test.json");
        //you can get directly your object bypassing JsonConvert
        GetJsonResult obj =JObject.Parse(j).SelectToken("GetJsonResult").ToObject<GetJsonResult>();
        //or deserialize this way
        var x = JsonConvert.DeserializeObject<Root>(j).Dump();
    }
    
    public class Root
    {
        public GetJsonResult GetJsonResult { get; set; }
    }
    
    public class GetJsonResult
    {
        public string EntityName { get; set; }
        public string FailureReason { get; set; }
        public int Counter { get; set; }
        public bool MoreRecords { get; set; }
        public string OptionSetName { get; set; }
        public bool Success { get; set; }
        [JsonConverter(typeof(StringConverter<string>))]
        public Dictionary<string, Int64> OptionSetsClean { get; set; }
        [JsonConverter(typeof(DictionaryConverter<JArray>))]
        public Dictionary<string, Int64> OptionSets { get; set; }
        public string Entities { get; set; }
    
    }
    
    public class DictionaryConverter<T> : JsonConverter
    {
        public override bool CanConvert(Type objectType) => typeof(T) == objectType;
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var res = new Dictionary<string, Int64>();
            var ja = JArray.Load(reader);
            res = ja.ToDictionary(k=>((JObject)k).Properties().First().Name, v=> v.Values().First().Value<long>());
            return res;
        }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
    
    public class StringConverter<T> : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return true;
        }
        public override bool CanRead { get { return true; } }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var dict = new Dictionary<string, Int64>();
    
            var s = JArray.Parse(reader.Value.ToString()).ToObject<IEnumerable<Dictionary<string, Int64>>>();
            s.ToList().ForEach(d =>
            {
                dict.Add(d.FirstOrDefault().Key, d.FirstOrDefault().Value);
            });
            return dict;
    
        }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
    
    

    result :

    enter image description here