I have the following ServiceContract and DataContract classes:
[ServiceContract]
public interface IWcfService
{
[OperationContract]
Response GetData();
}
[DataContract]
public class Response
{
[DataMember]
public Dictionary<string, object> Data { get; set; }
}
When the value of Response.Data dictionary is of type int, string, double or any other 'simple' primitive types, WCF can successfully serialize the object. But when the value of Response.Data dictionary is of type List< string>, the client threw following exception when itreceived the data and tried to deserialize it:
Message=The formatter threw an exception while trying to deserialize the message:
There was an error while trying to deserialize parameter http://tempuri.org/:GetDataResult.
The InnerException message was 'Error in line 1 position 990.
Element 'http://schemas.microsoft.com/2003/10/Serialization/Arrays:Value' contains data from a type
that maps to the name 'http://schemas.microsoft.com/2003/10/Serialization/Arrays:ArrayOfstring'.
The deserializer has no knowledge of any type that maps to this name.
Consider using a DataContractResolver or add the type corresponding to 'ArrayOfstring'
to the list of known types - for example, by using the KnownTypeAttribute attribute or
by adding it to the list of known types passed to DataContractSerializer.'.
I've also tried to add KnownType attribute to the ServiceContract and DataContract like following:
[ServiceContract]
[ServiceKnownType(typeof(List<string>))]
[ServiceKnownType(typeof(Dictionary<string, string>))]
[ServiceKnownType(typeof(Dictionary<string, List<string>>))]
public interface IWcfService
{
[OperationContract]
[ServiceKnownType(typeof(List<string>))]
[ServiceKnownType(typeof(Dictionary<string, string>))]
[ServiceKnownType(typeof(Dictionary<string, List<string>>))]
Response GetData();
}
[DataContract]
[ServiceKnownType(typeof(List<string>))]
[ServiceKnownType(typeof(Dictionary<string, string>))]
[ServiceKnownType(typeof(Dictionary<string, List<string>>))]
[KnownType(typeof(List<string>))]
[KnownType(typeof(Dictionary<string, string>))]
[KnownType(typeof(Dictionary<string, List<string>>))]
public class Response
{
[DataMember]
public Dictionary<string, object> Data { get; set; }
}
But none of this helped. Anyone has any ideas on this?
Updated
The Data would look like:
Data = new new DIctionary<string, object>
{
{"_id", 12344},
{"names", new List<string>{ "John", "Peter", "Jack"}},
{"time", DateTime.Now}
}
The reason why we used Dictionary< string, object>:
Server needs to send to the client a dictionary of 'dynamic' data, which can be int, List, DataTime, etc. It will help revolve this issue by using Dictionary, but it also lose the original type information. For example, the client needs List and do some data binding to display the collection, so List.ToString() will not be helpful in this case.
Best Solution
I think by Default the
System.Object
is notSerializable
. You need to send Extra information, but it still not the best practice, I recommend define a separate type before using your dictionary.Refer to the below:
WCF service returning an array of dictionary
WCF System.Object Serialization
Serializing IDictionary in WCF