发送没有DefaultRequestHeaders的HttpClient请求

时间:2018-05-17 19:15:48

标签: c# dotnet-httpclient

我正在使用设计糟糕的API,并且在其缺陷中,它有一个特定的端点,不应该给出特定的自定义标头,而字面上每个其他端点都需要它。因此,它包含在DefaultRequestHeaders中,因此我无需手动将其添加到每个请求中。

但是,现在,对于这个特定的端点,我需要删除它,我不确定它是如何或甚至是可能的。使问题复杂化,我正在处理单例范围的HttpClient实例,因此任何与DefaultRequestHeaders的混淆是不可取的。换句话说,我不能做一些hacky,比如暂时删除标题然后在请求之后将其添加回来,因为这可能会影响正在进行的其他并发请求。令人沮丧的是,即使我使用SendAsync使用自定义HttpRequestMessage实例,HttpClient 仍会添加标题。

此外,虽然它可行,但我真的不想在没有添加标题HttpClient的情况下注入另一个 DefaultRequestHeaders实例。由于许多原因,在同一个类中使用两个不同的HttpClient实例似乎是一个非常糟糕的主意。

我在这里运气不好,或者在过去一小时内搜索了Interwebs之后我是否遗漏了一些解决方案?

更新

我确实找到了一个使用自定义HttpRequestMessage实例的内容,我可以通过将其设置为HttpRequestMessage上的空字符串来清除标头。由于它是明确设置的,HttpClient不会使用默认版本覆盖它。这仍然意味着正在发送标头,但至少它实际上没有值。但是,如果存在更好的解决方案,仍然感兴趣。

2 个答案:

答案 0 :(得分:1)

您可以在处理程序SendAsync覆盖中执行此操作,因为此时HttpClient已经为您的请求添加了默认标头。如果您没有使用自定义处理程序 - 您可以继承HttpClientHandler并使用它,因为new HttpClient()new HttpClient(new HttpClientHandler())相同。例如:

public static void Main(string[] args) {
    HttpClient c = new HttpClient(new MyHttpClientHandler());
    c.DefaultRequestHeaders.Add("X-Test", "1");
    var res = c.GetAsync("http://google.com").Result;
}

class MyHttpClientHandler : HttpClientHandler {
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
        // check for your endpoint
        if (request.RequestUri.Host == "google.com") {
            // remove
            request.Headers.Remove("X-Test");
        }

        return base.SendAsync(request, cancellationToken);
    }
}

答案 1 :(得分:0)

可能不是您正在寻找的答案,但如果您不想在每次电话上发送标题,我就不会使用{{1}对它来说。对我来说,感觉不像是一个黑客来添加它&#34;手动&#34;当你需要它时,而不是为一个端点删除它。

当然你想保持干爽。如果没有看到您的代码,假设您从单个类中对API进行了所有调用,则可能只需创建一个这样的私有帮助器方法,其他所有方法都遵循:

DefaultRequestHeaders

或者,也许是一个帮助者,它也会采用动词和端点并实际发送请求。

或者,如果你想保持这个&#34;噪音&#34;在主要的API包装器类之外,您可以像在@Evk的答案中创建一个处理程序,除了我再次跳过使用HttpRequestMessage BuildRequestMessage(object body, bool sendCustomHeader = true) 并将逻辑翻转到 include 标题如果您调用特定端点。