意外类型 - 序列化异常

时间:2011-05-27 13:44:41

标签: c# .net wcf serialization exception-handling

我有一个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”
  •   

3 个答案:

答案 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这样会导致序列化中断。原因是新数据无法再针对旧数据进行验证。解决此问题的方法是使用服务器/客户端期望的旧版本。