Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 压缩操作过滤器ASP.NET内核_C#_Filter_Compression_Asp.net Core - Fatal编程技术网

C# 压缩操作过滤器ASP.NET内核

C# 压缩操作过滤器ASP.NET内核,c#,filter,compression,asp.net-core,C#,Filter,Compression,Asp.net Core,我需要使用ASP.NET核心创建压缩操作过滤器 我找到了一些MVC 5的示例,如: public class CompressAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { var encodingsAccepted = filterContext.HttpContext.Request.Header

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

我找到了一些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响应,没有任何内容

有谁能告诉我如何使用筛选器执行压缩吗?

请在for ASP.NET Core 1.0上查看的答案

1) 。如果您使用的是IIS,为什么不同时使用动态压缩呢 服务器级?

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

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

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

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

4) 。如果你想把整个系统的响应流搞得一团糟 应用程序,不想/不能使用您的 服务器,那么中间件就是一个不错的选择。(与过滤器相比 允许您将范围扩展到控制器/操作)

如果您仍然对上面使用的中间件方法存在问题: 你有没有试过在有问题的行动中设定一个转折点,以使 真的被击中了吗?您是否删除了操作筛选器代码 (哪一个做不到你想要的)


这是ASP.net Core 1.1中的一项新功能

这是您需要的软件包。

以下是一些microsoft官方视频,展示了如何使用它:

一些背景资料:

代码:

Project.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>();
});
}
public void配置(IApplicationBuilder应用程序、IHostingEnvironment环境、iLogger工厂)
{
...
//添加中间件
app.UseResponseCompression();
....
}
public void配置服务(IServiceCollection服务)
{
//配置压缩级别
services.Configure(options=>options.Level=CompressionLevel.faster);
//添加响应压缩服务
services.AddResponseCompression(选项=>
{
options.Providers.Add();
});
}

您没有调用base方法:
base.OnActionExecuted(上下文)一点帮助都没有。太好了!谢谢你的帖子!我感兴趣的不是添加压缩本身(当然我可以配置IIS服务器),而是关于创建这样一个过滤器的一般可能性的信息。而这种可能性目前还不清楚。这篇文章声称:(第3点)“如果您想干扰MVC操作(或所有MVC操作)的响应流,那么正确的过滤器阶段是结果过滤器(IResultFilter或IAsyncResultFilter)”但我仍然无法从结果过滤器中添加压缩。就我在asp核心中所关心的问题而言,我根本无法读取Response正文,并且从现在起,过滤器中打开和关闭Response压缩的整个功能都被禁用了?@OlgaKozlova:在上面的示例中,您正在连接到动作过滤器(重写
OnActionExecuting
)。要挂接到结果,您需要重写
OnResultExecuting
。rynowak的第二个选项(替换流)这一点是指ben adams建议添加一个中间件,它取代了围绕流的自动刷新工作的流。但是这样做你不能在每个控制器的基础上设置它,它的应用范围很广