.NET中的SOAP请求

我们正在尝试使用SOAP请求使用Visual Studio C#与预订API进行交互。

我们已经与另一个API的Web服务接口而没有问题,但这个问题certificate是有问题的。

我们已将其添加为服务引用,并且Visual Studio已为其生成所有类和web.config条目,以便一切看起来都很好。

但是,当我们尝试向客户端SOAP服务发出简单请求时,我们会收到以下错误:

rpc \ literal SOAP不支持Namespace =’com.hrs.soap.hrs’。 包装元素必须是不合格的。

代码是:

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

这是Web.config文件中添加的内容:

                 

根据文档,请求应如下所示:

          

完整堆栈跟踪如下:

 [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 

我们安装了Fiddler并且没有我们可以看到的XML请求,大概是因为它在发送任何内容之前抛出exception。

我们在设置中需要更改什么来使其工作?

UPDATE

WSDL:可用[这里] [1]

UPDATE

根据davidfmatheson的出色建议,我在本地复制了WSDL并按照建议进行了修改。 尽管可能在不同的地方,我仍然会得到同样的错误:

 [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; } 

失败的行是返回base.Channel.ping(request); 错误命名空间=’com.hrs.soap.hrs’不受rpc \ literal SOAP支持。 包装元素必须是不合格的。

我还尝试显式设置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: 

好了,现在我已经将SOAP Binding样式修改为在本地WSDL中记录并重新创建了类,我有一个不同的错误:

 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[]' 

堆栈跟踪:

 [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 

请求终于发了!

Fiddler为PING显示以下内容:

 .........Hello HRS 

您正在尝试从.NET使用RPC-literal服务,因此您可能必须将服务转换为doc-literal。 请参阅MSDN博客 。

编辑:更完整的答案

目标是能够使用doc-literal,但仍然发送相同的消息。 让我们关注ping操作。 现在你的WSDL的类型定义为:

          

并且您的消息定义为:

    

你的绑定定义为:

                

所以在本地我们将“rpc”更改为“document”,然后将WSDL修复为实际的document / literal:

                ...    

现在生成此WSDL并查看它是否发送ping请求。 如果您没有修复响应结构,它可能无法理解返回的内容,但您至少应该看到通过网络发送的请求。 您可以使用SoapUI加载两个WSDL并查看生成的请求类型。 目标是发送相同的请求,只使用document / literal而不是rpc / literal。