我有一个WCF服务。
正常操作会看到服务器正在进行一些处理,通过回调将填充的XactTaskIn对象返回给客户端。我的工作正常。
我的问题是,当我尝试将returnData变量设置为填充的XactException并尝试通过回调将XactTaskIn发送回客户端时,我会抛出以下异常。
异常 - “输入'XactException' 数据合同名称 'XactException:HTTP://schemas.datacontract.org/2004/07/' 不是预期的。考虑使用 DataContractResolver或添加任何类型 静态地不知道列表 已知类型 - 例如,通过使用 KnownTypeAttribute属性或 将它们添加到已知类型列表中 传递给DataContractSerializer。“ (System.Runtime.Serialization.SerializationException)异常 Message =“用'输入'XactException' 数据合同名称 'XactException:HTTP://schemas.datacontract.org/2004/07/' 不是预期的。考虑使用 DataContractResolver或添加任何类型 静态地不知道列表 已知类型 - 例如,通过使用 KnownTypeAttribute属性或 将它们添加到已知类型列表中 传递给DataContractSerializer。“, 例外类型= “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.
}
}
更新
好的,所以丹尼尔的评论帮助了我。
现在看起来服务器正在向客户端发送回调,但是客户端抛出了以下异常。
- 抓住:“格式化程序在尝试反序列化时抛出异常 消息:有一个错误 试图反序列化参数 http://tempuri.org/:taskIn。该 InnerException消息是'错误 第1行位置960.元素 'http://schemas.datacontract.org/2004/07/:returnData' 包含映射到的类型的数据 名字 'http://schemas.datacontract.org/2004/07/:XactException'。 解串器不知道 任何映射到此名称的类型。 考虑使用DataContractResolver 或添加对应的类型 'XactException'到已知列表 类型 - 例如,通过使用 KnownTypeAttribute属性或 将其添加到已知类型列表中 传递给DataContractSerializer。'。 有关更多信息,请参阅InnerException 细节。” (System.ServiceModel.Dispatcher.NetDispatcherFaultException)异常 消息=“格式化程序扔了一个 尝试反序列化时出现异常 消息:有一个错误 试图反序列化参数 http://tempuri.org/:taskIn。该 InnerException消息是'错误 第1行位置960.元素 'http://schemas.datacontract.org/2004/07/:returnData' 包含映射到的类型的数据 名字 'http://schemas.datacontract.org/2004/07/:XactException'。 解串器不知道 任何映射到此名称的类型。 考虑使用DataContractResolver 或添加对应的类型 'XactException'到已知列表 类型 - 例如,通过使用 KnownTypeAttribute属性或 将其添加到已知类型列表中 传递给DataContractSerializer。'。 有关更多信息,请参阅InnerException 详情。“,例外类型= “System.ServiceModel.Dispatcher.NetDispatcherFaultException”
答案 0 :(得分:80)
在你的班级
[DataContract]
public class XactTaskIn
你有返回对象的属性:
[DataMember]
public object[] originalInputs;
[DataMember]
public object returnData;
WCF需要提前知道可能存在哪些类型,以便它可以告诉客户端(通过WSDL)所有类型是什么。对于任何/所有非“非”类型(任何不是int,string,DateTime等),您需要为可能在这些对象属性中传回的每种可能类型添加[KnownType]属性,如下所示: / p>
[KnownType(typeof(XactException))]
[KnownType(typeof(...))]
[KnownType(typeof(...))]
[DataContract]
public class XactTaskIn
当WCF为服务构建WSDL时,它会知道将XactException添加到数据类型列表中,并且序列化程序也知道要查找这些类。
侧面说明;如果您的客户端是使用SrvUtil,Service Reference构建的,或者以某种方式从WSDL生成,则需要在添加[KnownType]属性后重建客户端!
答案 1 :(得分:0)
您的客户端期望XactTaskIn不是XactException。
您需要更改XactTaskIn才能将异常对象传递回客户端。
删除异常datacontract,并将XactException类型作为数据成员添加到XactTaskIn类中
答案 2 :(得分:0)
当数据发生变化时会发生Seriliazation异常,例如将字段名称从awesomeString
更改为awesomeSTring
这样会导致序列化中断。原因是新数据无法再针对旧数据进行验证。解决此问题的方法是使用服务器/客户端期望的旧版本。