HeisenBerg HeisenBerg - 1 year ago 76
JSON Question

C# deserialize Json based on condition

{
"timeAgo": "6 minutes ago",
"time": "07/11/2016 07:00 AM",
"alertId": 145928,
"details": {


},
"priority": 10,
"type": 2,
"isClosed": 0,
"notesCount": 0,
"patientAccountId": 680,
"isRead": 0
}


I want to deserialize the json based on the int value 'type', in such as way, I want the details to be different types

public class Notification
{
public string timeAgo { get; set; }
public string time { get; set; }
public int alertId { get; set; }
public object details { get; set; }
public int priority { get; set; }
public int type { get; set; }
public int isClosed { get; set; }
public int notesCount { get; set; }
public int patientAccountId { get; set; }
public int isRead { get; set; }
}


if type = 1, then the object 'details' is of type A, if type = 2, 'details' is of type B and so on. There are about 25 values for type.

So, later I can do something like:

Notification n = ....
if (type == 1)
{
A a = (a) n.details;

Jim Jim
Answer Source

If your json does not have appropriate typing included in the JSON, this will work.

This may need tweaking if your actual structure is more complex, but I managed to get this to work on your sample.

var instance = Newtonsoft.Json.JsonConvert.DeserializeObject<Notification>(
    js,
    new ItemConverter());

public class ItemA : Item { }
public class ItemB : Item { }
public class Item { }

public class Notification
{
    public string timeAgo { get; set; }
    public string time { get; set; }
    public int alertId { get; set; }
    public Item details { get; set; }
    public int priority { get; set; }
    public int type { get; set; }
    public int isClosed { get; set; }
    public int notesCount { get; set; }
    public int patientAccountId { get; set; }
    public int isRead { get; set; }
}

public class ItemConverter : JsonConverter
{
    private Type currentType;
    public override bool CanConvert(Type objectType)
    {
        return typeof(Item).IsAssignableFrom(objectType) || objectType == typeof(Notification);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject item = JObject.Load(reader);
        if (item["type"] != null)
        {
            // save the type for later.
            switch (item["type"].Value<int>())
            {
                case 1:
                    currentType = typeof(ItemA);
                    break;
                default:
                    currentType = typeof(ItemB);
                    break;
            }
            return item.ToObject<Notification>();
        }

        // use the last type you read to serialise.
        return item.ToObject(currentType);
    }

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