在 .net core 中使用 HttpClient/HttpClientFactory 时出现问题

Getting issue while using HttpClient/HttpClientFactory in .net core

提问人:XamDev 提问时间:4/10/2023 最后编辑:Peter CsalaXamDev 更新时间:6/29/2023 访问量:629

问:

我们已实现在 .NET Core 中使用第三方调用。但是,我们仍然收到以下错误。IHttpClientFactoryHttpClient

System.IO.IOException:无法从传输连接读取数据:由于线程退出或应用程序请求,I/O 操作已中止。

System.Net.Sockets.SocketException (995):由于线程退出或应用程序请求,I/O 操作已中止

System.Net.Http.HttpRequestException:发送请求时出错。---> System.IO.IOException:响应过早结束

这是我们配置事物的代码:

启动 .cs

builder.Services
       .AddHttpClient<IRequestHandler, RequestHandler>()
       .SetHandlerLifetime(TimeSpan.FromMinutes(5))
       .ConfigurePrimaryHttpMessageHandler(_ => new HttpClientHandler
       {
           SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13
       })
       .AddPolicyHandler(retryPolicyHttp);

services.AddTransient<IRequestHandler, RequestHandler>();

请求处理程序 .cs

public class RequestHandler: IRequestHandler
{
    private readonly IHttpClientFactory _httpClientFactory;

    public RequestHandler(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }

    public virtual HttpResponseMessage ExecuteThirdPartyServices(HttpMethod httpMethod, string 
                           postData, RequestModel requestModel)
    {
        using HttpRequestMessage request = new(httpMethod, requestModel.RequestUri);
        
        HttpResponseMessage httpMessageResponse;

        using (var httpClient = _httpClientFactory.CreateClient())
        {
            httpClient.Timeout = TimeSpan.FromMinutes(5);
            httpMessageResponse = httpClient.SendAsync(request).Result;
        }

        return httpMessageResponse;
    }
}

我已经尝试了各种选项来解决这些错误,但我们仍然无法传递这些错误,并且我们不断收到这些错误。

对此的任何帮助都是值得赞赏的!

C# ASP.NET-Core dotnet-httpclient httpclientfactory sendasync

评论

0赞 Angel Yordanov 4/10/2023
看起来您对 感到困惑,请查看此文档,了解您可以实例化其中的各种方法。但通常应使用 和 AddTransient 注册,或使用类型化的 AddHttpClient 注册和 RequestHandler 中的注入。IHttpClientFactoryTyped HttpClientIHttpClientFactoryHttpClient
0赞 XamDev 4/10/2023
@AngelYordanov 感谢您的回复。但是,我已经完全按照文档中解释的方式实现了。你能更新哪些变化,或者如果我错过了什么吗?
0赞 ℍ ℍ 4/10/2023
@XamDev : 当您关注“文档”后,请添加链接。
0赞 Guru Stron 4/10/2023
@XamDev根据用法,我会说强类型方法更适合您(在文档本文中也提到了这一点)。
0赞 Guru Stron 4/10/2023
httpClient.SendAsync(request).**Result** - 不要这样做。用-。asyncawait

答:

1赞 Mustafa Özçetin 4/10/2023 #1

不确定错误的实际原因,但我怀疑该行(因为使用Result)

httpClient.SendAsync(request).Result;

将此方法更改为并等待 () 行怎么样?asyncSendAsync

await httpClient.SendAsync(request);
0赞 Angel Yordanov 4/10/2023 #2

首先关于你的启动.cs。您对同一服务有两个注册,并且 .第二个是正在使用的那个,如果你尝试注入一个 .这意味着您的SSL设置未被使用,并且可能是错误的原因。.AddHttpClient<IRequestHandler, RequestHandler>().AddTransient<IRequestHandler, RequestHandler>();IRequestHandler

我建议您删除第二个注册并使用第一个注册。我也怀疑你需要这个,并建议你应该删除它。SetHandlerLifetime

而不是你的代码中有阻塞。一般来说,你永远不应该一直使用或做异步,但如果你真的想要一个阻塞电话,你最好这样做,看看Stephen Cleary关于这个问题的著作,他应该是你所有异步事情的首选指南。.Result.Result.Wait()GetAwaiter().GetResult()

// Startup.cs

services
    .AddHttpClient<IRequestHandler, RequestHandler>(httpClient =>
    {  
        httpClient.Timeout = TimeSpan.FromMinutes(5);
    })
    .ConfigurePrimaryHttpMessageHandler(_ =>
        new HttpClientHandler
        {
            SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13
        })
    .AddPolicyHandler(retryPolicyHttp);
// RequestHandler.cs

public class RequestHandler: IRequestHandler
{
    private readonly HttpClient _httpClient;

    public RequestHandler(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public virtual HttpResponseMessage ExecuteThirdPartyServices(
        HttpMethod httpMethod,
        string postData,
        RequestModel requestModel)
    {
        using HttpRequestMessage request = new(httpMethod, requestModel.RequestUri);
        
        return _httpClient.SendAsync(request).GetAwaiter().GetResult();
    }
}

评论

0赞 XamDev 4/12/2023
感谢您的回复。但是,我们在 IRequestHandler 接口中有一些方法,这些方法从各自的类中调用以执行第三方服务。通过删除第二个选项,它给出了依赖注入错误
0赞 Angel Yordanov 4/12/2023
没有什么能阻止你这样做,你可能有一些其他的错误配置。
0赞 XamDev 5/4/2023
那么,您能根据上面的代码建议我们可能有什么错误配置吗?