我需要使用HttpClientFactory连接到外部api。
Startup.cs中的代码看起来像这样

public void SetUpHttpClients(IServiceCollection services)
{
        var loginEndpoint = Path.Combine(baseApi, "api/authentication);
        var fileExists = File.Exists(certificatePath);

        if (!fileExists)
            throw new ArgumentException(certificatePath);

        var certificate = new X509Certificate2(certificatePath, certPwd);

        services.AddHttpClient("TestClient", client =>
        {
        client.BaseAddress = new Uri(baseApi);
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(accept));
        client.DefaultRequestHeaders.Add("ApiKey", apiKey);

        var body = new { Username = username, Password = password };
        var jsonBody = JsonConvert.SerializeObject(body);
        var content = new StringContent(jsonBody, Encoding.UTF8, contentType);

        var loginResponse = client.PostAsync(loginEndpoint, content).Result;

        }).ConfigurePrimaryHttpMessageHandler(() =>
        {
            var cookieContainer = new CookieContainer();
            var handler = new HttpClientHandler
            {
                CookieContainer = cookieContainer
            };
            handler.ClientCertificates.Add(certificate);
            return handler;
});


我已使用HttpClientFactory在MessageController中添加了此代码,

public class MessagesController : Controller
{
    private readonly IHttpClientFactory _httpClientFactory;

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

   [HttpGet]
    public IActionResult GetMessages()
    {
        var client = _httpClientFactory.CreateClient("TestClient");
        var result = client.GetStringAsync("/api/messages");
        return Ok(result);
    }
}


但是当我尝试连接并从HttpClientFactory获取消息时,出现此错误:


  无法加载资源:net :: ERR_CONNECTION_RESET,404-BadRequest

最佳答案

您尝试在完成出厂配置之前发出请求,因为您在尝试配置客户端的同时仍在尝试使用该客户端,因此Post将失败。

这里的假设是SetUpHttpClientsConfigureServices中被调用。

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


完成配置后,工厂可根据需要注入到控制器或服务类中。

以下示例显示使用工厂作为控制器的依赖项。

[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


但是,这可能会带来无法预料的结果,因为在启动过程中,此阶段尚不能完全填充服务集合。

关于c# - HttpClientFactory BadRequest吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51009482/

10-09 00:03