Since I upgraded to recent version or ServiceStack I started getting strange behavior.
From javascript when calling service stack via ajax the request object sent contains child dynamic object ( masterJob.customFields as attached)
This request in service stack defined CustomFields property as ExpandoObject.
Previously the ExpandoObject gets filled correctly with key and value having values as strings (A, B, C)
Since the upgrade now Value property (instead of containing the value as string) now it contains a complex object with properties (Buffer, HasValue, Length, Offset, Value) where actual value is now nested in “Value” property, and “Buffer” property contains json of the entire request object!
What is happening to the serialization to ExpandoObject and why ?
We’ve always strongly recommend using Types with the JSON Serializer, otherwise the different options for parsing dynamic JSON. We definitely don’t recommend putting using Expando in DTOs which violates the purpose of a typed service contract.
Either way add a stand-alone example that we can run to reproducible the issue either on http://gistlyn.com or GitHub and we can take a look.
These samples assumes we know the structure of the request. In my case I want to support custom fields which means it could be any arbitrary json (mainly key value pair or dictionary of string to object).
The way back-end handle it is that it attaches custom fields property as ExpandoObject property which gets persisted in MongoDB as is.
So at service stack request object does have a property of type ExpandoObject to map that arbitrary json which used to be parsed correctly to ExpandoObject as (dictionary of key to object where object contains the value string)… now after update the value property contains yet another complex object with other properties.
So Before ServiceStack update:
myRequest.CustomFields = {Key=“key1”, Value=“Value1”, Key=“key2”, Value=“value2”}
After ServiceStack update:
myRequest.CustomFields = {Key=“key1”, Value={Buffer=“LOTS OF JSON”, HasValue= “True”, Offset=0, Value=“value1”}, Key=“key2”, Value={Buffer=“LOTS OF JSON”, HasValue= “True”, Offset=0, Value=“value2”}}
My questions are:
Why did that behavior changed for the new version?
Is there a better supported way to have request (and response) object contains a dynamic property or dictionary of string to object ?
Use a Dictionary<string,string> to provide a Dictionary with unstructured values, you can use our IMeta interface that’s on many of our built-in DTOs to accept additional properties, you’re going to run into runtime issues like this by trying to have an unknown black hole in your Service Contract.
We don’t know why the behavior changed, that’s why I’ve asked for a stand-alone repro in order to investigate. But having unknown Expandos or object on DTOs isn’t a supported use-case that’s highly discouraged.