SOAP - WCF:OperationContract 未接收输入参数
SOAP - WCF: OperationContract not receiving input parameters
我正在 WCF 中构建一个新的 SOAP API 以替换已建立的与客户端服务器的通信 中的旧服务。
这里的收获是:
- 不允许我编辑客户端
- Current API(我正在替换的那个)非常旧并且在 wsdl 文件中生成所有内容,而不是 singleWsdl 和 wsdl
我设法建立了与客户端的连接并且正在调用我的操作,但是我没有收到任何输入参数。我确信正在发送参数,因为我有另一个解决方案,它像当前客户端一样工作,用于我的测试目的。当它指向旧的 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/
我正在 WCF 中构建一个新的 SOAP API 以替换已建立的与客户端服务器的通信 中的旧服务。 这里的收获是:
- 不允许我编辑客户端
- Current API(我正在替换的那个)非常旧并且在 wsdl 文件中生成所有内容,而不是 singleWsdl 和 wsdl
我设法建立了与客户端的连接并且正在调用我的操作,但是我没有收到任何输入参数。我确信正在发送参数,因为我有另一个解决方案,它像当前客户端一样工作,用于我的测试目的。当它指向旧的 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/