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

时间:2018-01-05 11:29:16

标签: wcf soap input wsdl operation

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

  • 我不允许编辑客户端
  • 当前的API(我要替换的那个)非常老,并且在wsdl文件中生成所有内容,而不是singleWsdl和wsdl

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

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

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

旧的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,所以我的理解可能不正确,或者我可能只是在寻找错误的地方。如果有人有任何想法,如果你愿意和我分享,我将非常感激。

1 个答案:

答案 0 :(得分:0)

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

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

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

我在wsdl中的message元素也是自动格式化的,其中包含错误的名称和命名空间参数。 在我的情况下,名称包括我的项目的名称空间,服务名称和特定的操作名称,而我需要它只是操作名称。

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

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

要设置项目以使用我遵循以下注释的包:

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