使用 .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 客户端的问题的主要内容,如果未能解决你的问题,请参考以下文章