1

I am deserializing some JSON endpoints to C# Objects via JArray.Parse() and have come across a schema I'm not sure how to handle. The nUnavailResReasonsMap Object below has a dynamic number of name/value pairs; all of the name values will be integers:

{
    "id": "Customer Service",
    "operation": "UPDATE",
    "VoiceIAQStats": {
        "id": 139,
        "esdId": 139,
        ...
        "nUnavailResources": 2,
        "nUnavailResReasonsMap": {
            "4": 1,
            "9": 1
        },
        "nWorkResources": 0,
        "nSelectedResources": 0,
        ...
        "nSLAPercentageHighThreshold": 0
    }
}

And here are my C# Objects:

//Root Level
public class QueueStats
{
    public string Id { get; set; }
    public string Operation { get; set; }
    public VoiceIaqStats VoiceIaqStats { get ; set ; }
}

public class VoiceIaqStats
{
    public int Id { get; set; }
    public int EsdId { get; set; }
    ...
    public int NUnavailResources { get; set; }
    public NUnavailResReasonsMaps NUnavailResReasonsMap { get ; set ; }
    public int NWorkResources { get; set; }
    public int NSelectedResources { get; set; }
    ...
    public int NSlaPercentageHighThreshold { get; set; }
}

[JsonConverter( typeof( QueueStatsConverter))]
public class NUnavailResReasonsMaps
{
    public Dictionary<string ,int > NUnavailResReasonsMap { get; set; }
}

Per another SO Post, I have setup the below Json Converter, which is getting called but I'm not sure how to get the values into the Dictionary defined above.

public class QueueStatsConverter : JsonConverter
{
    public override bool CanConvert( Type objectType)
    {
        return objectType.IsClass;
    }

    public override bool CanWrite => false;

    public override object ReadJson( JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var instance = objectType.GetConstructor(Type .EmptyTypes)?.Invoke(null);
        var props = objectType.GetProperties();

        var jo = JObject.Load(reader);
        foreach ( var jp in jo.Properties())
        {
            //I can see the properties, but how do I add them to my existing dictionary?
        }
        return instance;
    }

    public override void WriteJson( JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

Is there a way to make this work or do I need to change my approach?

faheem khan
  • 471
  • 1
  • 7
  • 33
slashNburn
  • 464
  • 4
  • 17
  • 3
    Is there a reason that NUnavailResReasonsMaps even needs to exist? It seems like you could just put the dictionary itself into VoiceIaqStats – Dan Dec 28 '17 at 18:24
  • 1
    Put the dictionary directly inside `VoiceIaqStats` like so: `public class VoiceIaqStats { public Dictionary NUnavailResReasonsMap { get ; set ; } ... }` should just work. See [Create a strongly typed c# object from json object with ID as the name](https://stackoverflow.com/q/34213566/3744182) or [How can I parse a JSON string that would cause illegal C# identifiers?](https://stackoverflow.com/q/24536533/3744182). – dbc Dec 28 '17 at 18:25
  • Yep - that did it, thank you for the help. – slashNburn Dec 28 '17 at 18:49

1 Answers1

1

You don't need a special converter at all, just remove the NUnavailResReasonsMaps class and use a Dictionary<int, int> instead:

public class VoiceIaqStats
{
    //snip
    public Dictionary<int, int> NUnavailResReasonsMap { get; set; }
    //snip
}

And the conversion will work out of the box:

var result = JsonConvert.DeserializeObject<QueueStats>(json);
DavidG
  • 113,891
  • 12
  • 217
  • 223