C# 发送不带DefaultRequestHeader的HttpClient请求
我使用的是一个设计拙劣的API,它有一个特定的端点,不应该提供特定的自定义头,而实际上其他端点都需要它。因此,它包含在C# 发送不带DefaultRequestHeader的HttpClient请求,c#,dotnet-httpclient,C#,Dotnet Httpclient,我使用的是一个设计拙劣的API,它有一个特定的端点,不应该提供特定的自定义头,而实际上其他端点都需要它。因此,它包含在DefaultRequestHeaders中,因此我不需要手动将其添加到每个请求中 然而,现在,对于这一个特定的端点,我需要删除它,我不知道如何或者是否可能。让事情有些复杂的是,我正在处理一个单例范围的HttpClient实例,因此任何对DefaultRequestHeaders的篡改都是不可能的。换句话说,我不能做一些像临时删除头然后在请求后再添加头这样的黑客行为,因为这可能会
DefaultRequestHeaders
中,因此我不需要手动将其添加到每个请求中
然而,现在,对于这一个特定的端点,我需要删除它,我不知道如何或者是否可能。让事情有些复杂的是,我正在处理一个单例范围的HttpClient
实例,因此任何对DefaultRequestHeaders
的篡改都是不可能的。换句话说,我不能做一些像临时删除头然后在请求后再添加头这样的黑客行为,因为这可能会影响其他并发请求。令人沮丧的是,即使我将SendAsync
与自定义HttpRequestMessage
实例一起使用,HttpClient
仍然会添加头
另外,虽然它可以工作,但我真的不希望在没有添加到DefaultRequestHeaders
的头的情况下注入另一个HttpClient
实例。由于许多原因,在同一个类中使用两个不同的HttpClient
实例似乎是一个非常糟糕的主意
是我在这里运气不好,还是在过去一个小时的网络搜索中我错过了一些解决方案
更新
有一件事我发现了,通过自定义的
HttpRequestMessage
实例,我可以通过在HttpRequestMessage
上将标题设置为空字符串来清除标题。因为它是显式设置的,HttpClient
不会用默认版本覆盖它。这仍然意味着正在发送头,但至少它实际上没有值。不过,如果存在更好的解决方案,您仍然对它感兴趣。您可以在handlerSendAsync
覆盖中这样做,因为此时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);
}
}
publicstaticvoidmain(字符串[]args){
HttpClient c=newhttpclient(new MyHttpClientHandler());
c、 DefaultRequestHeaders.Add(“X-Test”、“1”);
var res=c.GetAsync(“http://google.com三、结果;
}
类MyHttpClientHandler:HttpClientHandler{
受保护的覆盖任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken){
//检查您的端点
if(request.RequestUri.Host==“google.com”){
//除去
请求。标题。删除(“X测试”);
}
返回base.sendaync(请求、取消令牌);
}
}
可能不是您想要的答案,但是如果您不想在每次通话中发送标题,我根本不会使用DefaultRequestHeaders
。在我看来,在需要时“手动”添加它,而不是为一个端点删除它,感觉不像是一种黑客行为
你当然想让它保持干燥。在不查看代码的情况下,假设您正在从单个类对API进行所有调用,一种可能是只创建一个私有帮助器方法,所有其他方法都遵循这种方法:
HttpRequestMessage BuildRequestMessage(object body, bool sendCustomHeader = true)
或者,可能是一个助手,它也接受动词和端点,并实际发送请求
或者,如果您想将此“噪音”排除在主API包装器类之外,您可以创建一个类似@Evk的答案中的处理程序,除非我再次跳过使用DefaultRequestHeaders
,如果您不调用特定端点,则翻转逻辑以包含标头