.NET 8中是否存在HttpActionExecutedContext的等效替代类?
.NET 8中替代HttpActionExecutedContext的方案
首先明确:没有和HttpActionExecutedContext完全等效的类,因为.NET 8使用的ASP.NET Core和旧版ASP.NET Web API是架构完全不同的框架,请求/响应上下文的模型已经重构。你遇到的ActionExecutedContext是ASP.NET Core中的对应上下文,但它的Response是HttpResponse类型,和旧的HttpResponseMessage结构差异很大,需要用ASP.NET Core的API重新实现逻辑。
改写原过滤器逻辑的思路
- 检查gzip支持:通过
context.HttpContext.Request.Headers.AcceptEncoding判断客户端是否接受gzip压缩 - 处理响应内容:ASP.NET Core中响应流默认不可重读,需要先将原响应内容缓存到内存流中,再进行压缩
- 替换响应流并设置头:将压缩后的内容写入响应流,同时更新
Content-Encoding、Content-Type等响应头
改写后的示例代码
public override async Task OnActionExecutedAsync(ActionExecutedContext context, CancellationToken cancellationToken) { await base.OnActionExecutedAsync(context, cancellationToken); // 如果客户端不支持gzip,或响应无内容,直接返回 var acceptEncoding = context.HttpContext.Request.Headers.AcceptEncoding.ToString(); if (context.Result == null || !acceptEncoding.Contains("gzip", StringComparison.OrdinalIgnoreCase)) { return; } // 缓存原响应内容 var originalBodyStream = context.HttpContext.Response.Body; using var memoryStream = new MemoryStream(); context.HttpContext.Response.Body = memoryStream; // 触发ObjectResult的执行,确保内容写入内存流 if (context.Result is ObjectResult objectResult) { var executor = context.HttpContext.RequestServices.GetRequiredService<IObjectResultExecutor<ObjectResult>>(); await executor.ExecuteAsync(context, objectResult); } memoryStream.Seek(0, SeekOrigin.Begin); // 替换为压缩流并设置响应头 context.HttpContext.Response.Body = originalBodyStream; context.HttpContext.Response.Headers.ContentEncoding = "gzip"; context.HttpContext.Response.ContentType = "application/json"; using var gzipStream = new GZipStream(context.HttpContext.Response.Body, CompressionLevel.Fastest); await memoryStream.CopyToAsync(gzipStream, cancellationToken); }
更推荐的方案:使用内置响应压缩中间件
ASP.NET Core已经内置了响应压缩功能,不需要手动编写过滤器,只需在Program.cs中配置即可:
var builder = WebApplication.CreateBuilder(args); // 添加响应压缩服务 builder.Services.AddResponseCompression(options => { options.EnableForHttps = true; options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[] { "application/json" }); options.Providers.Add<GzipCompressionProvider>(); }); builder.Services.Configure<GzipCompressionProviderOptions>(options => { options.Level = CompressionLevel.Fastest; }); var app = builder.Build(); // 使用响应压缩中间件(需放在其他业务中间件之前) app.UseResponseCompression(); // 其他中间件配置... app.Run();
这种方式更简洁,且框架已经处理了流的重读、不同响应类型适配等边界情况,稳定性更高。
内容的提问来源于stack exchange,提问作者BigNull
相关产品推荐
相关产品推荐

