如果将内容编码添加到 header,则 OutputCache 不工作

OutputCache is not working if content encoding addded to header

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

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");
            }

 }

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

如果缓存中的这个版本是根据支持例如的请求构建的。 gzip压缩,此缓存数据将以gzip格式压缩。
同样的压缩数据也将提供给不支持压缩或只压缩的请求,结果就是你所看到的。

您必须确保缓存单独的版本; 1 个未压缩,1 个用于 gizp,另一个用于 deflate。
这样做可以根据网络浏览器支持的内容提供正确的版本。

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

编辑

除了缺失的 VaryByContentEncoding,还有更多内容。

Application_BeginRequest 不是 'playing nice' 和 OutputCacheAttribute
因此,不再应用缓存持续时间。 这一定与执行顺序有关,headers 在哪个时刻设置。

不再依赖 Application_BeginRequest 将压缩代码移至操作过滤器, ASP.NET MVC 这是在请求管道内采取行动的建议方式。
请参阅下面的 CompressAttribute

举个例子,我把它应用到HomeController上的out-of-the框About方法。
这次,结果如预期匹配请求和响应 http-headers.

压缩属性:

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");
            }
        }
    }
}

家庭控制器:

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();
    }        
}