C#使用HttpWebRequest发送带JSON的POST请求报404错误如何解决
问题排查与修复方案
核心问题及对应调整项
- JSON格式错误:当前你写的请求体JSON最后一个属性
confidential后面多了多余的尾随逗号,大部分服务端JSON解析器会直接拒绝这种非法格式,进而触发404/400错误。 - StreamWriter编码未匹配:默认
StreamWriter编码是UTF-8带BOM,部分接口不兼容,需要显式指定无BOM的UTF-8编码,写入后要确保数据全部写入请求流。 - 未显式设置ContentLength(可选但建议):部分反向代理/服务端要求POST请求必须携带正确的
Content-Length请求头,避免分块传输导致的识别失败。 - 接口端点校验:GET正常但POST报404,首先要确认目标接口的POST路径是否和GET一致,部分接口POST需要额外的路径后缀比如
/create之类的,可先和接口提供方确认路由规则。
修正后的代码示例
第一步:修正请求体写入逻辑
建议优先用Json.NET序列化对象生成JSON,避免手动拼接JSON出现格式错误,将原StreamWriter部分替换为如下代码:
// 构造请求体对象 var requestBody = new { reference = "Test", info = "additionalInfo", ID = (string)null, confidential = false }; // 序列化得到标准合法JSON string data = JsonConvert.SerializeObject(requestBody, Formatting.Indented); // 按UTF-8编码转字节流写入请求 byte[] byteArray = Encoding.UTF8.GetBytes(data); // 显式设置ContentLength request.ContentLength = byteArray.Length; using (Stream requestStream = request.GetRequestStream()) { requestStream.Write(byteArray, 0, byteArray.Length); }
第二步:完整调整后的程序代码
using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Net; using System.IO; using System.Text; namespace RestTesting { class Program { static void Main(string[] args) { string url = "https://server.APIEndpoint/REST/"; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = "POST"; // 补充charset声明 request.ContentType = "application/json; charset=utf-8"; request.Accept = "application/json"; request.KeepAlive = true; request.Credentials = CredentialCache.DefaultCredentials; // 可选:添加User-Agent头,部分服务端会拦截无UA的请求 request.UserAgent = "RestTesting/1.0"; // --------------- 请求体写入逻辑 --------------- var requestBody = new { reference = "Test", info = "additionalInfo", ID = (string)null, confidential = false }; string data = JsonConvert.SerializeObject(requestBody); byte[] byteArray = Encoding.UTF8.GetBytes(data); request.ContentLength = byteArray.Length; using (Stream requestStream = request.GetRequestStream()) { requestStream.Write(byteArray, 0, byteArray.Length); } // --------------- 请求体写入结束 --------------- Console.WriteLine("Request: {0} \"{1}\" ...", request.Method, request.RequestUri); Console.WriteLine(request.Headers); Console.WriteLine(request.ContentLength); try { HttpWebResponse response = (HttpWebResponse)request.GetResponse(); Console.WriteLine(String.Format("Response: HTTP/{0} {1} ({1:d})\n", response.ProtocolVersion, response.StatusCode)); Console.WriteLine(response.Headers); string responseText; using (var reader = new System.IO.StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8)) { responseText = reader.ReadToEnd(); } Console.WriteLine(response.ContentType); if (response.ContentType.StartsWith("application/json")) { JObject json = (JObject)JObject.Parse(responseText); Console.WriteLine(json.ToString()); } } catch (WebException err) { // 打印服务端返回的错误详情,方便排查 if (err.Response != null) { using (var reader = new StreamReader(err.Response.GetResponseStream(), Encoding.UTF8)) { Console.WriteLine("服务端返回错误内容:" + reader.ReadToEnd()); } } Console.WriteLine(err); } catch (Exception err) { Console.WriteLine(err); } Console.WriteLine("Press enter to close..."); Console.ReadLine(); } } }
额外排查建议
如果调整后还是报错,优先做如下检查:
- 用Postman/ApiPost等工具往同一个地址发同样的JSON请求体,确认接口本身可以正常返回,排除接口路由/权限问题
- 查看代码中捕获的WebException返回的服务端错误内容,里面会有具体的错误原因(比如参数错误、路由不存在、权限不足等)
- 确认你的请求不需要额外的鉴权头(比如Authorization头),部分接口GET不需要鉴权但POST需要
内容的提问来源于stack exchange,提问作者schmimla
相关产品推荐
相关产品推荐

