Вы пытаетесь сделать запрос перед завершением заводской конфигурации. Эта публикация завершится ошибкой, потому что вы пытаетесь использовать клиент, все еще настраивая его.
Здесь предполагается, что SetUpHttpClients
вызывается внутри ConfigureServices
.
public void ConfigureServices(IServiceCollection services) {
//...
SetUpHttpClients(services);
//...
services.AddMvc();
}
public void SetUpHttpClients(IServiceCollection services) {
var basePath = Directory.GetCurrentDirectory();
var certificatePath = Path.Combine(basePath, certPath);
var fileExists = File.Exists(certificatePath);
if (!fileExists)
throw new ArgumentException(certificatePath);
var certificate = new X509Certificate2(certificatePath, certPwd);
//Adding a named client
services.AddHttpClient("TestClient", client => {
client.BaseAddress = new Uri(baseApi);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(accept));
client.DefaultRequestHeaders.Add("ApiKey", apiKey);
})
.ConfigurePrimaryHttpMessageHandler(() => {
var cookieContainer = new CookieContainer();
var handler = new HttpClientHandler {
CookieContainer = cookieContainer
};
handler.ClientCertificates.Add(certificate);
return handler;
});
}
После завершения настройки фабрика становится доступной для внедрения в контроллер или класс обслуживания по мере необходимости.
В следующем примере показано использование фабрики в качестве зависимости отcontroller.
[Route("api/[controller]")]
public class ValuesController : Controller {
private readonly IHttpClientFactory factory;
public MyController(IHttpClientFactory factory) {
this.factory = factory;
}
[HttpGet]
public async Task<IActionResult> Get() {
var client = factory.CreateClient("TestClient");
var result = client.GetStringAsync("api/messages");
return Ok(result);
}
}
В приведенном выше примере фабрика используется для создания экземпляра именованного клиента.Он будет иметь всю конфигурацию, которая была установлена во время запуска, включая обработчик клиента с сертификатом.
Чтобы иметь возможность использовать клиент во время запуска (что я бы посоветовал), вам сначала потребуетсявстроить набор служб в поставщика услуг.
var serviceProvider = services.BuildServiceProvider();
var factory = serviceProvider.GetService<IHttpClientFactory>();
var client = factory.CreateClient("TestClient");
var body = new { Username = username, Password = password };
var jsonBody = JsonConvert.SerializeObject(body);
var content = new StringContent(jsonBody, Encoding.UTF8, contentType);
var loginResponse = client.PostAsync("api/authentication", content).Result;
//...do something with the response
Однако это может привести к непредвиденным результатам, так как на этом этапе в процессе запуска коллекция услуг не была бы полностью заполнена.