最近在做PageAdmin cms时候,栏目页用了http缓存,iis站点绑定了多个域名,后台也是每个站点绑定多个域名,最开始的http缓存写法如下:
HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache; TimeSpan cacheDuration = TimeSpan.FromSeconds(Duration);//Duration为缓存过期时间,单位秒 cache.SetCacheability(HttpCacheability.Public); cache.SetExpires(DateTime.Now.Add(cacheDuration)); cache.SetMaxAge(cacheDuration); //cacheDuration cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
后来有个用户网站使用多站点的时候,每个站点绑定了一个域名,而且都启用了开启了缓存,结果每个域名打开的首页都是一样的,都是第一个服务器缓存的首页,后来研究了HttpCachePolicyBase这个类,其中有一个属性
public virtual HttpCacheVaryByHeaders VaryByHeaders { get; }
看名称就知道是根据头信息缓存,但是发现没有set访问器,也没有办法直接赋值,好吧,再次跟踪HttpCacheVaryByHeaders
代码如下
using System.Reflection; namespace System.Web { // // 摘要: // 提供一种设置 System.Web.HttpCachePolicy.VaryByHeaders 属性的类型安全的方法。 [DefaultMember("Item")] public sealed class HttpCacheVaryByHeaders { // // 摘要: // 初始化 System.Web.HttpCacheVaryByHeaders 类的新实例。 public HttpCacheVaryByHeaders(); // // 摘要: // 获取或设置一个自定义标头字段,ASP.NET 输出缓存将随该字段改变缓存的响应,并将其追加到传出的 Vary HTTP 标头。 // // 参数: // header: // 自定义标头的名称。 // // 返回结果: // 当 ASP.NET 输出缓存随指定的自定义字段而变化时,则为 true ;否则为 false。默认值为 false。 // // 异常: // T:System.ArgumentNullException: // header 为 null。 public bool this[string header] { get; set; } // // 摘要: // 获取或设置一个值,该值指示 ASP.NET 输出缓存是否随 Accept HTTP 标头而改变缓存的响应并将该标头追加到传出的 Vary HTTP 标头。 // // 返回结果: // 当 ASP.NET 输出缓存随 Accept 标头而改变时,则为 true;否则为 false。默认值为 false。 public bool AcceptTypes { get; set; } // // 摘要: // 获取或设置一个值,该值指示 ASP.NET 输出缓存是否随 Accept-Language 标头改变缓存的响应并将该标头追加到传出的 Vary HTTP // 标头。 // // 返回结果: // 当 ASP.NET 输出缓存随 Accept-Language 标头而变化并将该标头添加到被发送到客户端的 Vary HTTP 标头时,则为 true;否则为 // false。默认值为 false。 public bool UserLanguage { get; set; } // // 摘要: // 获取或设置一个值,该值指示 ASP.NET 输出缓存是否随 User-Agent 标头改变缓存的响应并将该标头追加到传出的 Vary HTTP 标头。 // // 返回结果: // 当 ASP.NET 输出缓存随 User-Agent 标头而变化并将该标头添加到被发送到客户端的 Vary HTTP 标头时,则为 true;否则为 false。默认值为 // false。 public bool UserAgent { get; set; } // // 摘要: // 获取或设置一个值,该值指示 ASP.NET 输出缓存是否随 Accept-Charset 标头改变缓存的响应并将该标头追加到传出的 Vary HTTP 标头。 // // 返回结果: // 当 ASP.NET 输出缓存随 Accept-Charset 标头而变化并将该标头添加到被发送到客户端的 Vary HTTP 标头时,则为 true;否则为 // false。默认值为 false。 public bool UserCharSet { get; set; } // // 摘要: // 导致 ASP.NET 随所有标头值而变化,并将 Vary HTTP 标头设置为值 *(星号)。所有其他 Vary 标头信息将被丢弃。 public void VaryByUnspecifiedParameters(); } }
上面代码可以看到,发现有一个public bool this[string header] { get; set; }属性可以设置,那就问题解决,缓存声明时添加一个host请求头就可以了,代码如下:
HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
cache.VaryByHeaders["host"]=true;//host不同时缓存不同
TimeSpan cacheDuration = TimeSpan.FromSeconds(Duration);//单位秒
cache.SetCacheability(HttpCacheability.Public);
cache.SetExpires(DateTime.Now.Add(cacheDuration));
cache.SetMaxAge(cacheDuration);
cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
看红色部分,设置一个host来区分就可以了,完美解决多个域名缓存冲突的问题。