使用 .NET Core 3.1 生成 WCF wsdl 客户端的问题

Posted

技术标签:

【中文标题】使用 .NET Core 3.1 生成 WCF wsdl 客户端的问题【英文标题】:Problems with generating WCF wsdl client with .NET Core 3.1 【发布时间】:2020-12-02 04:47:41 【问题描述】:

我尝试连接到一个开放的 API:https://swea.riksbank.se/sweaWS/wsdl/sweaWS_ssl.wsdl

我在 VS 2019 16.7.1 中生成客户端就好了,并创建了 Reference.cs 文件

当我尝试执行远程功能时,我得到一个 404。

使用邮递员我可以很好地执行远程功能,但我注意到我需要使用这个确切的内容类型并请求,否则我也会得到 404

内容类型:application/soap+xml;charset=UTF-8;action="urn:getCalendarDays"

请求:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://swea.riksbank.se/xsd">
    <soap:Header/>
    <soap:Body>
        <xsd:getCalendarDays>
            <datefrom>2019-08-12</datefrom>
            <dateto>2021-08-12</dateto>
        </xsd:getCalendarDays>
    </soap:Body>
</soap:Envelope>

通过上述邮递员设置,我得到了正确数据的响应。

但是如果我尝试通过我的客户端执行相同的操作,我会得到一个 404。所以我虽然我会使用提琴手调试 WCF 客户端,但我似乎无法为其添加代理,我的代码

        var client = new SweaWebServicePortTypeClient(SweaWebServicePortTypeClient.EndpointConfiguration.SweaWebServiceHttpSoap12Endpoint, new EndpointAddress("https://swea.riksbank.se/sweaWS/services/SweaWebServiceHttpSoap12Endpoint"));
        var binding = client.Endpoint.Binding as CustomBinding;
        var htbe = binding.Elements.Find<HttpTransportBindingElement>();

        var prox = WebRequest.GetSystemWebProxy();

        htbe.ProxyAddress = new Uri("http://127.0.0.1:8866");
        htbe.BypassProxyOnLocal = false;
        htbe.UseDefaultWebProxy = false;
        //htbe.ProxyAuthenticationScheme = AuthenticationSchemes.Anonymous;

        var days = await client.getCalendarDaysAsync(DateTime.UtcNow.Date, DateTime.UtcNow.Date.AddDays(31));

对 client.getCalendarDaysAsync 的调用会生成此异常

'使用非空代理时,必须将 WindowsProxyUsePolicy 属性设置为 WindowsProxyUsePolicy.UseCustomProxy。'

Google 空手而归,请指教。谢谢

编辑:现在我运行自己的客户端,但它很乱,如果可能的话想使用内置函数

        private async Task<Dictionary<DateTime, bool>> GetBankDaysRemote(DateTime from, DateTime to)
        
            var format = "yyyy-MM-dd";
            var client = _clientFactory.CreateClient();
            var message =
                $@"<soap:Envelope xmlns:soap=""http://www.w3.org/2003/05/soap-envelope"" xmlns:xsd=""http://swea.riksbank.se/xsd"">
    <soap:Header/>
    <soap:Body>
        <xsd:getCalendarDays>
            <datefrom>from.ToString(format)</datefrom>
            <dateto>to.ToString(format)</dateto>
        </xsd:getCalendarDays>
    </soap:Body>
</soap:Envelope>";

            var stream = GetTextStream(message);

            var req = new HttpRequestMessage
            
                Method = HttpMethod.Post,
                RequestUri = new Uri("https://swea.riksbank.se/sweaWS/services/SweaWebServiceHttpSoap12Endpoint"),
                Content = new StreamContent(stream)
            ;
            req.Content.Headers.ContentLength = message.Length;
            req.Content.Headers.TryAddWithoutValidation("Content-Type", @"application/soap+xml;charset=UTF-8;action=""urn:getCalendarDays""");

            var response = await client.SendAsync(req);

            await CheckResponse(response);
            var xml = new XmlDocument();
            xml.LoadXml(await response.Content.ReadAsStringAsync());

            var nsmgr = new XmlNamespaceManager(xml.NameTable);
            nsmgr.AddNamespace("ns0", "http://swea.riksbank.se/xsd");

            var node = xml.SelectSingleNode("//ns0:getCalendarDaysResponse", nsmgr);
            if (node == null) throw new System.Exception("Response does not contain correct getCalendarDaysResponse");
            var bankDays = (getCalendarDaysResponse)new XmlSerializer(typeof(getCalendarDaysResponse)).Deserialize(GetTextStream(node.OuterXml));
            return bankDays.@return.ToDictionary(bd => NullSafe(bd.caldate).Date, bd => bd.bankday == "Y");
        

【问题讨论】:

我建议你使用.net框架来创建客户端,因为WCF的一些功能在内核中是不支持的,可能会导致这个问题。 @Dingpeng 请查看我的更新答案,这就是我正在做的事情,继续完成这项任务。但我更愿意使用合适的 wsdl 客户端 .net框架也可以通过添加服务引用来生成代理类,不需要我们自己创建请求。 可以参考这个链接在.net中生成代理类:***.com/questions/61631400/… 使用 cli 生成的代码与我最初的答案相同,但遗憾的是同样的问题 【参考方案1】:

错误消息“使用非空代理时,WindowsProxyUsePolicy 属性必须设置为 WindowsProxyUsePolicy.UseCustomProxy。”与错误有关。

解决方案是将您的库更新到最新版本。

更多信息在这里:

https://github.com/dotnet/runtime/issues/23373

https://github.com/dotnet/wcf/issues/1592

【讨论】:

以上是关于使用 .NET Core 3.1 生成 WCF wsdl 客户端的问题的主要内容,如果未能解决你的问题,请参考以下文章

在 .Net Core 3.1 中使用 WCF 服务

忽略 ASP.NET Core 3.1 中的 WCF 证书错误

连接的服务 WCF 不起作用 NET core 3.1

Wcf 服务在 .NET Core 3.1 控制台应用程序中工作,但在 ASP.NET Core 3.1 Web API 中无法工作

如何在 .NET Core 3.1 应用程序中添加 WCF 服务引用?

如何从 .NET Core 3.1 中的 F# 访问 WCF 服务?