Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
262 views
in Technique[技术] by (71.8m points)

c# - Unexpected Type - Serialization Exception

I have a WCF service in place.

Normal operation would see the server doing some processing the returning a populated XactTaskIn object to the client via a callback. I have this working ok.

My problem is that when I try and set the returnData variable to a populated XactException and try to send the XactTaskIn back to the client via the callback, I get the following exception thrown.

Exception - "Type 'XactException' with data contract name 'XactException:http://schemas.datacontract.org/2004/07/' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer." (System.Runtime.Serialization.SerializationException) Exception Message = "Type 'XactException' with data contract name 'XactException:http://schemas.datacontract.org/2004/07/' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.", Exception Type = "System.Runtime.Serialization.SerializationException"

Here is the XactTaskIn class

[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;
    }
}

Here is the XactException class:

[DataContract]    
public class XactException
{
    [DataMember]
    string message;

    public XactException(string message)
    {
        this.message = message;
        // Add implementation.
    }
}

Update:

Ok so the comment from Daniel has helped me.

It looks now like the server is sending the callback to the client, but the client is throwing the following exception.

  • Caught: "The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:taskIn. The InnerException message was 'Error in line 1 position 960. Element 'http://schemas.datacontract.org/2004/07/:returnData' contains data from a type that maps to the name 'http://schemas.datacontract.org/2004/07/:XactException'. The deserializer has no knowledge of any type that maps to this name. Consider using a DataContractResolver or add the type corresponding to 'XactException' 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.'. Please see InnerException for more details." (System.ServiceModel.Dispatcher.NetDispatcherFaultException) 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/:taskIn. The InnerException message was 'Error in line 1 position 960. Element 'http://schemas.datacontract.org/2004/07/:returnData' contains data from a type that maps to the name 'http://schemas.datacontract.org/2004/07/:XactException'. The deserializer has no knowledge of any type that maps to this name. Consider using a DataContractResolver or add the type corresponding to 'XactException' 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.'. Please see InnerException for more details.", Exception Type = "System.ServiceModel.Dispatcher.NetDispatcherFaultException"
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In your class

    [DataContract]
    public class XactTaskIn

you have properties that return objects:

        [DataMember]
        public object[] originalInputs;

        [DataMember]
        public object returnData;

WCF needs to know ahead of time what types can possibly be in there, so that it can tell the client (through the WSDL) what all the types are. For any/all non-'native' types (anything that isnt int, string, DateTime, etc) you will need to add a [KnownType] attribute for every possible type that might be passed back in those object properties, like this:

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

That way when WCF builds the WSDL for the service, it will know to add XactException to the list of datatypes, and also the serializer will know to look for those classes.


Side-note; if your client was built using SrvUtil, Service Reference, or generated from the WSDL in some way, you will need to rebuild the client after adding the [KnownType] attributes!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...