MVC POST请求遇远程主机关闭连接错误,求排查方法
问题描述
我在排查MVC表单向API发起POST请求时遇到错误,仅捕获到异常提示:remote host closed the connection。日志显示表单已命中控制器并发送请求,但后续无任何响应。请问可以添加哪些额外的异常处理来帮助定位该问题?
错误信息
System.Web.HttpException (0x80070057): The remote host closed the connection. The error code is 0x80070057. at System.Web.Hosting.IIS7WorkerRequest.RaiseCommunicationError(Int32 result, Boolean throwOnDisconnect) at System.Web.Hosting.IIS7WorkerRequest.ExplicitFlush() at System.Web.HttpResponse.Flush(Boolean finalFlush, Boolean async) at System.Web.HttpWriter.WriteFromStream(Byte[] data, Int32 offset, Int32 size) at Telerik.Sitefinity.Modules.Libraries.Web.LibraryHttpHandler.
代码实现
protected ResultStatus FormCreate(requestWeb model) { var url = string.Format("Permission/SavePermissionRequestForm"); var result = ApiHelpers.Post<ResultStatus>("POST", url, model); return result; } public static T Post<T>(string httpMethod, string url, object model) { try { var fullUrl = cmsApiUrl + url; var json = JsonConvert.SerializeObject(model); Stream dataStream = null; WebRequest Webrequest; Webrequest = WebRequest.Create(fullUrl); Webrequest.ContentType = "application/json"; Webrequest.Method = WebRequestMethods.Http.Post; Webrequest.PreAuthenticate = true; Webrequest.Headers.Add("Authorization", "Bearer " + cmsApiKey); byte[] byteArray = Encoding.UTF8.GetBytes(json); Webrequest.ContentLength = byteArray.Length; dataStream = Webrequest.GetRequestStream(); using (dataStream = Webrequest.GetRequestStream()) { dataStream.Write(byteArray, 0, byteArray.Length); } WebResponse response = Webrequest.GetResponse(); StreamReader reader = new StreamReader(response.GetResponseStream()); StringBuilder output = new StringBuilder(); output.Append(reader.ReadToEnd()); response.Close(); T result = JsonConvert.DeserializeObject<T>(output.ToString()); return result; } catch (Exception e) { T result = JsonConvert.DeserializeObject<T>(""); Elmah.ErrorSignal.FromCurrentContext().Raise(e); return result; } }
额外异常处理与排查手段
1. 细分异常类型捕获,精准记录错误细节
当前代码仅捕获通用Exception,无法区分网络类、HTTP类等特定异常。可以拆分捕获WebException、HttpException等针对性异常,获取更关键的错误信息:
catch (WebException webEx) { var errorDetail = $"Web异常状态:{webEx.Status}"; if (webEx.Response != null) { var httpResponse = (HttpWebResponse)webEx.Response; errorDetail += $",响应状态码:{(int)httpResponse.StatusCode}"; using var reader = new StreamReader(httpResponse.GetResponseStream()); errorDetail += $",响应内容:{reader.ReadToEnd()}"; } Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception(errorDetail, webEx)); return default(T); } catch (HttpException httpEx) { var contextInfo = $"客户端IP:{HttpContext.Current.Request.UserHostAddress},会话ID:{HttpContext.Current.Session?.SessionID}"; Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception($"Http异常:错误码{httpEx.ErrorCode},上下文:{contextInfo}", httpEx)); return default(T); } catch (Exception e) { Elmah.ErrorSignal.FromCurrentContext().Raise(e); return default(T); }
2. 增加请求/响应全链路日志
在请求发送前记录完整URL、请求头、序列化后的请求体;在获取响应后记录响应头、响应体。通过日志确认请求是否合规,以及API是否返回了部分内容:
// 请求发送前记录 var requestLog = $"请求URL:{fullUrl},请求体:{json},Authorization:Bearer {cmsApiKey.Substring(0, 10)}..."; Elmah.ErrorLog.GetDefault(HttpContext.Current).Log(new Error(new Exception(requestLog))); // 获取响应后记录 var httpResponse = (HttpWebResponse)response; var responseLog = $"响应状态码:{(int)httpResponse.StatusCode},响应内容:{output.ToString()}"; Elmah.ErrorLog.GetDefault(HttpContext.Current).Log(new Error(new Exception(responseLog)));
3. 单独处理流操作异常
流写入、读取过程中可能出现连接中断,可单独捕获IOException并记录细节:
try { using (dataStream = Webrequest.GetRequestStream()) { dataStream.Write(byteArray, 0, byteArray.Length); dataStream.Flush(); // 显式刷新确保数据发送完成 } } catch (IOException ioEx) { Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception($"请求流写入失败:{ioEx.Message}", ioEx)); return default(T); }
4. 设置并捕获超时异常
WebRequest默认超时较短,若API处理耗时过长会导致连接主动关闭。添加超时设置并针对性捕获:
Webrequest.Timeout = 30000; // 设置30秒超时 // 在WebException中判断超时 catch (WebException webEx) { if (webEx.Status == WebExceptionStatus.Timeout) { Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception("请求超时", webEx)); } // 其他WebException处理逻辑 }
5. 验证序列化结果兼容性
记录序列化后的JSON内容,排查是否存在格式错误、字段不匹配等问题——这类问题可能导致API处理失败并断开连接:
var json = JsonConvert.SerializeObject(model); Elmah.ErrorLog.GetDefault(HttpContext.Current).Log(new Error(new Exception($"请求序列化结果:{json}")));
内容的提问来源于stack exchange,提问作者Jefferson
相关产品推荐
相关产品推荐

