C# HttpClient添加到DefaultRequestHeaders的请求头无法传递到API
问题描述
在我的API项目中有如下控制器,使用Postman调用时运行正常:
[HttpPost] public async Task<ActionResult> Upload([FromHeader] string authorization, IFormFile payLoad) { ... }
我使用Postman时,在Auth模块添加Token并指定类型为Bearer Token,随后在Body模块将键payLoad设置为File类型,选择要上传的文件,请求可以正常执行,API可以拿到所有预期数据。
Postman生成的C# RestSharp代码如下:
var client = new RestClient("http://localhost:11764/api/logdata"); client.Timeout = -1; var request = new RestRequest(Method.POST); request.AddHeader("Authorization", "Bearer exampleTokenString"); request.AddFile("payLoad", "/C:/path/oqwi.zip"); IRestResponse response = client.Execute(request); Console.WriteLine(response.Content);
我没有使用RestSharp所以没有验证上述代码可用性。
但我自己写的客户端用HttpClient发起POST调用时,API控制器的authorization参数始终收到null,只有文件可以正常上传。以下是我尝试过的所有添加请求头的写法(并非同时使用所有方式):
Uri EndPoint = new Uri("http://localhost:11764/api/logdata"); using (var client = new HttpClient()) { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken); client.DefaultRequestHeaders.Add("Authorization", "Bearer " + AccessToken); var request = new HttpRequestMessage(HttpMethod.Post, EndPoint) { Content = fileAsFormData }; request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken); request.Headers.Add("Authorization", "Bearer " + AccessToken); var response = await client.SendAsync(request); ... }
注:上述代码仅展示我尝试过的所有添加Authorization头的方式,并未同时运行。
运行时我检查过客户端对象,确认请求头已经按预期添加,Fiddler抓包也能验证请求头确实被发出。
更新
我尝试添加其他请求头比如CacheControl,所有请求头都无法传递到API。客户端和Fiddler里都能看到请求头,但请求到达API时所有请求头都被清空了。
解决方案
你遇到的是ASP.NET Core + HttpClient调用的常见问题,按以下步骤排查即可解决:
- 关闭HttpClient自动重定向
这是概率最高的原因:HttpClient默认开启自动跟随重定向,当请求遇到301/302重定向(比如你请求的是HTTP地址,API自动跳转到HTTPS;或者地址缺少尾部斜杠被重定向)时,为了安全会自动移除Authorization头,防止凭证被发送到非预期站点。
修改HttpClient初始化代码,关闭自动重定向即可:
using (var client = new HttpClient(new HttpClientHandler() { AllowAutoRedirect = false })) { // 后续请求逻辑不变 var request = new HttpRequestMessage(HttpMethod.Post, EndPoint) { Content = fileAsFormData }; request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken); var response = await client.SendAsync(request); }
如果确实需要重定向,可以判断响应状态码为301/302后,手动读取响应头的Location字段,重新构造带Authorization头的请求发送到新地址。
- 修改API侧请求头读取方式
[FromHeader]直接绑定authorization参数时,可能因为ASP.NET Core内置的身份验证中间件提前处理了Authorization头,导致参数绑定得到null,改成直接从HttpContext读取即可:
[HttpPost] public async Task<ActionResult> Upload(IFormFile payLoad) { var authorization = Request.Headers.Authorization.FirstOrDefault(); // 后续逻辑不变 }
- 检查FormData构造逻辑
确认你构造fileAsFormData时,没有错误地在MultipartFormDataContent的Headers中添加Authorization头,也没有覆盖全局的请求头,正确的构造代码参考:
var fileAsFormData = new MultipartFormDataContent(); using var fileStream = File.OpenRead("你的本地文件路径"); var fileContent = new StreamContent(fileStream); fileAsFormData.Add(fileContent, "payLoad", "oqwi.zip");
- 排查API侧中间件
如果你部署时用了反向代理、WAF、自定义中间件,确认配置中没有过滤Authorization头。如果是本地调试,检查有没有注册过自定义的请求处理中间件提前清空了请求头。
内容的提问来源于stack exchange,提问作者8protons
相关产品推荐
相关产品推荐

