Search code examples
c#jsonconvert

Deserializing a JSON Array of size 1 in c#


I have two different JSON object which differ slightly for one property:

string JSONObject1 = "
{
prop1: val1
prop2: {
          prop3: val3
          prop4: val4
       }
}
"

string JSONObject2 = "
{
prop1: val1
prop2: [{
          prop3: val3
          prop4: val4
       }]
}
"

class MyObject
{
    string prop1 {get; set;}
    MyInnerObject prop2 {get; set;}
}

class MyInnerObject
{
    string prop3;
    string prop4;
}


JsonConvert.DeserializeObject<MyObject>(JSONObject1) // This works
JsonConvert.DeserializeObject<MyObject>(JSONObject2) // This does not work

How do I Deserialize JSONObject2, without adding new class or making modification to MyObject?


Solution

  • Updating my answer to provide a more dynamic and robust answer to this problem. The problems that were mentioned with the OP question became apparent to me when working on this solution but assuming that the following list of items are taken in account you could solve this problem with dynamic json.

    1. The json provided is not valid
    2. The classes provided are not serializable as they are not public
    3. The properties are also not serializable as they are also not public
    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.Runtime.Remoting;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace commandexample
    {
        class Program
        {
            static void Main(string[] args)
            {
                string JSONObject1 = @"
                {
                            prop1: ""val1"",
                            prop2: {
                                prop3: ""val3"",
                                prop4: ""val4""
                                   }
                }";
    
                string JSONObject2 = @"
                {
                            prop1: ""val1"",
                            prop2:[{
                                    prop3: ""val3"",
                                    prop4: ""val4""
                                  }]
                }";
    
    
                var dyn = JsonConvert.DeserializeObject<dynamic>(JSONObject2);
                if (dyn.prop2.GetType().Name == "JArray")
                {
                    dyn.prop2 = dyn.prop2[0];
                }
                string updatedJson = JsonConvert.SerializeObject(dyn);
    
                MyObject result1 = JsonConvert.DeserializeObject<MyObject>(JSONObject1);
                MyObject result2 = JsonConvert.DeserializeObject<MyObject>(updatedJson);
    
            }
            public class MyObject
            {
                public string prop1 { get; set; }
                public MyInnerObject prop2 { get; set; }
            }
    
            public class MyInnerObject
            {
                public string prop3;
                public string prop4;
            }
        }
    }
    

    Original post

    If you know that the array will always contain only one item and you only have one array in your json document you could just do a string replace on the json string for the square brackets. This would meet the conditions for your specific issue, but could cause issues if the document changes in the future to add additional array properties. Really depends on your use case.

    I could see this as being a data issue where a person is attempting to read a json document produced by two separate systems and one of the systems is not correctly creating the document.

    JSONObject2 = JSONObject2.Replace("[","").Replace("]","");
    
    //then continue with the Deserialization 
    JsonConvert.DeserializeObject<MyObject>(JSONObject2);