Deserialize JSON into different elements based on the content of the element


Andrew

I'm trying to parse a JSON file into different items, the JSON file contains items with the following sample content:

{
    "PM00000001": { "description": "Manufacturing","cost": -1,"group":"Manufacturing","WeldAngleDegrees": 60},
    "PM00000010": {"description": "Plate Roll","cost": 90,"unit": "hr","group": "Roll","setup": 0.5,"speed": 0.4},
    "PM00000011": {"description": "Weld SAW","cost": 90,"unit": "hr","group": "Weld","width": 0.5,"thickness": 50}
}

Each item has a description, cost and group. The rest of the properties depend on the group. In the example above, the manufacture has "WeldAngleDegrees", the roll has the setupsum speed, and the weld has the widthsum thickness.

I am trying to parse this file using JSON.NET.

Right now I am doing this:

string text = System.IO.File.ReadAllText(ofd.FileName);
Dictionary<string, Item> deserializedProduct = JsonConvert.DeserializeObject<Dictionary<string, Item>>(text, new ItemConverter());

and

public class Item
{
    public string description { get; set; }
    public double cost { get; set; }
    public string group { get; set; }
}

public class ManufacturingItem : Item
{
    public string WeldAngleDegrees { get; set; }
}

public class ItemConverter : CustomCreationConverter<Item>
{
    public override Item Create(Type objectType)
    {
        return new ManufacturingItem();
    }
}

Is there a way to ItemConverterfigure out which "group" the item belongs to to create the correct item type?

Is there an easier way to do this?

Brian Rogers

Instead, you get ItemConverterfrom CustomCreationConverter<T>, and from produces it JsonConverter; then you will be able to access the JSON through the reader. You can load the object data into JObjectand then inspect groupthe properties to determine which class to create. The code looks like this:

public class ItemConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Item);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        string group = (string)jo["group"];
        if (group == "Manufacturing")
        {
            return jo.ToObject<ManufacturingItem>();
        }
        else if (group == "Roll")
        {
            return jo.ToObject<RollItem>();
        }
        else if (group == "Weld")
        {
            return jo.ToObject<WeldItem>();
        }
        throw new JsonSerializationException("Unexpected item (group) type");
    }

    public override bool CanWrite
    {
        get { return false; }
    }

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

Fiddle : https://dotnetfiddle.net/8ZIubu _

Related


Remove elements based on element content?

bad thing df.cleaned <- df[-which(str_detect(df, "Not found")),] "df" refers to a data frame consisting of multiple columns and rows. Many elements in this data frame have certain words in them. What I'm trying to do is remove all values that contain the word

Remove elements based on element content?

bad thing df.cleaned <- df[-which(str_detect(df, "Not found")),] "df" refers to a data frame consisting of multiple columns and rows. Many elements in this data frame have certain words in them. What I'm trying to do is remove all values that contain the word

Remove elements based on element content?

bad thing df.cleaned <- df[-which(str_detect(df, "Not found")),] "df" refers to a data frame consisting of multiple columns and rows. Many elements in this data frame have certain words in them. What I'm trying to do is remove all values that contain the word

Remove elements based on element content?

bad thing df.cleaned <- df[-which(str_detect(df, "Not found")),] "df" refers to a data frame consisting of multiple columns and rows. Many elements in this data frame have certain words in them. What I'm trying to do is remove all values that contain the word

Remove elements based on element content?

bad thing df.cleaned <- df[-which(str_detect(df, "Not found")),] "df" refers to a data frame consisting of multiple columns and rows. Many elements in this data frame have certain words in them. What I'm trying to do is remove all values that contain the word

Remove elements based on element content?

bad thing df.cleaned <- df[-which(str_detect(df, "Not found")),] "df" refers to a data frame consisting of multiple columns and rows. Many elements in this data frame have certain words in them. What I'm trying to do is remove all values that contain the word

Remove elements based on element content?

bad thing df.cleaned <- df[-which(str_detect(df, "Not found")),] "df" refers to a data frame consisting of multiple columns and rows. Many elements in this data frame have certain words in them. What I want to do is remove all values that contain the word "no

Remove elements based on element content?

bad thing df.cleaned <- df[-which(str_detect(df, "Not found")),] "df" refers to a data frame consisting of multiple columns and rows. Many elements in this data frame have certain words in them. What I want to do is remove all values that contain the word "no

Remove elements based on element content?

bad thing df.cleaned <- df[-which(str_detect(df, "Not found")),] "df" refers to a data frame consisting of multiple columns and rows. Many elements in this data frame have certain words in them. What I want to do is remove all values that contain the word "no

Remove elements based on element content?

bad thing df.cleaned <- df[-which(str_detect(df, "Not found")),] "df" refers to a data frame consisting of multiple columns and rows. Many elements in this data frame have certain words in them. What I want to do is remove all values that contain the word "no

Remove elements based on element content?

bad thing df.cleaned <- df[-which(str_detect(df, "Not found")),] "df" refers to a data frame consisting of multiple columns and rows. Many elements in this data frame have certain words in them. What I want to do is remove all values that contain the word "no

Dynamically deserialize JSON to content-based derived type?

mr floria In a small library I wrote as a side project, I use RestSharp to get Json from a Web API. Deserializing to model classes works fine for simple types, but some endpoints generate unknown (or unclear) types at request time. Specifically its GuildWars2

Dynamically deserialize JSON to content-based derived type?

mr floria In a small library I wrote as a side project, I use RestSharp to get Json from a Web API. Deserializing to model classes works fine for simple types, but some endpoints generate unknown (or unclear) types at request time. Specifically its GuildWars2

Unable to deserialize JSON content

Antony.ouseph.k I have seen a lot of similar questions on stack overflow. However, it didn't help much. I'm having trouble deserializing JSON. Details are as follows: JSON content { "TicketDetails": { "General": { "TicketingCity": "DEL",

Deserialize JSON with irregular content

mental illness I have the following example where 2 "unusual" things can happen: If the state is NOK, the element datawill not be included at all Some attributes of inner elements listmay be missing (in the example below, key2missing in the second element of l

Deserialize JSON with irregular content

mental illness I have the following example where 2 "unusual" things can happen: If the state is NOK, the element datawill not be included at all Some attributes of inner elements listmay be missing (in the example below, key2missing in the second element of l

Deserialize JSON with irregular content

mental illness I have the following example where 2 "unusual" things can happen: If the state is NOK, the element datawill not be included at all Some attributes of inner elements listmay be missing (in the example below, key2missing in the second element of l