SOAP - WCF:OperationContract 未接收输入参数

SOAP - WCF: OperationContract not receiving input parameters

我正在 WCF 中构建一个新的 SOAP API 以替换已建立的与客户端服务器的通信 中的旧服务。 这里的收获是:

我设法建立了与客户端的连接并且正在调用我的操作,但是我没有收到任何输入参数。我确信正在发送参数,因为我有另一个解决方案,它像当前客户端一样工作,用于我的测试目的。当它指向旧的 API 时,它一切正常并发送输入,但是当我将它指向我的 API 时,它只调用操作但没有提到的输入。

我在我的测试解决方案中为每个 API 添加了服务引用以查看差异,我注意到输入复杂类型的命名空间不同,但这是我当前的问题: 操作的名称与其作为输入参数的复杂类型的名称相同,并且它们都需要在同一个命名空间中(我假设)。我没想到这是个问题,但在我的 singleWsdl 文件中,我可以看到我所有的 操作也列为 <types> 中的元素,它们的输入嵌套为 <complexType>s.

我也想知道问题是我的 wsdl 文件中的导入问题还是我正在 替换旧的 wsdl 文件结构已经与新的 wsdl/singleWsdl 建立通信的简单事实文件结构,它不知道去哪里寻找复杂类型。

old API Reference.cs(添加服务参考作为 Web 参考):

[System.Web.Services.Protocols.SoapRpcMethodAttribute("http://www.namespaceURL.com/InternalApi/UpdateScheduler", RequestNamespace="http://www.namespaceURL.com/InternalApi", ResponseNamespace="http://www.namespaceURL.com/InternalApi", Use=System.Web.Services.Description.SoapBindingUse.Literal)]
    [return: System.Xml.Serialization.XmlElementAttribute("return")]
    public returnUpdateScheduler UpdateScheduler([System.Xml.Serialization.XmlElementAttribute("UpdateScheduler")] UpdateScheduler UpdateScheduler1) {
        object[] results = this.Invoke("UpdateScheduler", new object[] {
                    UpdateScheduler1});
        return ((returnUpdateScheduler)(results[0]));
    }

新的 singleWsdl 文件类型:

<wsdl:types>
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.namespaceURL.com/InternalApi">
    <xs:import namespace="http://schemas.datacontract.org/2004/07/PairLeague"/>
    <xs:element name="UpdateScheduler">
      <xs:complexType>
        <xs:sequence>
          <xs:element minOccurs="0" name="UpdateScheduler" nillable="true" type="tns:UpdateScheduler"/>
        </xs:sequence>
      </xs:complexType>
    </xs:element>
  </xs:schema>
</wsdl:types>

新的 wsdl 文件导入:

<wsdl:types>
  <xsd:schema targetNamespace="http://www.namespaceURL.com/Imports">
    <xsd:import schemaLocation="http://localhost:18139/IPairLeague.svc?xsd=xsd0" namespace="http://www.namespaceURL.com/InternalApi" />
    <xsd:import schemaLocation="http://localhost:18139/IPairLeague.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
    <xsd:import schemaLocation="http://localhost:18139/IPairLeague.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/PairLeague" />
  </xsd:schema>
</wsdl:types>

这是我第一次使用 SOAP 和 WCF,所以我的理解可能不正确,或者我可能只是看错了地方。如果有人有任何想法,请与我分享,我将不胜感激。

最终的解决方案是将[ServiceContract]的OperationFormatStyle设置为'Rpc'

[ServiceContract(Namespace = "http://www.example.com/Service"),
 XmlSerializerFormat(Style = OperationFormatStyle.Rpc)]

似乎在尝试与 3rd 方服务建立连接时,您需要使用相同的名称和命名空间以及匹配相同的消息结构。由于我模仿的是RPC结构的SOAP接口,所以我不允许使用MessageContracts,但我需要指定发送DataContracts的消息结构。通过将样式参数设置为 RPC,wsdl 中的 DataContracts (ComplexTypes) 可以在消息标签中正确格式化。如果没有将样式设置为 Rpc,我的操作无法识别任何输入类型参数,当我将 DataContract 设置为 MessageContract 时,可以识别输入类型,但在调用操作时从未填充传递的值。请注意,这只是我基于对代码进行试验得出的推论,它现在工作的真正原因可能完全不同,但现在对我来说最重要的是 - 它正在工作!

我在 wsdl 中的消息元素也被自动格式化,其中包含不正确的名称和命名空间参数。 在我的例子中,名称包括我的项目的命名空间、服务名称和特定的操作名称,而我只需要它是操作名称。

我还专注于只生成一个没有任何包含的大 wsdl 文件,因为第 3 方服务需要这种格式。目前它似乎没有给我任何问题,但我可能会在稍后的过程中遇到问题。

我在这件事上的解决方案是通过 NuGet 实现 WCFExtrasPlus 包。在 Visual Studio 中,您可以通过项目面板菜单打开 NuGet 包管理器并搜索 WCFExtrasPlus 包并安装它。

要将您的项目设置为使用我遵循以下说明的包:

http://george2giga.com/development/wcf-merge-wsdl-in-a-single-file/