11

我已经看到了许多将 GZIP/DEFLATE 压缩添加到 ASP.Net MVC 输出的选项,但它们似乎都在动态应用压缩..因此不利用缓存压缩内容。

任何启用缓存压缩页面输出的解决方案?最好在代码中,以便MVC代码可以检查页面是否发生了变化,如果没有,则将预压缩的缓存内容发送出去。

这个问题确实也适用于常规的 asp.net。

4

7 回答 7

5
[Compress]
[OutputCache(Duration = 600, VaryByParam = "*", VaryByContentEncoding="gzip;deflate")]
public ActionResult Index()
{
    return View();
}
于 2010-10-16T17:57:45.227 回答
3

使用属性(对于 MVC)使用缓存选项,并且不要考虑压缩,因为 IIS/IISExpress 如果启用它会自动压缩您的输出。

它的工作方式是,mvc 不支持缓存单个片段或部分输出(部分内容缓存)。如果你想要这个,考虑使用像 CloudFlare 这样的服务(还有其他像 CF 的吗?)。它会自动缓存您的输出并缓存您的输出片段,并提供许多其他性能和安全改进,所有这些都无需更改您的代码。

如果这不适合您,那么您仍然可以使用 IISpeed(它是 Google 的 mod_pagespeed 的 IIS 端口)。它提供了一些有趣的设置,如空格删除、内联 css 和 js 压缩、js 文件合并等。

CF 和 IISpeed 都不关心您的网站是如何构建的,它们在 http/html 级别上工作,因此它们都可以在 MVC、Classic ASP.NET、php 甚至原始 html 文件上工作。

于 2013-05-07T12:56:49.660 回答
1

您可以创建一个属性,如

public class EnableCompressionAttribute : ActionFilterAttribute  
{  
    const CompressionMode Compress = CompressionMode.Compress;  

    public override void OnActionExecuting(ActionExecutingContext filterContext)  
    {  
        HttpRequestBase request = filterContext.HttpContext.Request;  
        HttpResponseBase response = filterContext.HttpContext.Response;  
        string acceptEncoding = request.Headers["Accept-Encoding"];  
        if (acceptEncoding == null)  
            return;  
        else if (acceptEncoding.ToLower().Contains("gzip"))  
        {  
            response.Filter = new GZipStream(response.Filter, Compress);  
            response.AppendHeader("Content-Encoding", "gzip");  
        }  
        else if (acceptEncoding.ToLower().Contains("deflate"))  
        {  
            response.Filter = new DeflateStream(response.Filter, Compress);  
            response.AppendHeader("Content-Encoding", "deflate");  
        }  
    }  
} 

在Global.asax.cs中添加条目

        public static void RegisterGlobalFilters(GlobalFilterCollection filters)  
        {  
            filters.Add(new EnableCompressionAttribute());  
        }  

然后您可以将此属性用作:

    [EnableCompression]
    public ActionResult WithCompression()
    {
        ViewBag.Content = "Compressed";
        return View("Index");
    }

您可以从 Github 下载工作示例: https ://github.com/ctesene/TestCompressionActionFilter

于 2013-05-08T06:22:39.773 回答
1

链接似乎与您的要求相当接近。它缓存压缩的动态生成的页面。虽然示例使用了 Web 表单,但可以通过使用 OutputCache 属性来适应 MVC

[OutputCache(Duration = 600, VaryByParam = "*", VaryByContentEncoding="gzip;deflate")]
于 2013-05-08T21:13:10.467 回答
0

有关该主题的完整介绍,请参阅使用输出缓存提高性能。主要建议是在应该应用缓存的 Action上使用 [ OutputCache ] 属性。

于 2010-10-17T10:21:42.073 回答
0

您可以创建一个缓存属性:

public class CacheAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;

        if (Enabled)
        {
            cache.SetExpires(System.DateTime.Now.AddDays(30));
        }
        else
        {
            cache.SetCacheability(HttpCacheability.NoCache);
            cache.SetNoStore();
        }
    }

    public bool Enabled { get; set; }

    public CacheAttribute()
    {
        Enabled = true;
    }
}
于 2010-10-16T18:10:01.653 回答
0

使用命名空间

using System.Web.Mvc;

using System.IO.Compression;

在您的主项目中创建 ClassName.cs

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(_response.Filter == null) return;
            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);
            }
        }
    }

--- 并添加 global.asax.cs

GlobalFilters.Filters.Add(new CompressAttribute());
于 2021-06-09T13:32:24.613 回答