HttpClient的单个实例与具有ClientCredentias的多个实例?

时间:2020-03-19 11:16:17

标签: c# httpclient x509certificate credentials socketexception

我正在使用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并使用其他凭证的更好方法是什么?

1 个答案:

答案 0 :(得分:2)

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

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

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

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);

更新

从评论中,我了解到该问题要求使用证书身份验证。因此,在这种情况下,最好使用多个实例(每个证书一个)。

没有意义将相同的连接用于不同的客户端证书。

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

HttpClient可以根据证书命名。