Я читал в нескольких местах (например, here, here или here), что это плохая практика, чтобы избавиться от HttpClient непосредственно после запроса, и лучше избавиться от него после того, как весь запрос был чтобы обеспечить повторное использование соединения.HttpClient повторно используется с сертификатом клиента
Чтобы попробовать это, я создал экземпляр HttpClient и добавляют к статическому полю в моем классе так:
public class Test
{
private static X509Certificate2 _certificate;
private static HttpClient HttpClient { get; set; }
...
public Test()
{
...
if (HttpClient == null)
{
LoadCertificate();
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
| SecurityProtocolType.Tls11
| SecurityProtocolType.Tls12
| SecurityProtocolType.Ssl3;
var handler = new WebRequestHandler();
handler.ClientCertificates.Add(_certificate);
HttpClient = new HttpClient(handler, false);
}
}
private void LoadCertificate()
{
using (var store = new X509Store(StoreName.My, CertificateStoreLocation))
{
store.Open(OpenFlags.ReadOnly);
var certificates = store.Certificates.Find(X509FindType.FindBySubjectName, CertificateFriendlyName, true);
if (certificates.Count != 1)
throw new ArgumentException(
$"Cannot find a valid certificate with name {CertificateFriendlyName} in {CertificateStoreLocation}");
_certificate = certificates[0];
store.Close();
}
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
}
}
Я тогда использую мой экземпляр для вызова веб-службы с помощью этого команда:
var result = await HttpClient.PostAsJsonAsync(completeUri, request);
Первый раз, когда я бегу код, все работает отлично, и я получаю ответ правильно, но потом, все в следующий раз я получаю неавторизованный от сервера говорил мне, что я не сделал используйте сертификат клиента.
Это как если бы для следующих звонков, WebRequestHandler
не был принят во внимание.
Что касается утилизации HttpClient - это не совсем так. Управление подключением выполняется с помощью «ServicePointManager», но не напрямую с помощью HttpClient (который использует HttpClientHandler, который использует WebRequest под капотом). Поэтому, если у вас есть параметр, чтобы поддерживать соединение TCP или вы одновременно выполняете несколько запросов к одному и тому же «ServicePoint», удаление HttpClient не приведет к закрытию базового соединения. –
Да, вот что я имел в виду. Утилизация HttpClient будет поддерживать соединения живыми, а использование метода use() считается плохой практикой, потому что это создаст большое количество подключений, которые останутся открытыми. Это то, что объясняют сообщения и веб-сайт, которые я связал. – Gimly