WCF列表序列化/反序列化错误

我有以下ServiceContract和DataContract类:

[ServiceContract] public interface IWcfService { [OperationContract] Response GetData(); } [DataContract] public class Response { [DataMember] public Dictionary Data { get; set; } } 

当Response.Data字典的值为int,string,double或任何其他“简单”基元类型时,WCF可以成功序列化该对象。 但是当Response.Data字典的值为List 类型时,客户端在接收到数据并尝试反序列化时抛出以下exception:

 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.'. 

我还尝试将KnownType属性添加到ServiceContract和DataContract,如下所示:

 [ServiceContract] [ServiceKnownType(typeof(List))] [ServiceKnownType(typeof(Dictionary))] [ServiceKnownType(typeof(Dictionary<string, List>))] public interface IWcfService { [OperationContract] [ServiceKnownType(typeof(List))] [ServiceKnownType(typeof(Dictionary))] [ServiceKnownType(typeof(Dictionary<string, List>))] Response GetData(); } [DataContract] [ServiceKnownType(typeof(List))] [ServiceKnownType(typeof(Dictionary))] [ServiceKnownType(typeof(Dictionary<string, List>))] [KnownType(typeof(List))] [KnownType(typeof(Dictionary))] [KnownType(typeof(Dictionary<string, List>))] public class Response { [DataMember] public Dictionary Data { get; set; } } 

但这一切都没有帮助。 任何人对此都有任何想法?

更新

数据看起来像:

 Data = new new DIctionary { {"_id", 12344}, {"names", new List{ "John", "Peter", "Jack"}}, {"time", DateTime.Now} } 

我们之所以使用Dictionary :Server需要向客户端发送’dynamic’数据的字典,可以是int,List,DataTime等。它将通过使用Dictionary帮助解决这个问题,但它也丢失了原始类型信息。 例如,客户端需要List并执行一些数据绑定以显示集合,因此List.ToString()在这种情况下没有帮助。

我认为默认情况下System.Object不是Serializable 。 您需要发送额外信息,但它仍然不是最佳做法,我建议您在使用字典之前定义一个单独的类型。

请参阅以下内容:

WCF服务返回一个字典数组

WCF System.Object序列化

在WCF中序列化IDictionary

请记住,您的数据协定通过线路被串行化为字符串,因此您传递的任何对象都必须是可序列化的(不是哪个object )。

问题是您在面向服务的上下文中使用面向对象的模式 – 期望您在字典值中传递的所有内容都是object多态。 我在这里回答了一个类似“气味”的问题: https : //stackoverflow.com/a/19445875/2382536 。

这个问题可归因于WCF非常善于抽象出你的服务的底层渠道,你很想忘记你现在正在“面向服务”的环境中工作( KnownTypes是一个黑客 – 给出了OO的错觉通过电线)。 数据协定构成服务“公共”API的一部分,因此必须明确表示您的服务所公开的数据。 拥有返回“动态”数据的数据结构违反了这一重要规则。

客户端需要知道它返回的数据,因此如果要实现“动态”响应,则应该为响应中的变体实现(比方说)不同的方法/端点/服务。 在您的服务中,没有理由不使用多态来简化代码 – 但这不应泄露到公共服务/数据协定中。

感谢大家的投入。 通过配置WCF使用NetDataContractSerializer作为序列化程序(默认为DataContractSerializer),我设法解决了这个问题。 NetDataContractSerializer在进行序列化时将包含更多CLR类型信息,尽管它具有性能损失(大约是序列化时间的两倍)。