0

I have problem how do it nicely.

I have string with JSON and want change it to class.

I know I can use this code:

var json = JsonConvert.DeserializeObject<MyClass>(stringJson);

The problem is I have a few classes and don't know how to nicely select what class should be used.

I know one way to do it, but I think it is nasty. E.g.:

try
{
    var json = JsonConvert.DeserializeObject<MyClass1>(stringJson);
}
catch()
{}
try
{
    var json = JsonConvert.DeserializeObject<MyClass2>(stringJson);
}
catch()
{}

Is there another why to do it?

Edit:

I have 8-10 different versions of what I can get and in all version I know how it will be look (number of version can change).

Craig W.
  • 17,838
  • 6
  • 49
  • 82
  • 3
    why don't you know the type that you're deserializing? that seems... unusual – Marc Gravell May 08 '18 at 21:32
  • I agree with @MarcGravell, if you don't know what you are deserializing, how will you know what to do with it after you deserialize it? – Ron Beyer May 08 '18 at 21:37
  • I have 8-10 diffrent version of that what can get and in all version i know how it will be look. – Marcin Gołuński May 08 '18 at 21:39
  • It's not that unusual. We have exactly the same situation. External systems can put serialized objects onto a queue, but those objects could be one of several notifications. We use the approach the OP posted, try to deserialize, if that one fails, try the next one. It's the best solution we've come up with. – Craig W. May 08 '18 at 21:44
  • Deserialize into object and later, use GetType to know what class should you use... – z3nth10n May 08 '18 at 21:51

2 Answers2

0

Method 1

As I commented, you should use object in this case:

var json = JsonConvert.DeserializeObject<JObject>(stringJson);

And inside your JObject you should send your class and switch it, like this:

string type = json["type"].ToString();

switch(type) 
{

    case "MyClass":
         //do whatever...
         break;

    case "MyClass1":
         //do whatever...
         break;

    case "MyClass2":
         //do whatever...
         break;

}

Method 2

I wrote a mistake, yep, I missed this (you can use ToObject method):

var json = JsonConvert.DeserializeObject<JObject>(stringJson);

string type = json.ToObject<object>().GetType().Name;

And do a switch like in Method 1

Method 3

Also, you can inherit from a base class:

public class MyClass 
{

}

public class MyClass1 : MyClass
{

}

public class MyClass2 : MyClass
{

}

//And so on...

If this isn't what you need, please tell me.

z3nth10n
  • 2,341
  • 2
  • 25
  • 49
  • first option didnt work, becouse i get "JObject". In second how it should work? var json = JsonConvert.DeserializeObject(stringJson);? If this is correct form i get on this way exception. – Marcin Gołuński May 08 '18 at 22:07
  • Sorry, please try this: https://stackoverflow.com/a/10221594/3286975 in the first option. – z3nth10n May 08 '18 at 22:13
  • still no: For first get message: "Message: "Object reference not set to an instance of an object."" For secoud still get JObject for the thirdi get exception – Marcin Gołuński May 08 '18 at 22:40
  • You get a object null reference exception because you don't have any entry with this name, you have to pass a entry with this name. – z3nth10n May 08 '18 at 22:42
  • I dont understand. In 2 method type is still JObjcet, or i should write smothing alse about: "object" ? In 1 method after this line: string type = json["type"].ToString(); i have exception, and i shuld change "type"? if yes than for what? – Marcin Gołuński May 08 '18 at 23:59
  • No in method 1 you should put a string with the name of the class – z3nth10n May 09 '18 at 00:23
  • still not work. But i dont understand how it should work, if i need class name before switch? However i find another solution. I check my json, i find one element its different always to another, and i can check use it. – Marcin Gołuński May 09 '18 at 18:08
0

You can parse to JObject to select the exact type according to your own rules. You can even use LINQ and other fancy things.

For example lets take message structure like that:

{
    "type": "info",
    "data" : { 

    }
}

then you have it:

JObject parsed = JObject.Parse(stringJson);
var type = parsed["type"].Value<string>();

switch(type)
{
    case "info":
        {
            // got an info
            // You can parse the exact property you need, not the whole object
            var result = JsonConvert.DeserializeObject<Info>(parsed["data"].ToString());
            break;
        }
    case "error":
        {
            // got an error
            var result = JsonConvert.DeserializeObject<Error>(parsed["data"].ToString());
            break;
        }
}

If you can't control json format you could use whatever evidence to determine the exact type

Curly Brace
  • 515
  • 3
  • 13