You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Bearer Token调用HttpClient返回401未授权问题排查

问题分析:.NET 6文件上传接口返回401未授权的原因

核心错误:请求头未被正确发送

问题代码的关键失误在于:你构造了HttpRequestMessage并添加了Authorization和api-version头,但最终调用client.PostAsync(uploadUrl, content)时,这个方法会完全忽略你之前创建的HttpRequestMessage对象,而是生成一个全新的POST请求发送,导致你设置的授权头和版本头都没有被传递到服务器,因此返回401未授权。

次要问题:地址配置冗余

问题代码中给HttpClient设置了BaseAddress,但又给HttpRequestMessage指定了完整的uploadUrl作为RequestUri,这不仅让BaseAddress的配置失去意义,还可能引发地址拼接的潜在问题。

修正代码的关键改进点

修正后的代码针对性解决了这些问题:

  • 将Authorization头添加到client.DefaultRequestHeaders,确保该客户端发送的所有请求都会自动携带授权信息;
  • 采用BaseAddress + 相对路径("uploads")的方式构造请求地址,避免地址冗余;
  • 通过client.SendAsync(request)发送预先构造好的HttpRequestMessage,确保api-version等自定义头被正确携带;
  • 将请求内容赋值给request.Content后再发送,保证请求的完整性。

问题代码

private static async Task UploadCsvFileAsync(string authToken)
{
    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri("https://subdomain.domain.com/");
        client.DefaultRequestHeaders
            .Accept
            .Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
        using (var request = new HttpRequestMessage())
        {
            request.RequestUri = new Uri(uploadUrl);
            request.Method = HttpMethod.Post;
            request.Headers.Add("api-version", "1");
            request.Headers.Add("Authorization", $"Bearer {authToken}");

            string header = $"{Environment.NewLine}--{formBoundary}{Environment.NewLine}" +
                $"Content-Disposition: form-data; name=\"csvfile\"; filename=\"{csvFileName}\"{Environment.NewLine}" +
                $"Content-Type: text/csv{Environment.NewLine}{Environment.NewLine}";
            byte[] headerBytes = Encoding.UTF8.GetBytes(header);
            var headerContent = new StreamContent(new MemoryStream(headerBytes));
            headerContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
            var content = new MultipartFormDataContent();
            content.Add(headerContent, "metadata", csvFileName);

            var response = await client.PostAsync(uploadUrl, content);
            // the response code is 401 - Unauthorized
        }
    }
}

修正后的可行代码

private static async Task UploadCsvFileAsyncV2(string authToken)
{
    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri(uploadUrl);
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authToken);
        client.DefaultRequestHeaders
            .Accept
            .Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
        using (var request = new HttpRequestMessage(HttpMethod.Post, "uploads"))
        {
            request.Headers.Add("api-version", "1");
            string header = $"{Environment.NewLine}--{formBoundary}{Environment.NewLine}" +
                $"Content-Disposition: form-data; name=\"csvfile\"; filename=\"{csvFileName}\"{Environment.NewLine}" +
                $"Content-Type: text/csv{Environment.NewLine}{Environment.NewLine}";
            byte[] headerBytes = Encoding.UTF8.GetBytes(header);
            var headerContent = new StreamContent(new MemoryStream(headerBytes));
            headerContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
            var content = new MultipartFormDataContent
            {
                { headerContent, "metadata", csvFileName }
            };
            request.Content = content;

            var response = await client.SendAsync(request);
        }
    }
}

内容的提问来源于stack exchange,提问作者OneClutteredMind

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 05:45:10