HttpRequestMessage本身不发送请求,仅作为请求容器;必须交由HttpClient.SendAsync执行,否则仅为“空壳”,常见错误是构造后未调用SendAsync导致静默卡住或ObjectDisposedException。
HttpRequestMessage 本身不发送请求,必须配 HttpClient.SendAsync
只是一个请求容器,它不包含网络能力。直接 new 它出来、设置
和
后,如果不交给
执行,就只是个“空壳”。常见错误是写完
就以为万事大吉,结果没调用
,程序静默卡住或抛
(因后续又用了已释放的 client)。
正确链路只有这一种:
创建
实例(推荐复用,别每次 new)
构造
,填好
、
、
(如有)、
传给
,await 等待响应
手动调用
检查状态码(
默认不抛异常)
POST 带 JSON Body 时,Content-Type 必须显式设为 application/json
用
发送 JSON 数据,不能只靠
构造时传入
,还要确认
确实生效。某些旧版 .NET Framework 下,如果没设或拼错,服务器可能返回 415 Unsupported Media Type。
安全写法:
注意:
构造函数第三个参数是 MIME 类型,但内部不一定严格绑定到
;显式赋值更可靠。
Authorization 头要加在 RequestMessage.Headers,不是 DefaultRequestHeaders
如果你用的是单次请求专用的
(比如不同请求带不同 token),授权头必须加在该实例的
上,而不是
。后者是全局默认头,一旦设置会污染所有后续请求——尤其在并发场景下极易导致 token 错乱。
C知道
CSDN推出的一款AI技术问答工具
下载
正确做法:
需要 per-request 鉴权:用
需要全局固定鉴权(如服务间调用统一 token):才设
混用时注意清除:若某次请求不需要 auth,得手动
,否则继承了 client 的默认头
GET 请求带 Query 参数,别拼字符串,用 UriBuilder 或 QueryHelpers
手写
容易出编码问题。中文、特殊符号(如
、
、空格)不 encode 会导致 400 Bad Request 或参数截断。
推荐两种方式:
.NET Core 2.1+:用
(即使非 ASP.NET 项目也可 NuGet 引入
)
全平台兼容:用
+
示例(QueryHelpers):
这个细节在调试时很难定位——请求发出去了,服务器收不到完整参数,日志里也看不出拼接痕迹。
HttpRequestMessageRequestUriHeadersHttpClientvar req = new HttpRequestMessage(...)client.SendAsync(req)ObjectDisposedExceptionHttpClientHttpRequestMessageMethodRequestUriContentHeadersclient.SendAsync(req)response.EnsureSuccessStatusCode()HttpClientHttpRequestMessageStringContent"application/json"Content.Headers.ContentTypevar json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");
// 强制覆盖 ContentType,避免被中间层篡改
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var request = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = content
};
StringContentHeaders.ContentTypeHttpRequestMessageHeadersHttpClient.DefaultRequestHeadersrequest.Headers.Add("Authorization", "Bearer xxx")client.DefaultRequestHeaders.Authorizationrequest.Headers.Remove("Authorization")url + "?key=value&..."&=Microsoft.AspNetCore.WebUtilities.QueryHelpersMicrosoft.AspNetCore.WebUtilitiesUriBuilderHttpUtility.ParseQueryStringvar query = new Dictionary { ["q"] = "c# http", ["page"] = "1" };
var uri = new Uri($"{baseUrl}?{QueryHelpers.AddQueryString("", query)}");
var request = new HttpRequestMessage(HttpMethod.Get, uri);
