压缩操作过滤器 ASP.NET Core

Olg*_*ova 5 c# compression filter asp.net-core

我需要使用 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);
    }
}  
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用它时

using Microsoft.AspNet.Http;
Run Code Online (Sandbox Code Playgroud)

它根本不起作用:

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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

有人可以告诉我如何使用过滤器进行压缩吗?

Tse*_*eng 1

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

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 支持,那么中间件是一个不错的选择。(与过滤器相比,过滤器允许您将范围限制为控制器/操作)。

如果您对上面使用的中间件方法仍然存在问题:您是否尝试在相关操作中设置断点以确保它确实被命中?您是否删除了操作过滤器代码(这不会执行您想要的操作)?