0

I have to deserialize a JSON string to C# classes inorder to bind to a grid. I have implemented the respective classes in C#. But at a particular instance, this fails because the JSON property will be either an array or an object. Please check a part of the string.

I have created ItemList class with 3 properties IL1 , Name and another object class "Item". However, you can see that when the property "Name" is Rubber, I should have List of Item class as a property rather than Item object. When it is Rubber, it returns array of 2 items.

 "ItemList": [
{
  "@IL1": "Yes",
  "@Name": "Pencil"
  "Item": {
    "@ItemType": "Pencil",
    "@Item2": "1A7716744F7048ACA2549BE93F0A2BF1",        
    "aimLink": {
      "@id": "1A7716744F7048ACA2549BE93F0A2BF1",
      "@DisplayText": "P00001"         
    }
  }
},
{
  "@IL1": "Yes",
  "@Name": "Pen",    
  "Item": {
    "@ItemType": "Pen",
    "@Item2": "AE067F7EDB6147C09AED243C1F7FAD25",        
    "aimLink": {
      "@id": "AE067F7EDB6147C09AED243C1F7FAD25",
      "@DisplayText": "5100010654120001
    }
  }
},
{
  "@IL1": "Yes",
  "@Name": "Rubber",     
  "Item": [
    {
      "@ItemType": "Rubber",
      "@ItemGID": "622025629037499394DF092DA16BAB7F",          
      "aimLink": {
        "@id": "622025629037499394DF092DA16BAB7F",
        "@DisplayText": "12345678-1234-123456-7116#01"
      }
    },
    {
      "@ItemType": "Rubber",
      "@ItemGID": "F336F65F8E014E80B84A2312F829493C"
      "aimLink": {
        "@id": "F336F65F8E014E80B84A2312F829493C",
        "@DisplayText": "12345678-1234-123456-7116#14"
      }
    }
  ]
}
 ],

How can I parse this to a C# class effectively and the easiest way to get this done?

Thanks, Divya

3
  • 1
    The best thing to do is to fix the JSON so that it is unambiguous. Commented Mar 18, 2021 at 14:16
  • if its the same object coming single or collection then its possible, you can check if jobject then deserialize to object otherwise to list or array Commented Mar 18, 2021 at 14:32
  • What serializer are you using? Newtonsoft.Json (a.k.a. Json.Net)? Commented Mar 18, 2021 at 20:17

2 Answers 2

2

You can resolve this issue by making your custom JsonConverter and you can use below to convert single value to array then mark Item property with the JsonConverter attribute

public class SingleValueArrayConverter<T> : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }



    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        object retVal = new Object();
        if (reader.TokenType == JsonToken.StartObject)
        {
            T instance = (T)serializer.Deserialize(reader, typeof(T));
            retVal = new List<T>() { instance };
        }
        else if (reader.TokenType == JsonToken.StartArray)
        {
            retVal = serializer.Deserialize(reader, objectType);
        }
        return retVal;
    }

    public override bool CanConvert(Type objectType)
    {
        return false;
    }
}

let's assume this your ItemList class

public class ItemList
{
    public string @IL1 { get; set; }
    public string @Name { get; set; }
    [JsonConverter(typeof(SingleValueArrayConverter<Item>))]
    public List<Item> Item { get; set; }
}

public class Item
{
    public string @ItemType { get; set; }
    public string @Item2 { get; set; }
    public AimLink aimLink { get; set; }
}

public class AimLink
{
    public string @id { get; set; }
    public string @DisplayText { get; set; }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you Anas. That worked. I have 1 more clarification. I am deserializing using this code - JObject studentObj = JObject.Parse(jsonString); var res = JsonConvert.DeserializeObject<Archive>(jsonString); If my json string looks like this , how can I extract the Archive part only {"?xml":{"@version":"1.0","@encoding":"UTF-8"}, "?xml-stylesheet":"type=\"text/xsl\" href=\"./xslt/Archive.xslt\"", "Archive":{"@DateTimeCreated":"2021-03-08T18:17:31",.....................
make archive inside another class like that then var res = JsonConvert.DeserializeObject<Rootobject>(jsonString); public class Rootobject { public Archive Archive { get; set; } } public class Archive { public DateTime DateTimeCreated { get; set; } }
0

You can make your custom JsonConverter (e.g. ItemConverter) and mark Item property with the [JsonConverter(typeof(ItemConverter))] attribute

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.