我有一个控制器和一个动作。
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");
}
}
答案 0 :(得分:0)
您必须添加一个VaryByContentEncoding
。
没有一个版本,仅缓存1个版本。
如果高速缓存中的此版本是根据支持(例如)的请求构建的gzip压缩,此缓存的数据将以gzip格式压缩。
然后,相同的压缩数据也将被提供给不支持压缩或仅压缩的请求,从而产生您所看到的结果。
您必须确保缓存单独的版本; 1个未压缩,1个用于gizp,另一个用于放气。
这样可以根据网络浏览器支持的版本提供正确的版本。
[OutputCache(Duration = 10000, VaryByParam = "none", VaryByContentEncoding="gzip;deflate")]
public ActionResult Logout()
{
// ...
}
编辑
除了缺少的VaryByContentEncoding
,还有更多事情要做。
Application_BeginRequest
与OutputCacheAttribute
玩的不好。
因此,缓存持续时间不再适用。
这必须与执行顺序以及在什么时候设置哪些标头有关。
与其依靠Application_BeginRequest
来将压缩代码移至动作过滤器,
对于ASP.NET MVC
而言,这是在请求管道内采取行动的建议方式。
请参见下面的CompressAttribute
。
通过示例,我将其应用于About
上的即用型HomeController
方法。
这次,结果符合预期,与请求和响应的HTTP标头匹配。
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();
}
}