none
WCF - DataContractSerializer - El formateador inició una excepción al intentar deserializar el mensaje RRS feed

  • Pregunta

  • Buenas tardes trabajo en un proyecto de Servicio Web WCF en C#. 

    Estamos en la etapa de pruebas unitarias, y ocurre el siguiente problema:

    Por ejemplo si el DataContract solicita un int y le paso un string ejm: "asd", obviamente saltará un error y se cae el servicio.

    Lo que necesito es poder controlar este error para evitar la caída del servicio. Esto salta en el DataContractSerializer. He buscado por todos lados pero no he encontrado nada parecido.

    Saludos y gracias por darse un tiempo en leer esto.

    jueves, 16 de julio de 2015 16:42

Respuestas

Todas las respuestas

  • hola

    pero como implementas los test ? me pregunto son test unitarios o de integracion ?

    porque si son test contra un servicio real alojado en el iis entonces no es test unitario porque no defines un mock del serviciosino que lo pruebas real

    como invocas el servicio ? porque si usas una service reference no veo como podrias pasale un tipo de dato incorrecto

    o estas armando el mensaje SOAP con xml ?

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    jueves, 16 de julio de 2015 16:49
  • Lo pruebo mediante SoapUI, un software para Testing.

    No esta integrado aun a nada. Este software me permite pasarle mediante XML los datos del request y te genera la respuesta, en otras palabras armo el XML.

    Obviamente al usar el serviceReference, no habria forma de pasarle un tipo de dato erroneo.

    Pero ante esto, hay alguna forma de controlar este evento?

    

    jueves, 16 de julio de 2015 17:00
  • puedes poner el mensaje exacto de la exception?gracias

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    jueves, 16 de julio de 2015 18:31
    Moderador
  • <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
       <s:Body>
          <s:Fault>
             <faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:DeserializationFailed</faultcode>
             <faultstring xml:lang="es-ES">El formateador inició una excepción al intentar deserializar el mensaje: Error al intentar deserializar el parámetro http://LPG.Minisite.Viajero.Model/2015/Viajero:DatosPlan. El mensaje de InnerException era 'Error al deserializar el objeto del tipo Viajero.DataContracts.DatosPlan. El valor 'asd' no se puede analizar como tipo 'Int32'.'. Consulte InnerException para obtener más información.</faultstring>
             <detail>
                <ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                   <HelpLink i:nil="true"/>
                   <InnerException>
                      <HelpLink i:nil="true"/>
                      <InnerException>
                         <HelpLink i:nil="true"/>
                         <InnerException>
                            <HelpLink i:nil="true"/>
                            <InnerException i:nil="true"/>
                            <Message>La cadena de entrada no tiene el formato correcto.</Message>
                            <StackTrace>en System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer&amp; number, NumberFormatInfo info, Boolean parseDecimal)
       en System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
       en System.Xml.XmlConvert.ToInt32(String s)
       en System.Xml.XmlConverter.ToInt32(String value)</StackTrace>
                            <Type>System.FormatException</Type>
                         </InnerException>
                         <Message>El valor 'asd' no se puede analizar como tipo 'Int32'.</Message>
                         <StackTrace>en System.Xml.XmlConverter.ToInt32(String value)
       en System.Xml.XmlConverter.ToInt32(Byte[] buffer, Int32 offset, Int32 count)
       en System.Xml.ValueHandle.ToInt()
       en System.Xml.XmlBaseReader.ReadContentAsInt()
       en System.Xml.XmlDictionaryReader.ReadElementContentAsInt()
       en System.Runtime.Serialization.XmlReaderDelegator.ReadElementContentAsInt()
       en ReadDatosPlanFromXml(XmlReaderDelegator , XmlObjectSerializerReadContext , XmlDictionaryString[] , XmlDictionaryString[] )
       en System.Runtime.Serialization.ClassDataContract.ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
       en System.Runtime.Serialization.XmlObjectSerializerReadContext.ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader)
       en System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator reader, String name, String ns, Type declaredType, DataContract&amp; dataContract)
       en System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, DataContract dataContract, String name, String ns)
       en System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
       en System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)</StackTrace>
                         <Type>System.Xml.XmlException</Type>
                      </InnerException>
                      <Message>Error al deserializar el objeto del tipo Viajero.DataContracts.DatosPlan. El valor 'asd' no se puede analizar como tipo 'Int32'.</Message>
                      <StackTrace>en System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
       en System.Runtime.Serialization.DataContractSerializer.ReadObject(XmlDictionaryReader reader, Boolean verifyObjectName)
       en System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameterPart(XmlDictionaryReader reader, PartInfo part, Boolean isRequest)</StackTrace>
                      <Type>System.Runtime.Serialization.SerializationException</Type>
                   </InnerException>
                   <Message>El formateador inició una excepción al intentar deserializar el mensaje: Error al intentar deserializar el parámetro http://LPG.Minisite.Viajero.Model/2015/Viajero:DatosPlan. El mensaje de InnerException era 'Error al deserializar el objeto del tipo Viajero.DataContracts.DatosPlan. El valor 'asd' no se puede analizar como tipo 'Int32'.'. Consulte InnerException para obtener más información.</Message>
                   <StackTrace><![CDATA[en System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameterPart(XmlDictionaryReader reader, PartInfo part, Boolean isRequest)
       en System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameter(XmlDictionaryReader reader, PartInfo part, Boolean isRequest)
       en System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameters(XmlDictionaryReader reader, PartInfo[] parts, Object[] parameters, Boolean isRequest)
       en System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object[] parameters, Boolean isRequest)
       en System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)
       en System.ServiceModel.Dispatcher.OperationFormatter.DeserializeRequest(Message message, Object[] parameters)
       en System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)
       en System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
       en System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
       en System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc)
       en System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
       en System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
       en System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
       en System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)
       en System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
       en System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
       en System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)]]></StackTrace>
                   <Type>System.ServiceModel.Dispatcher.NetDispatcherFaultException</Type>
                </ExceptionDetail>
             </detail>
          </s:Fault>
       </s:Body>
    </s:Envelope>

    jueves, 16 de julio de 2015 19:00
  • Pero eso es lo correcto. Wcf te devuelve un FaultException cuando se genera una excepción no controlada, todas las excepciones se deberían devolver así al cliente y en tu programa deberías capturar dicha excepción. Si ves este articulo te explica como crear tu custom faultexception. http://www.codeproject.com/Articles/799258/WCF-Exception-FaultException-FaultContract#10

    Ahora bien, el,problema es el empleo de SoapUi que no te permite capturar excepciones creo yo. No tengo mucha experiencia con este programa


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos


    jueves, 16 de julio de 2015 19:10
    Moderador
  • yo uso para mis pruebas el WCFTestClient que viene con Visual Studio

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    jueves, 16 de julio de 2015 19:12
    Moderador
  • Encontraste la respuesta?
    jueves, 10 de mayo de 2018 2:00
  • Freddy, lo que indica el maestro Sergio Parra es acertado.  Buscar una respuesta a esta pregunta no es lo correcto.

    Lo correcto es que la prueba unitaria se de por APROBADA cuando se recibe el FaultException.  Es el resultado correcto.


    Jose R. MCP
    Code Samples

    jueves, 10 de mayo de 2018 2:15