问题描述
我有一个 asp.net webforms SaaS 应用程序,其中正在运行多个电子商务网站。每个网站都有自己的域名(abc.com、xyz.com 等),每个网站的内容都是根据域名从数据库中提取的。
现在,为了提高主页性能,我正在实施输出缓存。请注意,主页已经包含多个用户控件(页眉、页脚、顶部菜单、用户菜单、迷你购物车、横幅、家居产品等)。所有用户控件都有资格输出缓存接受用户菜单(显示登录的用户名,否则显示注册/登录链接)和迷你购物车(显示购物车项目的数量,点击它显示购物车中的项目列表) .
我使用 VaryByCustom 在每个用户控件(我想要缓存的)上添加了输出缓存指令,以便为每个域创建单独的缓存。
<%@ OutputCache Duration="300" VaryByParam="*" VaryByCustom="Host" %>
由于 VaryByHeader 不是 UserControls 的可用选项,我在 Global.asax 中添加了一个覆盖函数来返回当前主机。
public override string GetVaryByCustomString(HttpContext context,string arg)
{
if (arg == "Host")
{
return context.Request.Url.Host;
}
return String.Empty;
}
到目前为止,一切正常。正在为不同的域(主机)缓存用户控件,并在指定的时间过期。
问题:我想在管理面板中为网站管理员用户提供一个选项,以手动刷新其网站的缓存。为此,我在前端应用程序中创建了一个页面 (refreshcache.aspx),当管理员用户单击管理面板中的刷新缓存按钮时,只需打开该 url(例如:abc.com/refreshcache.aspx)。
我研究了很多并尝试了多种方法来清除用户控件缓存但失败了。我实现的最后一件事是我在主页 aspx 中添加的以下代码,它创建了一个 StaticPartialCachingControl 对象并添加了对用户控件缓存的关键依赖。
在 Home.aspx 中,我添加了以下在 Page_Load 中调用的代码
protected void LoadControlsCache()
{
CacheKey = "Host-" + Request.Url.Host;
CacheKeyArray[0] = CacheKey;
if (Cache[CacheKey] == null)
{
AddControlCache(header1);
AddControlCache(footer1);
AddControlCache(banner1);
AddControlCache(products1);
}
}
protected void AddControlCache(UserControl uc)
{
StaticPartialCachingControl pcc = (StaticPartialCachingControl)uc.Parent;
pcc.Dependency = new CacheDependency(null,CacheKeyArray);
Cache.Insert(CacheKey,"value",null,DateTime.Now.AddSeconds(300),Cache.NoSlidingExpiration);
}
为了删除特定主机的缓存,我使用了带有主机特定键的 Cache.Remove 方法。
在refreshcache.aspx中我添加了以下代码
protected void Page_Load(object sender,EventArgs e)
{
Cache.Remove("Host-" + Request.Url.Host);
Response.Redirect("/");
}
我不确定我遗漏了什么或做错了什么。只是想要一种方法来清除特定主机(域)的用户控件缓存。
解决方法
最终通过为所有用户控件创建单独的键并添加对用户控件对象的依赖来解决问题。
protected void LoadControlsCache()
{
string CacheKey = Request.Url.Host;
AddControlCache(header1,"header-" + CacheKey);
AddControlCache(footer1,"footer-" + CacheKey);
AddControlCache(banner1,"banner-" + CacheKey);
AddControlCache(products1,"products-" + CacheKey);
}
protected void AddControlCache(UserControl uc,string CacheKey)
{
if (Cache[CacheKey] == null && uc != null)
{
uc.Cache.Insert(CacheKey,1);
uc.CachePolicy.Dependency = new System.Web.Caching.CacheDependency(null,new string[] { CacheKey });
}
}
然后清除缓存,使用 Cache.Remove() 和所有用户控制键。
protected void Page_Load(object sender,EventArgs e)
{
string CacheKey = Request.Url.Host;
Cache.Remove("header-" + CacheKey);
Cache.Remove("footer-" + CacheKey);
Cache.Remove("banner-" + CacheKey);
Cache.Remove("products-" + CacheKey);
Response.Redirect("/");
}
希望它可以帮助有类似问题的人!