3

Context: I'm serializing data into a message queue. The message queue will accept heterogeneous types, that need to be deserialized by the receiver.

Problem: Normally when deserializing, I'd use code like: JsonConvert.DeserializeObject<Type>(object); However, because the types are heterogeneous, I won't trivially know the desired type ahead of time.

I know I can use TypeNameHandling to embed the type in the JSON, but when calling DeserializeObject, I still don't get a strongly typed result (as in, the returned object isn't cast to the embedded Type already).

Question: Can Json.Net cast a deserialized object to the type embedded in the Json? If not, is my best option to get the type from the JSON and then call DeserializeObject so the object can be cast?

Craig
  • 1,890
  • 1
  • 26
  • 44
  • 3
    I the types don't share a base class, you will have manually deserialize every type you need. You can make it "smart" by using the type name from JSON. Or, you can add dummy common base class. TypeNameHandling allows you to do: `{circle, rect, triangle}.DeserializeObject()` – Krzysztof Skowronek Mar 19 '19 at 15:27
  • 1
    An option could be to deserialize it to type dynamic and checking the type afterwards, perhaps – Lennart Mar 19 '19 at 15:29
  • *when calling DeserializeObject, I still don't get a strongly typed result* -- can you share a [mcve] for this? The actual type of the object returned should be the type specified in the `"$type"` property. Afterwards you can just do `object.GetType()` to determine the actual type. – dbc Mar 19 '19 at 23:10

1 Answers1

4

You can embed Type (class) name to your data. When deserializing, you can use little bit of reflection and JsonConvert.DeserializeObject(string, Type):

string typeName; //Got from message
string json; //Got from message
Type type = Type.GetType($"Namespace.{typeName}, MyAssembly");
var obj = JsonConvert.DeserializeObject(json, type);
Risto M
  • 2,919
  • 1
  • 14
  • 27
  • 2
    Please be aware that this approach renders the app insecure by leaving it open to various type and code injection attacks. See [TypeNameHandling caution in Newtonsoft Json](https://stackoverflow.com/q/39565954) and https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf for details. (The stackoverflow question relates to the security risk of using the`"$type"` property but the answer applies here also.) – dbc Mar 19 '19 at 23:10
  • 1
    This is important to be aware of. In OP's case , this is not a risk, because he himself writes messages into the queue and my answer assumes that the message types are presented in certain assembly "MyAssembly". – Risto M Mar 20 '19 at 05:37