如果将内容编码添加到标头,则OutputCache不起作用

问题描述 投票:1回答:1

我有一个控制器和一个动作。

public class LoginController
{
    [OutputCache(Duration = 10000, VaryByParam = "none")]
    public ActionResult Logout()
    {
        ......
    }
}

上面的代码工作正常,输出缓存没有问题。一切都好。

但是当我将下面的代码添加到Application_BeginRequest时出现了问题。我添加了页面的图片。

 string encodings = app.Request.Headers.Get("Accept-Encoding");
 if (encodings != null)
 {
            // Check the browser accepts deflate or gzip (deflate takes preference)
            encodings = encodings.ToLower();

            if (encodings.Contains("gzip"))
            {
                app.Response.Filter = new GZipStream(app.Response.Filter, CompressionMode.Compress);
                app.Response.AppendHeader("Content-Encoding", "gzip");
            }
            else if (encodings.Contains("deflate"))
            {
                app.Response.Filter = new DeflateStream(app.Response.Filter, CompressionMode.Compress);
                app.Response.AppendHeader("Content-Encoding", "deflate");
            }

 }

The page is ....

asp.net gzip outputcache deflate content-encoding
1个回答
0
投票

你必须添加一个VaryByContentEncoding。 没有一个,只有1个版本被缓存。

如果缓存中的这个版本是从支持例如的请求构造的。 gzip压缩,这个缓存的数据将以gzip格式压缩。 然后,这些相同的压缩数据也将被提供给不支持压缩或仅收缩的请求,这会导致您看到的内容。

您必须确保缓存单独的版本; 1个非压缩,1个用于gizp,另一个用于放气。 这样做可以根据webbrowser支持的内容提供正确的版本。

[OutputCache(Duration = 10000, VaryByParam = "none", VaryByContentEncoding="gzip;deflate")]
public ActionResult Logout()
{
    // ...
}

编辑

除了缺少的VaryByContentEncoding,还有更多的事情要发生。

Application_BeginRequestOutputCacheAttribute并没有“玩得很好”。 因此,缓存持续时间不再适用。这必须与执行顺序以及在哪个时刻设置哪些标头有关。

而不是依赖Application_BeginRequest将压缩代码移动到动作过滤器,这对于ASP.NET MVC来说是建议的在请求管道中行动的方式。 请参阅下面的CompressAttribute

通过示例,我将它应用于About上开箱即用的HomeController方法。 这次,结果与请求和响应http-headers匹配。

CompressAttribute:

public class CompressAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpRequestBase request = filterContext.RequestContext.HttpContext.Request;
        HttpResponseBase response = filterContext.RequestContext.HttpContext.Response;

        string encodings = request.Headers.Get("Accept-Encoding");
        if (encodings != null)
        {
            // Check the browser accepts deflate or gzip (deflate takes preference)
            encodings = encodings.ToLower();

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

HomeController的:

public class HomeController : Controller
{
    [Compress()]
    [OutputCache(Duration = 10, VaryByParam = "none", VaryByContentEncoding="gzip;deflate")]
    public ActionResult About()
    {
        ViewBag.Message = DateTime.Now.ToString("dd/MM/yy HH:mm:ss.fff");
        return View();
    }        
}
© www.soinside.com 2019 - 2024. All rights reserved.