【问题标题】:Send HttpClient request without DefaultRequestHeaders发送没有 DefaultRequestHeaders 的 HttpClient 请求
【发布时间】:2018-05-17 19:15:48
【问题描述】:

我正在使用一个设计不佳的 API,在它的缺陷中,它有一个特定的端点,不应提供特定的自定义标头,而实际上所有其他端点都需要它。结果,它被包含在DefaultRequestHeaders 中,所以我不需要在每个请求中手动添加它。

但是,现在,对于这个特定的端点,我需要删除它,我不确定如何或是否可能。使事情有些复杂化,我正在处理一个单例范围的HttpClient 实例,所以任何与DefaultRequestHeaders 混在一起的事情都是不可行的。换句话说,我不能做一些像临时删除标头然后在请求之后将其重新添加回来的事情,因为这可能会影响正在发出的其他并发请求。令人沮丧的是,即使我将SendAsync 与自定义HttpRequestMessage 实例一起使用,HttpClient 仍然会添加标题。

此外,虽然它会起作用,但我真的不希望在没有将标头添加到 DefaultRequestHeaders 的情况下注入 另一个 HttpClient 实例。在同一个类中使用两个不同的HttpClient 实例似乎是一个非常糟糕的主意,原因有很多。

我是不是运气不好,还是在过去一个小时内搜索了 Internet 后我错过了一些解决方案?

更新

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

【问题讨论】:

    标签: c# dotnet-httpclient


    【解决方案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);
        }
    }
    

    【讨论】:

      【解决方案2】:

      可能不是您正在寻找的答案,但如果您不想在 每个 调用中发送标头,我根本不会使用 DefaultRequestHeaders。对我来说,当你需要它时“手动”添加它,而不是为一个端点删除它,感觉不像是一种黑客攻击。

      您当然希望保持干燥。在没有看到您的代码的情况下,假设您从单个类对 API 进行所有调用,一种可能性是创建一个像这样的私有帮助器方法,所有其他方法都遵循:

      HttpRequestMessage BuildRequestMessage(object body, bool sendCustomHeader = true)
      

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

      或者,如果你想把这个“噪音”排除在主 API 包装类之外,你可以像 @Evk 的回答那样创建一个处理程序,除了那里我会再次跳过使用 DefaultRequestHeaders 并将逻辑翻转到 include 如果您调用特定端点,则包含标头。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多