如果将内容编码添加到 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();
}
}
我有一个控制器和一个动作。
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();
}
}