I'm using the Servicestack.Text package to serialize and deserialize objects to and from JSON. One of my objects has a property of type object (System.Object). It is one of three things: a long, a double, a string. However, when I use JsonSerializer.DeserializeFromString it is always deserialized as a string. I need it deserialized as the type it was when it was serialized. I tried including the type information with JsConfig.IncludeTypeInfo = true; however, that only appears to apply to the class level, not the property level. How do I make this work?
1 Answers
This is not supported in ServiceStack JSON Serializer which looks at the target type that it's deserializing into for info on how to coerce the JSON value.
Because you're using an object
property there is no type info so it then fallsback and looks for existence of a __type property for this info, but ServiceStack never emits __type information for ValueTypes as it considerably bloats the payload.
With no type info to go on, the serializer just leaves the value as a string which is an object.
I recommend avoiding the use of interfaces, late-bound object types, etc which are a bad idea to have on DTOs, but for this you could create an extension method that inspects the string value and returns an instance of the correct type based on the contents, e.g:
var dto = new WildCard { AnyObject = 1 };
dto.AnyObject.AsJsonValue(); //Extension method that
"1" -> int 1
"true" -> bool true
"anything else" -> string "anything else"
The only issue with this is not being able to send a string literal containing a number or boolean value as it always gets coerced into their respective types.
-
What do you mean by "extension method" in this context? Is there some way to customize serialization on a per-property basis? And what would you think of an property attribute to force __type data to be written regardless of datatype and global settings? – Brannon Jan 26 '13 at 00:17
-
1In fact, it seems to me that we should always write __type data when serializing something of type object. How will we get it back otherwise? – Brannon Jan 26 '13 at 00:18
-
Updated to show extension method. It only emits __type info when the object property is a reference type. – mythz Jan 26 '13 at 00:32
-
I ended up adding a second property that got the DataMember attribute and formatted/parsed the data going/coming. – Brannon Jan 29 '13 at 00:50