我有一个控制器和一个动作。
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,另一个用于放气。 这样做可以根据webbrowser支持的内容提供正确的版本。
[OutputCache(Duration = 10000, VaryByParam = "none", VaryByContentEncoding="gzip;deflate")]
public ActionResult Logout()
{
// ...
}
编辑
除了缺少的VaryByContentEncoding
,还有更多的事情要发生。
Application_BeginRequest
与OutputCacheAttribute
并没有“玩得很好”。
因此,缓存持续时间不再适用。这必须与执行顺序以及在哪个时刻设置哪些标头有关。
而不是依赖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();
}
}