c# - serializacion - Tipo inesperado: excepción de serialización
error al reflejar el tipo vb net (3)
Tengo un servicio WCF en su lugar.
La operación normal vería que el servidor está procesando el retorno de un objeto XactTaskIn poblado al cliente a través de 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 de vuelta al cliente a través de la devolución de llamada, me sale la siguiente excepción lanzada.
Excepción: "No se espera el tipo ''XactException'' con el nombre del contrato de datos ''XactException: http: //schemas.datacontract.org/2004/07/''. Considere utilizar un DataContractResolver o agregue cualquier tipo no conocido de forma estática a la lista de tipos conocidos. - por ejemplo, al usar el atributo KnownTypeAttribute o al agregarlos a la lista de tipos conocidos pasados a DataContractSerializer. " (System.Runtime.Serialization.SerializationException) Mensaje de excepción = "Escriba ''XactException'' con el nombre del contrato de datos ''XactException: http: //schemas.datacontract.org/2004/07/'' no esperado. Considere el uso de DataContractResolver o agregue cualquier tipos no conocidos de forma estática en la lista de tipos conocidos, por ejemplo, mediante el uso del atributo KnownTypeAttribute o agregándolos a la lista de tipos conocidos pasados a DataContractSerializer. ", Exception Type =" System.Runtime.Serialization.SerializationException "
Aquí está 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.
}
}
Actualizar:
Ok, 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.
- Atrapado: "El formateador arrojó una excepción al intentar deserializar el mensaje: Hubo un error al intentar deserializar el parámetro http://tempuri.org/:taskIn . El mensaje InnerException fue ''Error en la línea 1, posición 960. Elemento'' http : //schemas.datacontract.org/2004/07/: returnData ''contiene datos de un tipo que se asigna al nombre'' http://schemas.datacontract.org/2004/07/:XactException ''. El deserializador no tiene conocimiento de cualquier tipo que se corresponda con este nombre. Considere usar DataContractResolver o agregue el tipo correspondiente a ''XactException'' a la lista de tipos conocidos, por ejemplo, utilizando el atributo KnownTypeAttribute o agregándolo a la lista de tipos conocidos pasados a DataContractSerializer. . ''. Consulte InnerException para más detalles. (System.ServiceModel.Dispatcher.NetDispatcherFaultException) Exception Message = "El formateador arrojó una excepción al intentar deserializar el mensaje: Hubo un error al intentar deserializar el parámetro http://tempuri.org/:taskIn . El mensaje InnerException fue '' Error en la posición 1 de la línea 1 960. El elemento ''http://schemas.datacontract.org/2004/07/:returnData'' contiene datos de un tipo que se asigna al nombre ''http://schemas.datacontract.org/2004/07 /: XactException ''. El deserializador no tiene conocimiento de ningún tipo que se corresponda con este nombre. Considere usar DataContractResolver o agregue el tipo correspondiente a'' XactException ''a la lista de tipos conocidos, por ejemplo, utilizando el atributo KnownTypeAttribute o agregando a la lista de tipos conocidos pasados a DataContractSerializer. ''. Consulte InnerException para obtener más detalles. ", Exception Type =" System.ServiceModel.Dispatcher.NetDispatcherFaultException "
En tu clase
[DataContract]
public class XactTaskIn
usted tiene propiedades que devuelven objetos:
[DataMember]
public object[] originalInputs;
[DataMember]
public object returnData;
WCF necesita saber de antemano qué tipos pueden estar allí, 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 construya el WSDL para el servicio, sabrá agregar XactException a la lista de tipos de datos, y también el serializador sabrá que debe 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].
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
hará 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.
Su cliente espera una XactTaskIn no una XactException.
Necesita cambiar su XactTaskIn para poder pasar un objeto de excepción a su cliente.
Elimine su contrato de datos de excepción y agregue el tipo XactException a su clase XactTaskIn como miembro de datos