Deserializing an unknown type in JSON.NET
Asked Answered
S

5

21

I just got a hold of JSON.NET and its been great so far.

However, I cannot figure out how to determine the type of a serialized object when deserializing it.

How can I determine the object's class to cast it?

To clarify my question, let's say I wanted to do this

string json = <<some json i don't know>>
var data = JsonConvert.DeserializeObject(json);
if (data is Person)
{
   //do something
}
else if (data is Order)
{
   //do something else
}

Does Json.NET support this kind of functionality?

Spracklen answered 20/1, 2014 at 23:58 Comment(5)
That was my first thought too. However, the type is Newtonsoft.Json.Linq.JObjectSpracklen
JSON is a plain format and not keep metadata on serialization. You MUST know what type you are deserialize.Echevarria
@HamletHakobyan, how can I differentiate between different objects then? When a client sends something to my server, I have to be able to detect what it isSpracklen
How client sends data to your server? You must have some protocol to determine what client sent.Echevarria
If GetType() returns JObject the the value of the key simply another json object. You need to recurse into it and read the subsequent keys.Rapturous
T
34

you can use dynamic type

JsonConvert.DeserializeObject<dynamic>(JSONtext)
Twigg answered 21/1, 2014 at 0:6 Comment(2)
Console.WriteLine(JsonConvert.DeserializeObject<dynamic>(serializedMessage).GetType()); just gives me Newtonsoft.Json.Linq.JObjectSpracklen
i think Json can't recognize the type of object. you need to check it manually.Twigg
S
13

it may help you

IDictionary < string, JToken > Jsondata = JObject.Parse(yourJsonString);
   foreach(KeyValuePair < string, JToken > element in Jsondata)
    {
           string innerKey = element.Key;
            if (element.Value is JArray)
             {
                  // Process JArray
             }
            else if (element.Value is JObject) 
            { 
                  // Process JObject
            }
   }

Salyer answered 21/1, 2014 at 6:56 Comment(0)
S
4

In case you control the serialization, you can use the TypeNameHandling setting

var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
var toBeSerialized = settings; // use the settings as an example data to be serialized

var serialized = JsonConvert.SerializeObject(toBeSerialized, Formatting.Indented, settings);
var deserialized = JsonConvert.DeserializeObject(serialized, settings);

var deserializedType = deserialized.GetType().Name; // JsonSerializerSettings
Snobbery answered 6/6, 2019 at 12:38 Comment(0)
M
1

for anyone still trying to do this, I suggest to use

JsonConvert.DeserializeObject<ExpandoObject>(JSONtext)
Mckinnie answered 16/9, 2022 at 4:8 Comment(2)
WTH is ExpandoObject??Eats
@AdamHey why would one ask smth on SO before googlingCelebrant
H
0

With modern cross-platform .NET (6+) you can use System.Text.Json with JsonDocument.Parse(string jsonStr) to read arbitrary json fast and efficient. In most circumstances, System.Text.Json is powerful enough to not need Newtonsoft.Json (a.k.a. JSON.NET) anymore.

Check out the official .NET Docs on JSON DOM for a deep dive: https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/use-dom

But if you already have to have Newtonsoft.Json installed as a dependency (either by choice or because another Nuget package depends on it), you might as well use it...

Nowadays (Newtonsoft.Json 13.x) you could either use JObject.Parse() or just skip the generic for DeserializeObject like so: JsonConvert.DeserializeObject(jsonStr)

Omitting the generic will deserialize it to a JObject implicitly, but is slower than explicitly calling JObject.Parse yourself.

Haemato answered 3/5 at 23:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.