Serializing IDictionary<string, object> in WCF
We have an existing application for which one of our DTO object has a property typed as IDictionary<string, object>
.
I am now trying to expose this object through a WCF service. This works in some cases, but not in the general case. To demonstrate the problem, consider the following two methods:
[OperationContract]
public IDictionary<string, object> Test1()
{
return new Dictionary<string, object>
{
{ "testkey1", "newstringvalue"},
};
}
[OperationContract]
public IDictionary<string, object> Test2()
{
return new Dictionary<string, object>
{
{ "testkey1", "newstringvalue"},
{ "testkey2", new object [] { "one" , "two", "three", } }
};
}
Method Test1() works as expected, but when I call Test2(), I get a strange runtime error on the client:
The request channel timed out while waiting for a reply after 00:01:00. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout.
Inner exception: The remote server returned an error: (504) Gateway Timeout.
This is despite the fact that the exception was thrown instantly, ie. I didn't actually have to wait a minute for this response. No error is shown on the server.
I suspect this stems from the fact that the serializer can't serialize object[], but this is not what is indicated by the error.
So my questions are:
Thanks.
I think you need to add object[] to the known types with the KnownTypeAttribute to make the 2nd case work, since that's what you're putting into the dictionary.
In any case, to see the real error on the server, you need to turn WCF Tracing on (or else run the debugger in the mode where it stops on every exception, even if it's caught)
As neither myself or any of my colleagues could think of a way to make this serialization work directly, we worked around the issue in the end by wrapping our object in a custom object, which converts the Dictionary<string, object>
to a Dictionary<string, string>
, which has a special serialization case defined for string arrays. We then changed the application to be aware of this. Not particularly elegant, but simple enough, and seems to work.