1

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?

  • 1
    "*How do I Deserialize JSONObject2, without adding new class or making modification to MyObject?*" - that's an unreasonable restriction. The answer is **you can't**. What is the reason for such a restriction? – CoolBots Aug 23 '20 at 00:05
  • 1
    Can `MyInnerObject` be modified? Or no modifications at all? – CoolBots Aug 23 '20 at 00:08
  • Can you explain the reasoning for the requirement please and explain the actual end goal? Then maybe someone can come up with a solution, right now it seems it can't be solved – Sebi Aug 23 '20 at 00:08
  • *"...without adding new class..."* - so a custom converter is also out? Please clarify your question; as is, the answer is "Sorry, you can't", and the question should be closed. – CoolBots Aug 23 '20 at 00:28
  • Did https://stackoverflow.com/questions/18994685/how-to-handle-both-a-single-item-and-an-array-for-the-same-property-using-json-n work for you? – mjwills Aug 23 '20 at 02:37

1 Answers1

2

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);

  • All that does (if compile-time errors are fixed - `''` is not a vailid `char`, and `replace` starts with an upper-case `R`) is manually change the JSON input from second format to first. If that's really the OP's question, it needs to be rephrased, if not closed, before an answer is posted. As is, neither the question, nor your answer are helpful to anyone, imho. – CoolBots Aug 23 '20 at 00:48
  • 1
    Fair enough updated my answer. Was just trying to provide a solution based on my understanding of the question posed, I don't think just saying it can't be solved is very constructive either, but yes additional info around the use case would be helpful. Will be compiling my answers going forward, lessons learned :) – Steven Williams Aug 23 '20 at 01:05