Formato de jabón WCF

Estoy desarrollando un Servicio WCF que va a ser utilizado por una agencia gubernamental. Como accederán al mismo servicio alojado por diferentes empresas contratantes, han especificado la forma exacta en que los mensajes debe: (por lo tanto, solo cambiarán las URL para acceder al servicio de cada empresa).

Entonces, para este método:

sbyte Execute(int Id1, short Id2, string Id3, string Id4, string Value)

Esperan que aceptemos exactamente el siguiente mensaje SOAP:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http:/
/www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/
XMLSchema">
    <SOAP-ENV:Body>
        <m:Execute xmlns:m="http://tempuri.org/">
            <m:Id1>1</m:Id1>
            <m:Id2>2</m:Id2>
            <m:Id3>3</m:Id3>
            <m:Id4>4</m:Id4>
            <m:Value></m:Value>
        </m:Execute>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Y nuestra respuesta debe ser:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <ExecuteResponse xmlns="http://tempuri.org/">
            <ExecuteResult>
                <res>0</res>
            </ExecuteResult>
        </ExecuteResponse>
    </soap:Body>
</soap:Envelope>

En este momento, los mensajes para mi servicio actual, con binding="basicHttpBinding" y usando mi cliente de prueba (y también la herramienta WCF Test Client), se ven así:

Solicitud:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/ISomeService/Execute</Action>
  </s:Header>
  <s:Body>
    <Execute xmlns="http://tempuri.org/">
      <Id1>0</Id1>
      <Id2>0</Id2>
      <Id3>0</Id3>
      <Id4>0</Id4>
      <Value>0</Value>
    </Execute>
  </s:Body>
</s:Envelope>

Respuesta:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header />
  <s:Body>
    <ExecuteResponse xmlns="http://tempuri.org/">
      <ExecuteResult>1</ExecuteResult>
    </ExecuteResponse>
  </s:Body>
</s:Envelope>


¿Entonces mi pregunta es: ¿Qué debo cambiar para que mi servicio use mensajes SOAP como

" "

En lugar de usar...

Probé varios enlaces, configuraciones personalizadas, etc., pero no pude hacer que se viera igual.

Esta es mi configuración actual, usando el customBinding propuesto:

  <system.serviceModel>
    <services>
      <service name="Test.SomeService">
        <endpoint binding="customBinding" bindingConfiguration="Soap11Binding"
          contract="Test.ISomeService" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <bindings>
      <customBinding>
        <binding name="Soap11Binding">
          <textMessageEncoding messageVersion="Soap11" writeEncoding="utf-8">
            <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          </textMessageEncoding>
          <httpTransport allowCookies="true" />
        </binding>
      </customBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true" />
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

¿Alguna pista de alguien? ¡Gracias!

preguntado el 04 de julio de 12 a las 04:07

3 Respuestas

Debe cambiar el enlace de su servicio WCF para basicHttpBinding, Que utiliza SOAP v1.1, mientras wsHttpBinding usos SOAP v1.2.

Mira aquí: SOAP 1.1 vs SOAP 1.2

También puede crear su enlace personalizado y especificar explícitamente que desea SOAP 1.1:

<customBinding>  
    <binding name="Soap11Binding">  
        <textMessageEncoding messageVersion="Soap11" writeEncoding="utf-8">  
            <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"  
                maxBytesPerRead="4096" maxNameTableCharCount="16384" />  
        </textMessageEncoding>  
        <httpTransport allowCookies="true" />  
    </binding>  
</customBinding>  

Respondido 04 Jul 12, 08:07

Gracias, probé basicHttpBinding, como dije anteriormente, pero la salida predeterminada de basicHttpBinding tiene el formato del segundo conjunto de Solicitud/Respuesta que publiqué. Necesito que la salida sea como el primer conjunto. - Modesto

@Modesto: ¿Puede publicar cómo se ven sus pares de respuesta/solicitud con basicHttpBinding? - marcel n

Acabo de probar con el customBinding que ofreces (utilizado tanto en el host como en el cliente). Pero recibo el mismo mensaje en movimiento. - Modesto

@Modesto: Pero eso no puede ser. ¿Puede actualizar su pregunta con la configuración del servicio (enlace, servicio y punto final)? Algo debe estar saliendo mal. - marcel n

Gracias por cierto. Hasta ahora, solo pude recrear el formato solicitado, usando un servicio .ASMX, pero no usando WCF (no sé si es posible) - Modesto

Puede usar un codificador de mensajes personalizado para formatear el mensaje para que sea exactamente como lo necesita. Esta es una URL de cómo implementarlo: http://msdn.microsoft.com/en-us/library/ms751486.aspx

En el método WriteMessage puede hacer los cambios necesarios en el mensaje.

Respondido 05 Jul 12, 08:07

Esta es una respuesta brutal, pero parece la correcta. ¡Crear un formato personalizado para WCF no es fácil! - Pablo Keister

Para un control completo sobre la respuesta en wcf, debe usar [MessageContract].

[MessageContract] son ​​clases simples, que se utilizan además como un paquete SOAP para la transmisión.

Al considerar su requisito, debe usar MessageContract.

Respondido 15 Jul 14, 14:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.