【问题标题】:Single Instance of HttpClient vs Multiples Instances with ClientCredentias?HttpClient 的单个实例与具有 ClientCredentias 的多个实例?
【发布时间】:2020-03-19 20:19:12
【问题描述】:

我正在使用 HttpClient 向 Soap Api 发出请求。 我看到建议为每个请求使用一次 HttpClient 的单个实例,以避免 SocketException。

在我的桌面应用程序中,我需要发出多个请求,每个请求都有不同的凭据。我这样做就像示例代码一样:

WebRequestHandler requestHandler = new WebRequestHandler();
requestHandler.ClientCertificates.Add(certificate);

using(var client = new HttpClient(requestHandler))
{
    try
    {
        HttpResponseMessage response = await client.PostAsync("https://nfe-homologacao.svrs.rs.gov.br/ws/nfeinutilizacao/nfeinutilizacao4.asmx", httpContent);
        response.EnsureSuccessStatusCode();
        string responseBody = await response.Content.ReadAsStringAsync();
        return responseBody;
    }
    catch (HttpRequestException e)
    {
        return e.Message;
    }
}

但是,我想避免为每个请求创建一个 HttpClient 实例。我看到正确的方法是使用这样的静态实例:

static readonly HttpClient client = new HttpClient();

但是对于静态实例,我无法使用 WebRequestHandler 设置凭据。请注意,每个请求中的凭据都会发生变化。

执行所有请求、避免 SocketException 和使用不同凭据的更好方法是什么?

【问题讨论】:

    标签: c# httpclient x509certificate credentials socketexception


    【解决方案1】:

    通常应为创建的每个请求设置每个请求的凭据:

    var request = new HttpRequestMessage();
    request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer");
    await client.SendAsync(request);
    

    您也可以在自己的网络请求处理程序中执行此操作:

    class SetCredentialsWebRequestHandler : WebRequestHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer");
            return base.SendAsync(request, cancellationToken);
        }
    }
    
    client = new HttpClient(new SetCredentialsWebRequestHandler());
    await client.PostAsync(url);
    

    更新

    从 cmets 中,我了解到这个问题需要使用证书身份验证。所以在这种情况下,多个实例(每个证书一个)会是更好的选择。

    没有必要为不同的客户端证书重用相同的连接。

    看看这个名为HttpClient的: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.1#named-clients

    HttpClient 可以根据证书命名。

    【讨论】:

    • 感谢您的回复!就我而言,我使用 X509Certificate2 而不是 Bearer Token。这个例子也应该有效吗?
    • 没有。抱歉,我认为客户端证书是通用的,您正在使用请求级别授权。如果使用证书,您需要HttpClient 每个证书。证书身份验证发生在建立连接期间的 SSH/TLS 握手期间。重用HttpClient 的全部意义在于重用底层连接。
    • 然后我可以创建一个 HttpClient 列表并重用具有相同证书的客户端。这是一个好方法吗?
    • 但是如果您的应用程序中没有依赖注入的东西,那么是的,列表/字典也应该这样做。只需要确保您最终处置它们。
    • 是的。列表/字典/你自己的经理类。只要您可以在不再需要时将它们丢弃即可。如果它们与您的应用程序具有相同的生命周期也很好。只是 TCP 连接会在关闭之前保持半开状态。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-02
    • 2021-03-16
    相关资源
    最近更新 更多