代理服务器响应发送报错:返回缓存响应遇InvalidOperationException异常
解决方案:修复Response已启动无法清空的错误
你遇到这个错误主要有两个原因:一是Response.HasStarted的判断存在竞态条件——判断之后到执行写入操作的间隙,可能有其他中间件悄悄启动了响应;二是response.Clear()在ASP.NET Core里本身就不是安全操作,一旦响应开始发送,这个调用必然报错。
要实现“返回缓存响应并阻止请求转发到第三方API”的需求,直接按下面的方式改代码就行:
var result = await priceFilter.ValidateRequest(document); if (result != null) { var response = _httpContext.Response; // 直接终止请求管道,阻止后续转发到第三方API _httpContext.Abort(); // 设置响应参数并写入缓存内容 response.StatusCode = 200; response.ContentType = "text/xml;charset=utf-8"; var buffer = Encoding.UTF8.GetBytes(result); await response.Body.WriteAsync(buffer, 0, buffer.Length); await response.Body.FlushAsync(); }
如果是在自定义中间件里处理,更稳妥的写法是把缓存逻辑放在管道最前面,彻底避免响应被提前启动:
// 注意:这个中间件要注册在所有可能启动响应的中间件之前 public async Task InvokeAsync(HttpContext context, RequestDelegate next) { var document = // 从请求中获取你的document对象 var result = await priceFilter.ValidateRequest(document); if (result != null) { var response = context.Response; response.StatusCode = 200; response.ContentType = "text/xml;charset=utf-8"; var buffer = Encoding.UTF8.GetBytes(result); response.ContentLength = buffer.Length; await response.Body.WriteAsync(buffer); await response.Body.FlushAsync(); // 直接返回,不执行后续中间件(也就不会转发到第三方API) return; } // 没有缓存内容,继续走后续管道 await next(context); }
核心注意事项:
- 提前拦截:把缓存响应的逻辑放在中间件管道最靠前的位置,不给其他中间件启动响应的机会。
- 别用Clear():直接设置响应状态和内容就行,清空操作本身就是触发错误的根源。
- 终止管道:用
return(中间件内)或context.Abort()切断后续流程,确保请求不会发到第三方API。
内容的提问来源于stack exchange,提问作者Parmiz
相关产品推荐
相关产品推荐

