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

ASP.NET Core自定义加密中间件触发客户端响应提前结束异常排查

问题根因与修复方案

核心问题点

  • 未更新Content-Length响应头:控制器返回原始响应内容时,框架会自动写入和原始内容长度匹配的Content-Length头。你将内容加密后长度发生了变化,但代码中没有同步修改该响应头,客户端按照原始长度读取响应数据,和实际返回的加密内容长度不匹配,就会触发「响应提前结束」的异常。application/json场景下Postman对响应格式校验更严格,所以直接无法展示内容,text/plain校验宽松所以能展示内容,但客户端依然会报错。
  • StreamReader未配置leaveOpen参数:默认情况下StreamReader销毁时会自动关闭底层的MemoryStream,属于不规范的流操作,可能引发不可预期的流异常。
  • 缺少异常/非成功响应过滤逻辑:如果控制器返回重定向、错误状态码、或已经开始写入响应的场景,你依然强行修改响应内容,也会引发异常。

修复后的代码

public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
    string reponseContent = string.Empty;
    // 响应已经开始发送时不能再修改,直接跳过
    if (context.Response.HasStarted)
    {
        await next(context);
        return;
    }

    var existingBody = context.Response.Body;
    using (var newBody = new MemoryStream())
    {
        context.Response.Body = newBody;
        await next(context);

        // 只处理200状态码的响应,其他状态直接返回原始内容,可按需调整过滤条件
        if (context.Response.StatusCode != StatusCodes.Status200OK)
        {
            newBody.Seek(0, SeekOrigin.Begin);
            await newBody.CopyToAsync(existingBody);
            context.Response.Body = existingBody;
            return;
        }

        context.Response.Body = existingBody;
        newBody.Seek(0, SeekOrigin.Begin);

        // 配置leaveOpen: true,避免StreamReader销毁时关闭底层MemoryStream
        using (var contentReader = new StreamReader(newBody, leaveOpen: true))
        {
            reponseContent = await contentReader.ReadToEndAsync();
        }

        string encryptedData = _cryptoService.Encrypt(reponseContent);
        // 同步更新Content-Length为加密后内容的实际长度
        context.Response.ContentLength = Encoding.UTF8.GetByteCount(encryptedData);

        await context.Response.WriteAsync(encryptedData);
    }
}

额外注意点

如果加密后的结果不是纯文本格式,可以根据实际业务需求同步调整Content-Type响应头。

内容的提问来源于stack exchange,提问作者Tony Riddle

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 11:12:01