2011-05-27 17 views
47

Tengo un servicio WCF en su lugar.Tipo inesperado - Excepción de serialización

La operación normal vería que el servidor está procesando la devolución de un objeto XactTaskIn ocupado al cliente mediante una devolución de llamada. Tengo esto funcionando bien.

Mi problema es que cuando intento establecer la variable returnData en una XactException llena y trato de enviar el XactTaskIn al cliente a través de la devolución de llamada, me sale la siguiente excepción.

Excepción - "Tipo 'XactException' con los datos nombre de contrato 'XactException: http: //schemas.datacontract.org/2004/07/'. no se espera Considere el uso de un DataContractResolver o añadir cualquier tipos no conocidos de forma estática en la lista de tipos conocidos ; por ejemplo, al usar el atributo KnownTypeAttribute o por agregándolos a la lista de tipos conocidos pasados ​​a DataContractSerializer. " (System.Runtime.Serialization.SerializationException) Excepción mensaje = "Tipo 'XactException' con los datos nombre de contrato 'XactException: http: //schemas.datacontract.org/2004/07/'. no se espera Considere el uso un DataContractResolver o añadir cualquier tipo no conocen de forma estática a la lista de tipos conocidos - por ejemplo, mediante el uso de el atributo KnownTypeAttribute o de añadirlos a la lista de tipos conocidos pasado a DataContractSerializer ", Tipo de excepción =. "System.Runtime.Serialization.SerializationException"

Aquí es la clase 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; 
    } 
} 

Aquí está la clase XactException:

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

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

Actualización:

autorización así que el comentario de Daniel me ha ayudado.

Ahora parece que el servidor está enviando la devolución de llamada al cliente, pero el cliente está lanzando la siguiente excepción.

  • parados: "El formateador inició una excepción al intentar deserializar el mensaje: Se ha producido un error al tratando de deserializar parámetro http://tempuri.org/:taskIn El mensaje InnerException era 'Error en línea 1 posición 960. El elemento 'http://schemas.datacontract.org/2004/07/:returnData' contiene datos de un tipo que mapea a el nombre 'http://schemas.datacontract.org/2004/07/: XactException '. El deserializador no tiene conocimiento de cualquier tipo que se corresponda con este nombre. Considere el uso de un DataContractResolver o añadir el tipo correspondiente a 'XactException' a la lista de conocidos tipos -. Por ejemplo, utilizando el atributo KnownTypeAttribute o por de añadir a la lista de tipos conocidos pasados ​​a DataContractSerializer' . favor ver InnerException para más detalles " (System.ServiceModel.Dispatcher.NetDispatcherFaultException) Excepción mensaje =" El formateador inició una excepción al intentar deserializar el mensaje:. Hubo un error al intentar deserializar parámetro http://tempuri.org/:taskIn. El mensaje InnerException era 'Error en línea 1 posición 960. Elemento 'http://schemas.datacontract.org/2004/07/:returnData' contiene datos de un tipo que se asigna a el nombre ' http: //schemas.datacontract.org/2004/07/:XactException '. El deserializador no tiene conocimiento de cualquier tipo que se corresponda con este nombre. Considere el uso de un DataContractResolver o añadir el tipo correspondiente a 'XactException' a la lista de conocidos tipos -. Por ejemplo, utilizando el atributo KnownTypeAttribute o por de añadir a la lista de tipos conocidos pasados ​​a DataContractSerializer' . favor ver InnerException para más detalles . ", Tipo de excepción = "System.ServiceModel.Dispatcher.NetDispatcherFaultException"
+0

Pruebe usar 'KnownTypeAttribute' como se detalla en la excepción. –

+1

@Daniel - ¿Dónde pondría el atributo? – user589195

+0

@ user589195: Supongo que en la clase 'XactException'. –

Respuesta

79

En su clase de

[DataContract] 
    public class XactTaskIn 

tiene propiedades que devuelven objetos:

 [DataMember] 
     public object[] originalInputs; 

     [DataMember] 
     public object returnData; 

WCF tiene que saber de antemano qué tipo posiblemente pueden estar ahí, de modo que pueda decirle al cliente (a través del WSDL) cuáles son todos los tipos. Para cualquiera/todos los tipos que no sean 'nativos' (cualquier cosa que no sea int, cadena, DateTime, etc.) deberá agregar un atributo [KnownType] para cada tipo posible que pueda transmitirse en esas propiedades de objeto, como esta:

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

de esta forma cuando WCF construye el WSDL para el servicio, se sabrá añadir XactException a la lista de tipos de datos, y también el serializador sabrá que tiene que buscar esas clases.


Nota al margen; si su cliente se compiló utilizando SrvUtil, la referencia de servicio o se generó a partir del WSDL de alguna manera, tendrá que reconstruir el cliente después de agregar los atributos [KnownType].

+2

Brillante, muchas gracias, me ayudó a entenderlo también en lugar de simplemente darme la respuesta :) – user589195

+0

Tuve más problemas, donde tenía un campo público, pero solo un obtener, que necesitaba un conjunto antes de ver el siguiente error en la lista – TruthOf42

0

Su cliente está esperando un XactTaskIn no es un XactException.

Es necesario cambiar su XactTaskIn para poder pasar un objeto de excepción a su cliente.

Coloque su excepción datacontract y agregue el tipo XactException a su clase XactTaskIn como un miembro de datos

+0

Hola Ken, gracias por la respuesta, creo que estoy tratando de hacer lo que sugeriste. No estoy tratando de enviar una XactException al cliente, sino más bien un objeto XactTaskIn cuyo dataDactor de returnData contiene un objeto XactException. – user589195

0

Las excepciones de Seriliazation ocurren cuando los datos han cambiado, por ejemplo, algo tan trivial como cambiar el nombre de un campo de awesomeString a awesomeSTring causará que la serialización se rompa. La razón de esto es que los datos nuevos ya no se pueden validar con los datos anteriores. La solución para esto es usar la versión anterior que espera el servidor/cliente.

Cuestiones relacionadas