Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 发送不带DefaultRequestHeader的HttpClient请求_C#_Dotnet Httpclient - Fatal编程技术网

C# 发送不带DefaultRequestHeader的HttpClient请求

C# 发送不带DefaultRequestHeader的HttpClient请求,c#,dotnet-httpclient,C#,Dotnet Httpclient,我使用的是一个设计拙劣的API,它有一个特定的端点,不应该提供特定的自定义头,而实际上其他端点都需要它。因此,它包含在DefaultRequestHeaders中,因此我不需要手动将其添加到每个请求中 然而,现在,对于这一个特定的端点,我需要删除它,我不知道如何或者是否可能。让事情有些复杂的是,我正在处理一个单例范围的HttpClient实例,因此任何对DefaultRequestHeaders的篡改都是不可能的。换句话说,我不能做一些像临时删除头然后在请求后再添加头这样的黑客行为,因为这可能会

我使用的是一个设计拙劣的API,它有一个特定的端点,不应该提供特定的自定义头,而实际上其他端点都需要它。因此,它包含在
DefaultRequestHeaders
中,因此我不需要手动将其添加到每个请求中

然而,现在,对于这一个特定的端点,我需要删除它,我不知道如何或者是否可能。让事情有些复杂的是,我正在处理一个单例范围的
HttpClient
实例,因此任何对
DefaultRequestHeaders
的篡改都是不可能的。换句话说,我不能做一些像临时删除头然后在请求后再添加头这样的黑客行为,因为这可能会影响其他并发请求。令人沮丧的是,即使我将
SendAsync
与自定义
HttpRequestMessage
实例一起使用,
HttpClient
仍然会添加头

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

是我在这里运气不好,还是在过去一个小时的网络搜索中我错过了一些解决方案

更新


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

您可以在handler
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);
    }
}
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
,如果您不调用特定端点,则翻转逻辑以包含标头