意外的types – 序列化exception

我有一个WCF服务。

正常的操作会看到服务器正在执行一些处理,通过callback函数将填充的XactTaskIn对象返回给客户端。 我有这个工作确定。

我的问题是,当我尝试将returnDatavariables设置为已填充的XactException并尝试通过callback将XactTaskIn发送回客户端时,出现以下exception。

exception – “不希望使用数据协定名称”XactException:http://schemas.datacontract.org/2004/07/“键入'XactException'。考虑使用DataContractResolver或将静态未知的任何types添加到已知types列表 – 例如,使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知types的列表中。 (System.Runtime.Serialization.SerializationException)exception消息=“types'XactException'与数据协定名称'XactException:http://schemas.datacontract.org/2004/07/'不是预期的考虑使用DataContractResolver或添加任何types不知道静态到已知types的列表 – 例如,通过使用KnownTypeAttribute属性或通过将它们添加到传递给DataContractSerializer的已知types的列表“,Exception Type =”System.Runtime.Serialization.SerializationException“

这是XactTaskIn类

[DataContract] public class XactTaskIn { [DataMember] public DateTime timeOut; [DataMember] public DateTime timeIn; [DataMember] public string name; [DataMember] public string responseTo; [DataMember] public String moduleFromName; [DataMember] public String moduleFromType; [DataMember] public String methodFromName; [DataMember] public object[] originalInputs; [DataMember] public String returnMethodToCall; [DataMember] public String returnModuleToCall; [DataMember] public object returnData; public XactTaskIn(DateTime timeOut, DateTime timeIn, string name, string responseTo, String moduleFromName, String moduleFromType, String methodFromName, object[] originalInputs, String returnMethodToCall, String returnModuleToCall, object returnData) { this.timeOut = timeOut; this.timeIn = timeIn; this.name = name; this.responseTo = responseTo; this.moduleFromName = moduleFromName; this.moduleFromType = moduleFromType; this.methodFromName = methodFromName; this.originalInputs = originalInputs; this.returnMethodToCall = returnMethodToCall; this.returnModuleToCall = returnModuleToCall; this.returnData = returnData; } } 

这里是XactException类:

 [DataContract] public class XactException { [DataMember] string message; public XactException(string message) { this.message = message; // Add implementation. } } 

更新:

好吧,丹尼尔的评论帮助了我。

它现在看起来像服务器发送到客户端的callback,但客户端抛出以下exception。

  • Caught:“格式化程序尝试反序列化消息时抛出一个exception:尝试反序列化参数http://tempuri.org/:taskIn时发生错误,InnerException消息是'Error in line 1 position 960.Element'http ://schemas.datacontract.org/2004/07/:returnData'包含映射到名称'http://schemas.datacontract.org/2004/07/:XactException'的types的数据。解串器没有知识可以考虑使用DataContractResolver或者将与'XactException'相对应的types添加到已知types的列表中 – 例如,使用KnownTypeAttribute属性或将其添加到传递给DataContractSerializer的已知types的列表'。请参阅InnerException获取更多细节。“ (System.ServiceModel.Dispatcher.NetDispatcherFaultException)Exception Message =“格式化程序在尝试反序列化消息时抛出一个exception:尝试反序列化参数http://tempuri.org/:taskIn时发生错误,InnerException消息是'第1行第960位错误。元素'http://schemas.datacontract.org/2004/07/:returnData'包含来自映射到名称'http://schemas.datacontract.org/2004/07'的types的数据/:XactException'。反序列化器不知道映射到这个名称的任何types,可以考虑使用DataContractResolver或者将与'XactException'对应的types添加到已知types的列表中 – 例如,通过使用KnownTypeAttribute属性或者添加它到传递给DataContractSerializer的已知types的列表“,请参阅InnerException获取更多细节。”,Exception Type =“System.ServiceModel.Dispatcher.NetDispatcherFaultException”

在你的class级

  [DataContract] public class XactTaskIn 

你有返回对象的属性:

  [DataMember] public object[] originalInputs; [DataMember] public object returnData; 

WCF需要提前知道哪些types可能在那里,以便它可以告诉客户端(通过WSDL)所有types。 对于任何/所有非“原生”types(任何不是int,string,DateTime等),您将需要为每个可能的types添加一个[KnownType]属性,这些types可能会在这些对象属性中传回,如下所示:

  [KnownType(typeof(XactException))] [KnownType(typeof(...))] [KnownType(typeof(...))] [DataContract] public class XactTaskIn 

这样,当WCF为服务构buildWSDL时,它会知道将XactException添加到数据types列表中,并且序列化程序也知道要查找这些类。


边注; 如果您的客户端是使用SrvUtil,Service Reference或通过某种方式从WSDL生成的,则需要在添加[KnownType]属性后重新生成客户端!

您的客户期望XactTaskIn不是XactException。

您需要更改您的XactTaskIn,以便能够将exception对象传回客户端。

删除exception数据合同,并将XactExceptiontypes作为数据成员添加到XactTaskIn类中

当数据发生变化时,会发生Seriliazationexception,例如,将字段名称从awesomeStringawesomeSTring会导致序列化中断。 原因是新的数据不能再根据旧的数据进行validation。 对此的修复是使用服务器/客户端期望的旧版本。