1

I'm connected to a websocket and subscribed to the MessageRecieved event. In that event I will get a string (json) that could be deserialized to any of about 5 different DataContracts. Right now I'm just using a switch statement with a unique bit of the txt and then calling var item = message.FromJson<MyType1>();

Is there a better way to do that dynamically?

LorneCash
  • 1,446
  • 2
  • 16
  • 30
  • Do you have any control over the JSON format? If you really are using `DataContractJsonSerializer` you can use the [type hint mechanism](https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/stand-alone-json-serialization#preserving-type-information) to specify the concrete type in a `"__type"` metadata property. See e.g. [How to deserialize JSON with unnamed collection of types using DataContractSerializer](https://stackoverflow.com/a/34435623/3744182). (I'm not certain that ServiceStack.Text is using `DataContractJsonSerializer` though, will try to check...) – dbc Feb 04 '21 at 15:28
  • unfortunately no, the websocket is from another company. – LorneCash Feb 04 '21 at 15:34
  • Too bad, looks like it could have been made to work, see [this ServiceStack.Text unit test here](https://github.com/ServiceStack/ServiceStack.Text/blob/45305969e170d9ae1d1695898778dc705eaf0901/tests/ServiceStack.Text.Tests/JsonTests/PolymorphicListTests.cs#L217). – dbc Feb 04 '21 at 15:39

1 Answers1

1

If you want the JSON deserialized into a Type then you would need to tell the ServiceStack serializer what type it should deserialize into, if you prefer you can deserialize into a runtime type with:

Type intoType = GetTypeToDeserializeInto(msg);
var dto = JsonSerializer.DeserializeFromString(msg, intoType);

Using JS Utils

Alternatively if you just need to generically access the JSON data without needing to deserialize into a Type you can use JSON Utils, eg:

var obj = (Dictionary<string, object>) JSON.parse(msg);
var prop1 = obj["prop1"];

Convert Object Dictionary into Type

If the JSON is a flat structure you can later use ServiceStack's Reflection Utils to convert the object dictionary into a Type, e.g:

var dto = obj.FromObjectDictionary<MyType1>();

var dto = map.FromObjectDictionary(intoType); // runtime Type

Embed Type Info in JSON

If all message Types are derived from the same subclass it's also possible to embed the Type the JSON should deserialize into if it embeds the Full Type Name in the first "__type" property, e.g:

// json starts with: {"__type": "Namespace.MyType1", ...}
var dto = msg.FromJson<Message>(json);

But you would need to take into consideration of restrictions imposed on auto deserialization of Late-bound Object Types.

mythz
  • 141,670
  • 29
  • 246
  • 390