我们知道OutputCache缓存的设置是在 OutputCacheModule 的OnLeave方法中,这里面有一个条件判断,只有当 flag = true才会做缓存处理,但是这个条件究竟要做些什么了,为了还理解代码我们把代码调整一下:
if (response.HasCachePolicy)
{
cache = response.Cache;
if ( cache.IsModified() && response.Cookies.Count <= 0 && response.StatusCode == 200
&& (request.HttpVerb == HttpVerb.GET || request.HttpVerb == HttpVerb.POST)
&& response.IsBuffered())
{
bool flag3 = false;
if ((cache.GetCacheability() == HttpCacheability.Public) && context.RequestRequiresAuthorization())
{
cache.SetCacheability(HttpCacheability.Private);
flag3 = true;
}
if ((
(cache.GetCacheability() == HttpCacheability.Public ||
cache.GetCacheability() == HttpCacheability.ServerAndPrivate||
cache.GetCacheability() == HttpCacheability.Server || flag3) &&
!cache.GetNoServerCaching()
&& (cache.HasExpirationPolicy() ||
cache.HasValidationPolicy()))
&& ((!cache.VaryByHeaders.GetVaryByUnspecifiedParameters()
&& (cache.VaryByParams.AcceptsParams() || (request.HttpVerb !=
HttpVerb.POST && !request.HasQueryString) ))
&& (!cache.VaryByContentEncodings.IsModified()
||
cache.VaryByContentEncodings.IsCacheableEncoding(context.Response.GetHttpHeaderContentEncoding())
)
))
{
flag = true;
}
}
}
尤其是里面的条件比较复杂,现在我们就来看看这个条件究竟干了些什么吧:
response.HasCachePolicy这个属性基本上都是为true的。一般我们不用考虑它为false的情况。cache.IsModified()、IsBuffered()一般情况下也是为true的。外层条件我们需要注意一个条件就是response.Cookies.Count <= 0,也就是说 我们的服务端是不能写Cookie,一旦写入Cookie则缓存失效。
在内层的判断分为3部分,我已经用不同的颜色区分它们了:
第一部分我们需要cache.GetNoServerCaching()这个方法必须返回fasle,返回true的情况有2种分别是配置为:noStore="true"和调用 HttpCachePolicy的 public void SetNoServerCaching()方法,第一部分的判断其它也好理解。
第二部分中GetVaryByUnspecifiedParameters方法必须返回 false,该方法一般返回都是false,返回为true的情况也比较好理解,如果调用HttpCacheVaryByHeaders的 public void VaryByUnspecifiedParameters()方法,剩下的也比较好理解。
第三部分也很好理解,检查VaryByContentEncodings是否被修改,如果修改了那么它必须包含context.Response.GetHttpHeaderContentEncoding()。
我现在实际项目中也没遇到什么特别的,只是输出流设置Cookies时缓存无效倒是遇到过,总之这几个判断条件还是比较重要的,希望大家小心啊。