Solicitudes de SOAP en .NET

Estamos intentando usar solicitudes SOAP para interactuar con una API de reserva usando Visual Studio C #.

Nos hemos interconectado con un servicio web de otra API sin problema, pero este está resultando problemático.

Lo hemos agregado como Referencia de servicio y Visual Studio ha generado todas las clases para él y las entradas web.config para que todo parezca bien.

Sin embargo, cuando intentamos realizar una solicitud simple al servicio SOAP del cliente, obtenemos el siguiente error:

Namespace = 'com.hrs.soap.hrs' no es compatible con rpc \ literal SOAP. El elemento envoltorio debe ser no calificado.

El código es:

PingRequest pingrequest = new PingRequest();    
SoapServiceClient service = new SoapServiceClient();
service.ping(pingrequest);

Esto se ha agregado en el archivo web.config:

<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="HRSSoapServiceBinding" closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
            maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
            messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
            useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None"
                realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="..."
          binding="basicHttpBinding" bindingConfiguration="HRSSoapServiceBinding"
          contract="HRSService.HRSSoapService" name="HRSSoapServicePort" />
    </client>
  </system.serviceModel>

De acuerdo con la documentación, la solicitud debe ser similar a la siguiente:

<complexType name="PingRequest">
    <complexContent>
        <extension base="tns:Request">
            <sequence>
                <element name="echoData" type="xsd:string"/>
            </sequence>
        </extension>
    </complexContent>
</complexType>

Rastreo de pila completa a continuación:

