C# POST提交XML数据时request.GetRequestStream()调用报错
问题原因与修复方案
你在执行request.GetRequestStream()时报错、Postman同参数可正常请求的核心原因是代码存在硬逻辑错误,和XML内容本身无关:
- 编码声明与实际使用完全不匹配:你在ContentType头里声明编码是utf-8,但实际转请求字节用的是ASCII编码,ASCII无法支持XML中可能存在的非英文字符、特殊符号,会导致字节长度计算错误、内容损坏,服务器会直接拒绝连接,触发流获取阶段报错。另外你用
StringWriter序列化XML时默认用UTF-16编码,和后续转码逻辑也存在冲突,会额外引入字符长度偏差。 - 默认请求头存在兼容性问题:
HttpWebRequest默认会携带Expect: 100-continue请求头,大量后端服务不兼容该头,收到后会直接断开连接,这也是GetRequestStream阶段报错的高频诱因。 - 资源释放逻辑缺失:响应对象、响应流没有用using包裹,可能引发连接池占用导致的偶发请求失败。
修正后的可运行代码
主方法优化(直接读取XML文件,避免转码问题)
static void Main(string[] args) { // 如果目标是HTTPS接口,取消下面这行的注释,兼容多版本TLS协议 // ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; string url = "你的目标接口地址"; // 直接以UTF8编码读取XML文件内容,跳过冗余的XmlDocument序列化步骤 string xmlContent = File.ReadAllText(@"你的XML文件本地绝对路径", Encoding.UTF8); string response = postXMLData(url, xmlContent); Console.WriteLine(response); Console.ReadLine(); }
修复后的POST请求方法
public static string postXMLData(string destinationUrl, string requestXml) { // 全程统一使用UTF8编码,和请求头声明保持一致 byte[] bytes = Encoding.UTF8.GetBytes(requestXml); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(destinationUrl); request.Method = "POST"; // 修正ContentType写法,用标准charset参数声明编码 request.ContentType = "text/xml; charset=utf-8"; request.ContentLength = bytes.Length; request.Accept = "*/*"; // 关闭不兼容的Expect头 request.ServicePoint.Expect100Continue = false; // 配置30秒超时,避免无限等待 request.Timeout = 30000; // 如果接口校验User-Agent,取消下面一行注释即可 // request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"; using (Stream requestStream = request.GetRequestStream()) { requestStream.Write(bytes, 0, bytes.Length); } using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) using (Stream responseStream = response.GetResponseStream()) using (StreamReader reader = new StreamReader(responseStream, Encoding.UTF8)) { if (response.StatusCode == HttpStatusCode.OK) { return reader.ReadToEnd(); } return $"请求异常,状态码:{response.StatusCode},描述:{response.StatusDescription}"; } }
额外排查点
如果替换代码后仍报错,可以用抓包工具对比Postman发送的请求头和代码发出的请求头,补全接口要求的特殊鉴权头、自定义参数即可,XML内容本身不需要调整。
内容的提问来源于stack exchange,提问作者Noob Gamer
相关产品推荐
相关产品推荐

