none
Java Web Service + .NET Client =Unmarshalling Error: unexpected element..." RRS feed

  • Pregunta

  • Buenas,

    Realización una comunicación WS contra un servidor Java que funcionaba hasta la fecha y el cual han actualizado, en las peticiones enviadas mediante la referencia añadida al servicio WSDL / SOAP en Visual Studio 2015 el Payload que genera automáticamente en el mensaje SOAP con codificación UTF8 Document Literal se genera

    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <obtenerPlan xmlns="http://ws.url.wsempresa.com/">
        <idCurso xmlns="">2016</idCurso>
      </obtenerPlan>
    </s:Body>

    Pero ahora se debe enviar:

    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <pe:obtenerPlan xmlns:pe="http://ws.url.wsempresa.com/">
        <idCurso xmlns="">2016</idCurso>
      </pe:obtenerPlan>
    </s:Body>

    Definieindo PE: en el mismo tag o en el padre xmlns:pe=http://ws.url.wsempresa.com/

    Porque al actualizar las referencias del WS en el proyecto no envía con ese formato? el esquema publicado es incorrecto? el XSD no corresponde? desde SOAPUI contra el WSDL funciona pero con Visual Studio no crea el mismo formato en el body de la petición SOAP...

    ¿Alguna sugerencia?


    • Editado Mainmind lunes, 6 de marzo de 2017 15:34 actualizar asunto
    jueves, 2 de marzo de 2017 13:20

Todas las respuestas

  • Hola, puedes mostrarnos la clase generada al agregar la referencia al servicio web? Para validar que los namespaces son correctos. gracias

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

    jueves, 2 de marzo de 2017 13:59
  • Hola Sergio,

    Te adjunto la parte del código correspondiente

    Reference.cs

    ...

        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
        [System.ServiceModel.MessageContractAttribute(WrapperName="obtenerPlan", WrapperNamespace="http://ws.url.wsempresa.com/", IsWrapped=true)]
        public partial class obtenerPlan {

            [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://ws.url.wsempresa.com/", Order=0)]
            [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
            public int idCurso;

            public obtenerPlan() {
            }

            public obtenerPlanEstudios(int idCursoEscolar) {
                this.idCursoEscolar = idCursoEscolar;
            }
        }

    ...

    Un saludo

                           
    • Editado Mainmind jueves, 2 de marzo de 2017 16:45
    jueves, 2 de marzo de 2017 16:39
  • Hola. Revisa este articulo https://weblog.west-wind.com/posts/2016/Apr/02/Custom-Message-Formatting-in-WCF-to-add-all-Namespaces-to-the-SOAP-Envelope

    en la parte de A generic [EnvelopeNamespaces] Operation Attribute. La idea es sobreescribir como se serializa un mensaje enviado desde un cliente proxy.


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

    jueves, 2 de marzo de 2017 19:21
  • Hola Sergio, puede ser el problema que no concuerde el XSD devuelto por el WSDL? antes de que "actualizaran" el servidor Java funcionaba sin ninguna personalización...

    De tener que personalizar todas las funciones del WS a alguna adaptación general sobre el binding para aplicar un formato específico del xml del body de forma genérica?

    • Editado Mainmind viernes, 3 de marzo de 2017 7:42
    viernes, 3 de marzo de 2017 7:40
  • Hola. Pues habría que analizar el wsdl del servicio para poder darte una mejor respuesta. Como generas tus clases proxy? Prueba tanto a generarlo con un Service Reference y un Wb Reference y ver la diferencia. Has "actualizado" tus referencias? A lo mejor te falta ese paso

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

    viernes, 3 de marzo de 2017 9:50
  • Hola Sergio, están añadidas como Service Reference actualizadas con el WS... no debería haber diferentes a la hora de realizar las llamadas...
    viernes, 3 de marzo de 2017 10:29
  • Resumiendo el problema... al importar la referencia al WS desde VS...

    Esta petición genera el error "Unmarshalling Error: unexpected element..."

    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <obtenerPlan xmlns="http://ws.url.wsempresa.com/">
        <idCurso xmlns="">2016</idCurso>
      </obtenerPlan>
    </s:Body>

    Esta es la petición que debería generar, pero no lo hace:

    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <m:obtenerPlan xmlns:m="http://ws.url.wsempresa.com/">
        <idCurso xmlns="">2016</idCurso>
      </m:obtenerPlan>
    </s:Body>

    ¿por que? ¿es posible especificar que se incluya de esta forma? ¿es problema de VS? con SOAP UI o Altova XMLSpy si parece realizar correctamente...


    • Editado Mainmind lunes, 6 de marzo de 2017 8:32
    lunes, 6 de marzo de 2017 8:30
  • Finalmente si es posible utilizado Web Service en lugar de Reference Service desde VS heredar la clase proxy en lugar de:

    System.Web.Services.Protocols.SoapHttpClientProtoco

    forzar a heredar y referenciar de:

    Microsoft.Web.Services3.WebServicesClientProtocol

    Utilizando WSE3:

    Cambiando en reference.cs de la clase proxy:

    System.Web.Services.Description.SoapBindingUse.Literal

    por

    System.Web.Services.Description.SoapBindingUse.Encoded

    sigue sin aceptar el formato del mensaje, pero esta vez problemas de validación de cabecera y autenticación...

    OJO esto es para una clase proxy generada como Web Reference heredando de WSE3:

                ExternoWS.ExternoWSImplService client = new ExternoWS.ExternoWSImplService();
    
                client.PreAuthenticate = true;
                client.RequestEncoding = System.Text.Encoding.UTF8;
                client.SoapVersion = System.Web.Services.Protocols.SoapProtocolVersion.Soap11;
    
    
                UsernameToken usuario = new UsernameToken("usuario",
                                                    "contraseña",
                                                    PasswordOption.SendPlainText);
    
                SoapContext context = client.RequestSoapContext;
                context.Security.Tokens.Add(usuario);
    	    context.Security.Elements.Add(new MessageSignature(usuario));
    	    client.Llamadafuncion();

    ¿Sería posible trasladar esta configuración a Service Reference?


    Como se puede configurar la equivalencia en WSE3 de:

    messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"

    • Editado Mainmind martes, 14 de marzo de 2017 8:48
    martes, 14 de marzo de 2017 8:12
  • Finalmente la opción más sencilla es realizar un cliente con WCF personalizando los mensajes para añadir todos los namespace en los mensajes SOAP, de esta manera "traga" los posibles problemas de comunicación con un servicio JAVA antiguo... muy antiguo...
    miércoles, 22 de marzo de 2017 9:32