【问题标题】:Service reference generates soap proxy incompatible with the web service服务引用生成soap代理与web服务不兼容
【发布时间】:2018-04-16 14:12:53
【问题描述】:

根据我用来获取引用的 WSDL,我尝试使用的操作定义如下。

出于安全原因,我在所有引用中都将服务名称替换为“MyService”。

<message name="MyService_fetchOperation">
    <part name="user" type="xsd:string"/>
    <part name="passwd" type="xsd:string"/>
    <part name="package" type="xsd:string"/>
    <part name="txType" type="xsd:string"/>
    <part name="swref" type="xsd:string"/>
    <part name="force" type="xsd:string"/>
</message>

我正在用 C# 构建一个请求:

using (var client = new MyService.MyServiceGatewayClient())
{
    response = await client.fetchOperationAsync(USER, PASS, PACKAGE, "509", "", "0");
}

在这个问题的上下文中,此请求的作用或用途无关紧要。

请求(来自 Fiddler)如下所示:

POST https://myservice.gateway.thing HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Host: myservice.gateway.thing
Content-Length: 816
Expect: 100-continue
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Header>
        <ActivityId CorrelationId="04a608d9-fbfd-4a4d-b26b-e57098352dff" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">
80000162-0005-fb00-b63f-84710c7967bb</ActivityId>
        <VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo6GoRTTueVZOiE2QS303TwoAAAAA6GBrNOg50ESdf6d7KUk2nMLdj/sn/wxCqk4Df+zV1yQACQAA</VsDebuggerCausalityData>
    </s:Header>
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <fetchOperation xmlns="http://myservice.gateway.thing/v1">
            <user>TEST9876</user>
            <passwd>test4139</passwd><!-- plain text password ftw! -->
            <package>SWITCHON</package>
            <txType>509</txType>
            <swref/>
            <force>0</force>
        </fetchOperation>
    </s:Body>
</s:Envelope>

此请求在服务上返回一个错误,即找不到子元素“用户”。

我已经向服务管理员查询过这个问题,他说我需要重新定义 fetchOperation 标记中的命名空间,并给出了以下示例:

<v1:fetchOperation xmlns:v1="http://myservice.gateway.thing/v1">
    ...
</v1:fetchOperation>

我有两个问题:

  1. 为什么需要这样的改变?这将如何解决服务在请求中看不到“缺失”元素的问题?
  2. 为什么,如果需要此更改,在 VS 中添加服务引用不会生成实际工作的 SOAP 代理?是服务开发人员的不一致还是我做错了什么?

【问题讨论】:

  • 我使用生成的代码遇到了同样的问题。命名空间是问题之一。我已经结交了很多客户,只有在使用 .net 的其他语言开发服务时才发现问题。
  • 我已经有同样的问题,我解决了使用svcutil.exe命令行工具生成代理类,像这样:svcutil http://url/servicesvc /Language=c#
  • @RicardoPontual 您能否添加一个涵盖您用来执行此操作的步骤的答案?哦,这是在带有 Windows SDK 的 Windows 10 上吗?我现在很遗憾地坚持使用 Windows 8。不过,如果您能提供更多信息,它可能会对其他人有所帮助
  • 您没有向我们展示任何 WSDL,并且 xml 的 sn-p 建议面向消息 (Java) 而不是 RPC (.NET) 样式。非常注意您拥有的选项(VS 向导或 cmd 行)。 SvcUtil可以插入一些值得一读的cmets。

标签: c# web-services wcf


【解决方案1】:

为服务生成代理客户端的另一种方法是使用 svutil.exe,这是一个命令行工具,用于从元数据、Web 或 wsdl 文件生成服务模型代码。

Microsoft Docs svcutil.exe

它包含在 Visual Studio 安装中,您可以打开 Developer Command Prompt 并像这样执行它:

svcutil http://url/service.svc /Language=c#

您还可以使用 Microsoft Windows SDK 安装 svcutilhttps://www.microsoft.com/en-us/download/details.aspx?id=8279

举一个我使用过这个服务的真实例子:http://www.chemspider.com/MassSpecAPI.asmx

svcutil http://www.chemspider.com/MassSpecAPI.asmx /Language=c#

它是生成MassSpecAPI.cs 文件,在生成的代理类下面的一部分:

//------------------------------------------------------------------------------
// <auto-generated>
/ ....
// </auto-generated>
//------------------------------------------------------------------------------

[assembly: System.Runtime.Serialization.ContractNamespaceAttribute("http://www.chemspider.com/", ClrNamespace="www.chemspider.com")]

namespace www.chemspider.com
{
    using System.Runtime.Serialization;


    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
    [System.Runtime.Serialization.CollectionDataContractAttribute(Name="ArrayOfString", Namespace="http://www.chemspider.com/", ItemName="string")]
    public class ArrayOfString : System.Collections.Generic.List<string>
    {
    }

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
    [System.Runtime.Serialization.DataContractAttribute(Name="ECompression", Namespace="http://www.chemspider.com/")]
    public enum ECompression : int
    {

        [System.Runtime.Serialization.EnumMemberAttribute()]
        eGzip = 0,
    }

【讨论】:

  • 但这基本上是 VS Add-Reference 所做的,你必须使用命令行选项。
  • 是的@HenkHolterman,你说的很对,但是我遇到了一些服务问题,无论我如何尝试,VS 都没有正确生成代理类,svcutil 解决了这个问题。
  • 完成,谢谢。现在我该如何实现呢?我认为这不仅仅是在我的项目中复制粘贴的问题吗?
  • 是的,只需复制并添加到您的项目中。生成的文件包含使用服务所需的所有内容。
  • 该文件看起来与 ASP.NET 放入项目中的内容非常相似。尽管如此,我还是会把它放到一个新项目中并尝试使用它。
猜你喜欢
  • 2013-09-03
  • 2019-02-25
  • 1970-01-01
  • 2011-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多