You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 09:15:23