C# .NET Core中HttpClient实现Basic认证时遇InvalidOperationException异常
解决C# .NET Core中Basic认证时的InvalidOperationException异常
这个问题很典型——你把**Authorization请求头错误地加到了FormUrlEncodedContent的内容头集合里**,这就触发了那个InvalidOperationException。
问题原因
Authorization属于HTTP请求级别的头信息,用来标识请求的身份验证凭据;而HttpContent.Headers是用来描述请求内容的元数据(比如Content-Type、Content-Length这类和请求体直接相关的头)。把请求头放到内容头里,违反了.NET HttpClient的头信息分类规则,自然会抛出异常。
修正方案
你需要把Authorization头添加到请求的Headers集合中,而不是内容的Headers里。这里有两种常用的实现方式:
方式1:使用HttpClient的默认请求头(适合复用HttpClient的场景)
如果这个HttpClient会被多次复用,且所有请求都需要Basic认证,直接设置DefaultRequestHeaders是最高效的:
// 可复用HttpClient配置 HttpClient client = new HttpClient(); Uri baseUri = new Uri(url); client.BaseAddress = baseUri; client.DefaultRequestHeaders.Clear(); client.DefaultRequestHeaders.ConnectionClose = true; // Basic认证:将Authorization头添加到请求的默认头中 var authenticationString = $"{clientId}:{clientSecret}"; var base64EncodedAuthenticationString = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(authenticationString)); client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", base64EncodedAuthenticationString); // Post请求体内容 var values = new List<KeyValuePair<string,string>>(); values.Add(new KeyValuePair<string, string>("grant_type", "client_credentials")); var content = new FormUrlEncodedContent(values); // 发送请求 var task = client.PostAsync("/oauth2/token",content); var response = task.Result; response.EnsureSuccessStatusCode(); string responseBody = response.Content.ReadAsStringAsync().Result; Console.WriteLine(responseBody);
方式2:使用HttpRequestMessage(适合单次请求的场景)
如果只是这一次请求需要Basic认证,不想污染HttpClient的全局默认头,可以创建单独的HttpRequestMessage来设置头:
// 可复用HttpClient配置 HttpClient client = new HttpClient(); Uri baseUri = new Uri(url); client.BaseAddress = baseUri; client.DefaultRequestHeaders.Clear(); client.DefaultRequestHeaders.ConnectionClose = true; // Post请求体内容 var values = new List<KeyValuePair<string,string>>(); values.Add(new KeyValuePair<string, string>("grant_type", "client_credentials")); var content = new FormUrlEncodedContent(values); // 创建请求消息并单独设置Authorization头 var request = new HttpRequestMessage(HttpMethod.Post, "/oauth2/token"); request.Content = content; var authenticationString = $"{clientId}:{clientSecret}"; var base64EncodedAuthenticationString = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(authenticationString)); request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", base64EncodedAuthenticationString); // 发送请求 var response = client.SendAsync(request).Result; response.EnsureSuccessStatusCode(); string responseBody = response.Content.ReadAsStringAsync().Result; Console.WriteLine(responseBody);
额外提示
获取到Bearer令牌后,后续请求可以用同样的方式设置Authorization头,只是换成Bearer方案:
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", yourAccessToken);
内容的提问来源于stack exchange,提问作者ScArcher2
相关产品推荐
相关产品推荐

