C#使用HttpWebRequest、HttpClient发POST报400仅RestSharp正常问题排查
通过两份抓包结果对比,核心差异点是HttpClient和HttpWebRequest发送的请求默认携带了Expect: 100-continue请求头,你使用的目标服务端未兼容该HTTP 1.1特性,因此直接返回400错误;而RestSharp默认关闭了该特性,因此请求可以正常响应。
修复方案
1. HttpWebRequest实现修复
在初始化请求对象后添加禁用Expect 100-continue的配置即可:
var httpRequest = (HttpWebRequest) WebRequest.Create(uri); httpRequest.Method = "POST"; httpRequest.Accept = "application/json"; httpRequest.Headers["Authorization"] = $"Bearer {token}"; httpRequest.Headers["Client_Id"] = clientId; httpRequest.ContentType = "application/json"; // 新增以下行禁用Expect 100-continue httpRequest.ServicePoint.Expect100Continue = false; using (var streamWriter = new StreamWriter(httpRequest.GetRequestStream())) { streamWriter.Write(json); } var httpResponse = (HttpWebResponse) httpRequest.GetResponse();
补充:如果仍报错可显式指定StreamWriter编码为无BOM的UTF8:new StreamWriter(httpRequest.GetRequestStream(), new UTF8Encoding(false))
2. HttpClient实现修复
建议将HttpClient定义为全局单例(不要每次请求新建),通过HttpClientHandler禁用Expect 100-continue特性:
// 全局单例声明 private static readonly HttpClient _httpClient = new HttpClient(new HttpClientHandler { Expect100Continue = false }); // 发送请求逻辑 _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); _httpClient.DefaultRequestHeaders.Add("Client_Id", clientId); _httpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); _httpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate")); _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/json")); _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/x-json")); _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/javascript")); _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml")); _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml")); var content = new StringContent(json, Encoding.UTF8, "application/json"); // 建议用await异步调用,避免.Result可能引发的死锁问题 var result = await _httpClient.PostAsync(uri, content);
如果需要全局禁用所有HTTP请求的Expect 100-continue,可以在程序启动时添加配置:ServicePointManager.Expect100Continue = false;
内容的提问来源于stack exchange,提问作者Mihai Cranga
相关产品推荐
相关产品推荐

