如何以美观XML格式展示请求响应?代码无输出问题排查
控制台无XML输出问题排查与需求实现修正
问题背景
需要按顺序执行两段XML请求:
- 先发送
checkPaymentRequisites请求 - 若该请求返回的
result为0且status为3,则发送addOfflinePayment请求 - 目标是在控制台以美观格式展示请求响应,但当前代码执行后控制台无任何输出。
原代码展示
主请求方法
public static string postXMLData(string destinationUrl, string xml) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(destinationUrl); byte[] bytes; bytes = System.Text.Encoding.ASCII.GetBytes(xml); request.ContentType = "text/xml; encoding='utf-8'"; request.ContentLength = bytes.Length; request.Method = "POST"; Stream requestStream = request.GetRequestStream(); requestStream.Write(bytes, 0, bytes.Length); requestStream.Close(); HttpWebResponse response; response = (HttpWebResponse)request.GetResponse(); if (response.StatusCode == HttpStatusCode.OK) { Stream responseStream = response.GetResponseStream(); var xmlResponce = XmlToResponce(responseStream); if (xmlResponce.Providers.checkPaymentRequisites.Payment.result == 0 && xmlResponce.Providers.checkPaymentRequisites.Payment.status == 3) { xml=Requests.addOfflinePayment(); } else { Console.WriteLine("Something wrong"); } string responseStr = new StreamReader(responseStream).ReadToEnd(); return responseStr; } return string.Empty; }
响应序列化方法
// checkPaymentRequisites 响应解析 private static Responses.Response XmlToResponce (Stream stream) { var xmlSerializer = new XmlSerializer(typeof(Responses.Response)); var xmlResponce = xmlSerializer.Deserialize(stream) as Responses.Response; return xmlResponce; } // addOfflinePayment 响应解析 private static Responses.ResponseOff XmlToResOff(Stream stream) { var xmlSerializer = new XmlSerializer(typeof(Responses.ResponseOff)); var xmlResponce = xmlSerializer.Deserialize(stream) as Responses.ResponseOff; return xmlResponce; }
控制台入口
static void Main(string[] args) { string str = Requests.checkPaymentRequisites(); var xml = postXMLData(url, str); Console.WriteLine(xml); Console.ReadKey(); }
问题分析
- 响应流读取耗尽:
XmlSerializer.Deserialize会将响应流读取到末尾,后续StreamReader.ReadToEnd()无法再读取到任何内容,导致返回空字符串,控制台无输出。 - 第二个请求未实际发送:代码仅修改了
xml变量的值,但没有调用postXMLData发送addOfflinePayment请求,不符合需求逻辑。 - 异常处理缺失:
HttpWebRequest.GetResponse()可能抛出网络异常、服务器错误等,此时会直接返回空字符串,无任何错误提示。 - 编码不匹配:请求内容用
ASCII.GetBytes编码,但ContentType声明为UTF-8,若XML包含非ASCII字符会导致编码错误。
修复方案
修正主请求方法
public static string postXMLData(string destinationUrl, string xml) { try { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(destinationUrl); // 使用UTF-8编码匹配ContentType byte[] bytes = System.Text.Encoding.UTF8.GetBytes(xml); request.ContentType = "text/xml; encoding=utf-8"; request.ContentLength = bytes.Length; request.Method = "POST"; using (Stream requestStream = request.GetRequestStream()) { requestStream.Write(bytes, 0, bytes.Length); } using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { if (response.StatusCode == HttpStatusCode.OK) { // 先读取完整响应字符串,再序列化解析 string responseStr; using (Stream responseStream = response.GetResponseStream()) using (StreamReader reader = new StreamReader(responseStream)) { responseStr = reader.ReadToEnd(); } // 反序列化前需重新生成流 using (MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(responseStr))) { var xmlResponce = XmlToResponce(ms); if (xmlResponce.Providers.checkPaymentRequisites.Payment.result == 0 && xmlResponce.Providers.checkPaymentRequisites.Payment.status == 3) { // 发送第二个请求并获取响应 string offlineXml = Requests.addOfflinePayment(); string offlineResponse = postXMLData(destinationUrl, offlineXml); // 拼接两次响应以便展示 responseStr += Environment.NewLine + "--- 第二次请求响应 ---" + Environment.NewLine + offlineResponse; } else { Console.WriteLine("Something wrong"); } } return responseStr; } return $"请求失败,状态码:{response.StatusCode}"; } } catch (Exception ex) { return $"请求异常:{ex.Message}"; } }
优化控制台展示(可选)
若需要格式化XML输出,可添加XML格式化方法:
private static string FormatXml(string xml) { try { XDocument doc = XDocument.Parse(xml); return doc.ToString(); } catch { return xml; } }
然后在Main方法中调用:
static void Main(string[] args) { string str = Requests.checkPaymentRequisites(); var xml = postXMLData(url, str); // 格式化XML后输出 Console.WriteLine(FormatXml(xml)); Console.ReadKey(); }
关键修复点说明
- 先读取完整响应字符串,再通过内存流重新序列化,避免流耗尽问题。
- 实际发送第二个请求,并拼接两次响应结果。
- 添加
try-catch捕获异常,返回错误信息便于排查。 - 统一使用UTF-8编码,避免编码不匹配问题。
- 新增XML格式化方法,实现美观展示需求。
内容的提问来源于stack exchange,提问作者John Paul Johns
相关产品推荐
相关产品推荐