[InvalidOperationException: Namespace='com.hrs.soap.hrs' is not supported with rpc\literal SOAP. The wrapper element has to be unqualified.]
   System.Xml.Serialization.XmlReflectionImporter.CheckTopLevelAttributes(XmlAttributes a, String accessorName) +842469
   System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +4072651
   System.Xml.Serialization.XmlReflectionImporter.ImportMemberMapping(XmlReflectionMember xmlReflectionMember, String ns, XmlReflectionMember[] xmlReflectionMembers, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +699
   System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping(XmlReflectionMember[] xmlReflectionMembers, String ns, Boolean hasWrapperElement, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +298

[InvalidOperationException: There was an error reflecting 'HRSException'.]
  System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping(XmlReflectionMember[] xmlReflectionMembers, String ns, Boolean hasWrapperElement, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +1051
   System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping(String elementName, String ns, XmlReflectionMember[] members, Boolean hasWrapperElement, Boolean rpc, Boolean openModel, XmlMappingAccess access) +137
   System.ServiceModel.Description.XmlSerializerImporter.ImportMembersMapping(XmlName elementName, String ns, XmlReflectionMember[] members, Boolean hasWrapperElement, Boolean rpc, Boolean isEncoded, String mappingKey) +237
   System.ServiceModel.Description.OperationReflector.ImportMembersMapping(String elementName, String ns, XmlReflectionMember[] members, Boolean hasWrapperElement, Boolean rpc, String mappingKey) +134
   System.ServiceModel.Description.OperationReflector.ImportFaultElement(FaultDescription fault, XmlQualifiedName& elementName) +458
   System.ServiceModel.Description.OperationReflector.GenerateXmlSerializerFaultContractInfos() +153
   System.ServiceModel.Description.OperationReflector.EnsureMessageInfos() +929
   System.ServiceModel.Description.Reflector.EnsureMessageInfos() +98
   System.ServiceModel.Description.XmlSerializerOperationBehavior.CreateFormatter() +32
   System.ServiceModel.Description.XmlSerializerOperationBehavior.System.ServiceModel.Description.IOperationBehavior.ApplyClientBehavior(OperationDescription description, ClientOperation proxy) +42
   System.ServiceModel.Description.DispatcherBuilder.BindOperations(ContractDescription contract, ClientRuntime proxy, DispatchRuntime dispatch) +94
   System.ServiceModel.Description.DispatcherBuilder.ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime clientRuntime) +247
   System.ServiceModel.Description.DispatcherBuilder.BuildProxyBehavior(ServiceEndpoint serviceEndpoint, BindingParameterCollection& parameters) +342
   System.ServiceModel.Channels.ServiceChannelFactory.BuildChannelFactory(ServiceEndpoint serviceEndpoint, Boolean useActiveAutoClose) +85
   System.ServiceModel.ChannelFactory.CreateFactory() +43
   System.ServiceModel.ChannelFactory.OnOpening() +23
   System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +274
   System.ServiceModel.ChannelFactory.EnsureOpened() +107
   System.ServiceModel.ChannelFactory`1.CreateChannel(EndpointAddress address, Uri via) +134
   System.ServiceModel.ChannelFactory`1.CreateChannel() +29
   System.ServiceModel.ClientBase`1.CreateChannel() +91
   System.ServiceModel.ClientBase`1.CreateChannelInternal() +26
   System.ServiceModel.ClientBase`1.get_Channel() +261
   BLL.HRSService.HRSSoapServiceClient.ping(HRSPingRequest pingRequest) in C:\Code\-------\BLL\Service References\HRSService\Reference.cs:15850
   -------.Test.Ping() in C:\Code\-------\Test.aspx.cs:48
   -------.Test.Page_Load(Object sender, EventArgs e) in C:\Code\-------\Test.aspx.cs:24
   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
   System.Web.UI.Control.OnLoad(EventArgs e) +91
   System.Web.UI.Control.LoadRecursive() +74
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2207

Instalamos Fiddler y no hay ninguna solicitud XML que podamos ver, probablemente porque lanza una excepción antes de que se envíe algo.

¿Qué es exactamente lo que necesitamos cambiar en nuestra configuración para que esto funcione?

ACTUALIZAR

WSDL: Disponible [aquí] [1]

ACTUALIZAR

Siguiendo los excelentes consejos de davidfmatheson, he copiado el WSDL localmente y he realizado las enmiendas como se sugiere. Sigo recibiendo el mismo error aunque posiblemente en un lugar diferente:

[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
        BLL.HRSService.pingResponse BLL.HRSService.HRSSoapService.ping(BLL.HRSService.pingRequest request) {
            return base.Channel.ping(request);
        }

        public BLL.HRSService.HRSPingResponse ping(BLL.HRSService.HRSPingRequestWrapper ping1) {
            BLL.HRSService.pingRequest inValue = new BLL.HRSService.pingRequest();
            inValue.ping = ping1;
            BLL.HRSService.pingResponse retVal = ((BLL.HRSService.HRSSoapService)(this)).ping(inValue);
            return retVal.pingResponse1;
        }

La línea que falla es lavolver base.Channel.ping (solicitud); con errorNamespace = 'com.hrs.soap.hrs' no es compatible con rpc \ literal SOAP. El elemento envoltorio debe ser no calificado.

También intenté establecer explícitamente el SOAPBinding:

Exception Details: System.InvalidOperationException: Namespace='com.hrs.soap.hrs' is not supported with rpc\literal SOAP. The wrapper element has to be unqualified.

Source Error: 

Line 15917:        [System.Web.Services.Protocols.SoapDocumentMethod(Use = System.Web.Services.Description.SoapBindingUse.Literal)]
Line 15918:        BLL.HRSService.pingResponse BLL.HRSService.HRSSoapService.ping(BLL.HRSService.pingRequest request) {
Line 15919:            return base.Channel.ping(request);
Line 15920:        }
Line 15921:

Bien, ahora he modificado el estilo de enlace de SOAP para documentar en mi WSDL local y he recreado las clases y tengo un error diferente:

Unable to generate a temporary class (result=1).
error CS0030: Cannot convert type 'BLL.HRSService.HRSHotelTaxDetail[]' to 'BLL.HRSService.HRSHotelTaxDetail'
error CS0030: Cannot convert type 'BLL.HRSService.HRSHotelAmenityCriterion[]' to 'BLL.HRSService.HRSHotelAmenityCriterion'
error CS0029: Cannot implicitly convert type 'BLL.HRSService.HRSHotelTaxDetail' to 'BLL.HRSService.HRSHotelTaxDetail[]'
error CS0029: Cannot implicitly convert type 'BLL.HRSService.HRSHotelAmenityCriterion' to 'BLL.HRSService.HRSHotelAmenityCriterion[]'

StackTrace:

[InvalidOperationException: Unable to generate a temporary class (result=1).
error CS0030: Cannot convert type 'BLL.HRSService.HRSHotelTaxDetail[]' to 'BLL.HRSService.HRSHotelTaxDetail'
error CS0030: Cannot convert type 'BLL.HRSService.HRSHotelAmenityCriterion[]' to 'BLL.HRSService.HRSHotelAmenityCriterion'
error CS0029: Cannot implicitly convert type 'BLL.HRSService.HRSHotelTaxDetail' to 'BLL.HRSService.HRSHotelTaxDetail[]'
error CS0029: Cannot implicitly convert type 'BLL.HRSService.HRSHotelAmenityCriterion' to 'BLL.HRSService.HRSHotelAmenityCriterion[]'
]
   System.Xml.Serialization.Compiler.Compile(Assembly parent, String ns, XmlSerializerCompilerParameters xmlParameters, Evidence evidence) +1024
   System.Xml.Serialization.TempAssembly.GenerateAssembly(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, Evidence evidence, XmlSerializerCompilerParameters parameters, Assembly assembly, Hashtable assemblies) +1997
   System.Xml.Serialization.XmlSerializer.GetSerializersFromCache(XmlMapping[] mappings, Type type) +772
   System.Xml.Serialization.XmlSerializer.FromMappings(XmlMapping[] mappings, Type type) +4066268
   System.ServiceModel.Description.SerializerGenerationContext.GenerateSerializers() +185
   System.ServiceModel.Description.SerializerGenerationContext.GetSerializer(Int32 handle) +102
   System.ServiceModel.Description.MessageInfo.get_BodySerializer() +17
   System.ServiceModel.Dispatcher.XmlSerializerOperationFormatter.SerializeBody(XmlDictionaryWriter writer, MessageVersion version, String action, MessageDescription messageDescription, Object returnValue, Object[] parameters, Boolean isRequest) +112

[CommunicationException: There was an error in serializing body of message pingRequest: 'Unable to generate a temporary class (result=1).
error CS0030: Cannot convert type 'BLL.HRSService.HRSHotelTaxDetail[]' to 'BLL.HRSService.HRSHotelTaxDetail'
error CS0030: Cannot convert type 'BLL.HRSService.HRSHotelAmenityCriterion[]' to 'BLL.HRSService.HRSHotelAmenityCriterion'
error CS0029: Cannot implicitly convert type 'BLL.HRSService.HRSHotelTaxDetail' to 'BLL.HRSService.HRSHotelTaxDetail[]'
error CS0029: Cannot implicitly convert type 'BLL.HRSService.HRSHotelAmenityCriterion' to 'BLL.HRSService.HRSHotelAmenityCriterion[]'
'.  Please see InnerException for more details.]
   System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +9440287
   System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +345
   BLL.HRSService.HRSSoapService.ping(pingRequest request) +0
   BLL.HRSService.HRSSoapServiceClient.BLL.HRSService.HRSSoapService.ping(pingRequest request) in C:\Code\...\BLL\Service References\HRSService\Reference.cs:17311
   BLL.HRSService.HRSSoapServiceClient.ping(HRSPingRequestWrapper ping1) in C:\Code\...\BLL\Service References\HRSService\Reference.cs:17317
   BLL.HRS_Integration.Ping() in C:\Code\...\BLL\General\HRSIntegration.cs:55
   VenueOptions.Test.Page_Load(Object sender, EventArgs e) in C:\Code\...\Test.aspx.cs:24
   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
   System.Web.UI.Control.OnLoad(EventArgs e) +91
   System.Web.UI.Control.LoadRecursive() +74
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2207

Solicitud finalmente hecha!

Fiddler muestra lo siguiente para PING:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><ping xmlns="com.hrs.soap.hrs"><pingRequest xmlns=""><credentials><clientType>...</clientType><clientKey>...</clientKey><clientPassword>...</clientPassword><customerKey xsi:nil="true"/></credentials><myHRSCredentials xsi:nil="true"/><echoData>Hello HRS</echoData></pingRequest></ping></s:Body></s:Envelope>

Respuestas a la pregunta(1)

Su respuesta a la pregunta