【问题标题】:Compression Action Filter ASP.NET Core压缩动作过滤器 ASP.NET Core
【发布时间】:2016-06-24 07:27:25
【问题描述】:

我需要使用 ASP.NET Core 创建压缩操作过滤器

我找到了一些 MVC 5 的示例,例如:

public class CompressAttribute : ActionFilterAttribute   {

public override void OnActionExecuting(ActionExecutingContext filterContext)
{

    var encodingsAccepted = filterContext.HttpContext.Request.Headers["Accept-Encoding"];
    if (string.IsNullOrEmpty(encodingsAccepted)) return;

    encodingsAccepted = encodingsAccepted.ToLowerInvariant();
    var response = filterContext.HttpContext.Response;

    if (encodingsAccepted.Contains("deflate"))
    {
        response.AppendHeader("Content-encoding", "deflate");
        response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
    }
    else if (encodingsAccepted.Contains("gzip"))
    {
        response.AppendHeader("Content-encoding", "gzip");
        response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
    }
}  

但是当我尝试将它与

一起使用时
using Microsoft.AspNet.Http;

根本没用:

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc.Filters;
using Microsoft.Extensions.Primitives;

namespace App.Filterss
{
    public class CompressionFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            HttpRequest request = context.HttpContext.Request;

            string acceptEncoding = request.Headers["Accept-Encoding"];

            if (string.IsNullOrEmpty(acceptEncoding)) return;

            acceptEncoding = acceptEncoding.ToUpperInvariant();

            HttpResponse response = context.HttpContext.Response;

            if (acceptEncoding.Contains("GZIP"))
            {
                response.Headers.Add("Content-Encoding", "gzip");
                response.Body = new GZipStream(response.Body, CompressionMode.Compress);
            }
            else if (acceptEncoding.Contains("DEFLATE"))
            {
                response.Headers.Add("Content-encoding", "deflate");
                response.Body = new DeflateStream(response.Body, CompressionMode.Compress);
            }
        }
    }
}

我只得到了 200 个没有任何内容的 http 响应。

谁能提示我如何使用过滤器进行压缩?

【问题讨论】:

  • 你没有调用基本方法:base.OnActionExecuted(context);
  • 一点用都没有。

标签: c# filter compression asp.net-core


【解决方案1】:

这是 ASP.net Core 1.1 的新功能。

这是您需要的软件包。 https://www.nuget.org/packages/Microsoft.AspNetCore.ResponseCompression/

这里有一些官方的微软视频展示了如何使用它: https://youtu.be/IfLg6LQCl-Y?t=223

一些背景资料: https://github.com/aspnet/BasicMiddleware/issues/34

代码:

项目.json:

"dependencies": {
   ...,
   "Microsoft.AspNetCore.ResponseCompression": "1.0.0"
}

Startup.cs:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
//Add Middleware
app.UseResponseCompression();

....
}

public void ConfigureServices(IServiceCollection services)
{
//Configure Compression level
services.Configure<GzipCompressionProviderOptions>(options => options.Level = CompressionLevel.Fastest);

//Add Response compression services
services.AddResponseCompression(options =>
{
    options.Providers.Add<GzipCompressionProvider>();
});
}

【讨论】:

    【解决方案2】:

    查看rynowak 对 ASP.NET Core 1.0 的 GitHib issue 的回答

    1)。如果您在 IIS 上,为什么不直接在 服务器级别? https://technet.microsoft.com/en-us/library/cc753681%28v=ws.10%29.aspx

    2)。我们的默认流不打算被读取。默认情况下,我们这样做 在这些流中进行一些缓冲,但我们不缓冲整个 响应,因为那会占用大量内存。一旦 我们愿意缓冲的数据量已被写入,它会消失 在电线上,我们不再存储它。有一些技巧 启用缓冲,其中之一是替换流。

    3)。如果您想弄乱 MVC 操作的响应流(或 所有 MVC 操作),正确的过滤器阶段是结果过滤器( IResultFilter 或 IAsyncResultFilter )。

    事情就是这样,在你的控制器中调用 View() 正在创建 一个 IActionResult ,稍后将由 MVC 执行,它不是 实际执行内联视图,这就是为什么搞乱 那个阶段的流不会做你想要的。

    结果过滤器实际上围绕着视图代码的执行。

    4)。如果您想弄乱整个响应流 应用程序并且不想/不能使用您提供的 gzip 支持 服务器,那么中间件是一个不错的选择。 (与过滤器相比,过滤器 允许您将范围限定为控制器/操作)。

    如果您仍然对上面使用的中间件方法有疑问: 您是否尝试过在相关操作中设置断点 确定它真的被击中了吗?您是否删除了您的操作过滤器代码 (这不会做你想要的)?

    【讨论】:

    • 太棒了!谢谢你的帖子!
    • 我感兴趣的不是添加压缩本身(当然我可以配置 IIS 服务器),而是有关创建此类过滤器的一般可能性的信息。而这种可能性目前还不清楚。这篇文章声称:(第 3 点)“如果您想弄乱 MVC 操作(或所有 MVC 操作)的响应流,则正确的过滤器阶段是结果过滤器( IResultFilter 或 IAsyncResultFilter )”但我仍然未能添加压缩来自结果过滤器。
    • 所以就我在 asp 核心中的问题而言,我根本无法读取响应正文,并且从现在开始禁用过滤器中打开和关闭响应压缩的整个功能?
    • @OlgaKozlova:在上面的示例中,您正在连接到动作过滤器(覆盖 OnActionExecuting)。要挂钩结果,您需要改写 OnResultExecuting。 rynowak 的第二个选项(替换流)点是指 ben adams 建议添加一个中间件,它替换围绕流的自动刷新工作的流。但是这样做你不能在每个控制器基础上设置它,它是应用程序范围内的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多