wcf - 如何在.net core项目中设置soapclient的超时

标签 wcf soap asp.net-core-2.0 timeoutexception

我必须在 .Net Core 2.0 项目中使用 SOAP 服务。我添加了服务引用,如以下链接所述:( Missing link, 404 )

对于某些方法,服务运行良好。但是,某些方法需要很长时间(由于操作服务正在执行),在这种情况下程序会抛出异常:“System.Net.Http.WinHttpException:操作超时”

我尝试设置超时值,但没有效果。

MyService.MyServiceSoapClient Pr = 
    new MyService.MyServiceSoapClient(
            new MyService.MyServiceSoapClient.EndpointConfiguration());

Pr.InnerChannel.OperationTimeout = new TimeSpan(0, 10, 0);

我还检查了以下链接,其中有有关.Net Core中的wcf/soap服务的相关问题:GitHub: dotnet/wcf

但目前还没有解决方案。知道如何解决这个问题吗?

最佳答案

好的,如果有人遇到同样的问题,我将发布我找到的解决方案。似乎其他人也遇到了这个问题并提出了问题here

据我了解,这是 .Net Core 2.0 的一般错误,如果请求持续时间超过 30 秒,就会发生该错误。

正如上面的链接所示,他们发布了一个解决方案 here 。这对我有用。解决方案要求每次在发出真实请求之前向服务发出虚假请求,以便可以更改超时设置。为了避免这种情况,我建议您捕获“CommunicationException”,并在该捕获中应用解决方案。因此,只有在确实需要时才调用额外的电话。我正在复制代码,以防万一链接失效(代码的所有学分均归 https://github.com/mconnew/ )

   static void Main(string[] args)
    {
        var client = new SimpleServiceClient();
        client.OpenAsync().GetAwaiter().GetResult();
        client.DelayedResponseAsync(2000).GetAwaiter().GetResult();
        var channel = client.InnerChannel;
        var httpChannelFactory = client.InnerChannel.GetProperty<IChannelFactory>();
        var cacheField = httpChannelFactory.GetType().GetField("_httpClientCache", BindingFlags.NonPublic | BindingFlags.Instance);
        var httpClientCache = cacheField.GetValue(httpChannelFactory);
        var cacheDictionaryField = httpClientCache.GetType().GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance);

        IDictionary cacheDictionary = (IDictionary)cacheDictionaryField.GetValue(httpClientCache);
        foreach(var cacheKey in cacheDictionary.Keys)
        {
            var cacheEntry = cacheDictionary[cacheKey];
            var valueField = cacheEntry.GetType().GetField("value", BindingFlags.NonPublic | BindingFlags.Instance);
            HttpClient httpClient = (HttpClient)valueField.GetValue(cacheEntry);
            FixHttpClient(httpClient);
        }

        client.DelayedResponseAsync(50000).GetAwaiter().GetResult();
        Console.WriteLine("Done");
        Console.ReadLine();
    }
    private static void FixHttpClient(HttpClient httpClient)
    {
        var handlerField = typeof(HttpMessageInvoker).GetField("_handler", BindingFlags.NonPublic | BindingFlags.Instance);
        DelegatingHandler delegatingHandler = (DelegatingHandler)handlerField.GetValue(httpClient); // Should be of type ServiceModelHttpMessageHandler
        WinHttpHandler winHttpHandler = (WinHttpHandler)delegatingHandler.InnerHandler;
        WinHttpHandler newHandler = new WinHttpHandler();
        newHandler.ServerCredentials = winHttpHandler.ServerCredentials;
        newHandler.CookieUsePolicy = winHttpHandler.CookieUsePolicy;
        newHandler.ClientCertificates.AddRange(winHttpHandler.ClientCertificates);
        newHandler.ServerCertificateValidationCallback = winHttpHandler.ServerCertificateValidationCallback;
        newHandler.Proxy = winHttpHandler.Proxy;
        newHandler.AutomaticDecompression = winHttpHandler.AutomaticDecompression;
        newHandler.PreAuthenticate = winHttpHandler.PreAuthenticate;
        newHandler.CookieContainer = winHttpHandler.CookieContainer;

        // Fix the timeouts
        newHandler.ReceiveHeadersTimeout = Timeout.InfiniteTimeSpan;
        newHandler.ReceiveDataTimeout = Timeout.InfiniteTimeSpan;
        newHandler.SendTimeout = Timeout.InfiniteTimeSpan;

        var servicemodelHttpHandlerInnerHandlerField = delegatingHandler.GetType().GetField("_innerHandler", BindingFlags.NonPublic | BindingFlags.Instance);
        servicemodelHttpHandlerInnerHandlerField.SetValue(delegatingHandler, newHandler);
        var delegatingHandlerInnerHandlerField = typeof(DelegatingHandler).GetField("_innerHandler", BindingFlags.NonPublic | BindingFlags.Instance);
        delegatingHandlerInnerHandlerField.SetValue(delegatingHandler, newHandler);}

关于wcf - 如何在.net core项目中设置soapclient的超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48079244/

相关文章:

c# - 不同角色的不同 API 功能

c# - 由于 Base64 错误,无法将图像上传到数据库

java - 如何使用 apache.cxf java 从响应信封中提取 soap header

c# - 返回的 soap 客户端不能破坏响应体 net core 的稳定性

python - 通过 python suds 在 Web 服务链接中调用 SAS 存储过程

c# - cookie 过期后如何返回 401 状态而不是 302 重定向?

c# - Asp.net core 2.0 中间件 - 使用在运行时更改的应用程序设置中的参数

c# - IParameterInspector .BeforeCall 中的引用类型字段为 null

c# - 通过消息契约重用类型

c# - 如何从浏览器调用 WCF 服务 OperationContract?