看起来使用GetVaryByCustomString 是这里的方法。我的概念证明包括以下内容:
- WebUserControl.ascx:测试控件。它有一个公共属性
MatchDescription。
- Global.asax:覆盖
GetVaryByCustomString 方法。
- WebForm.aspx:承载控件的简单表单。
WebUserControl.ascx
将以下内容添加到控件上的标记中:
<%@ OutputCache Duration="120" VaryByParam="none" VaryByCustom="MatchDescription" %>
这指定缓存控件的持续时间(以秒为单位),VaryByCustom="MatchDescription" 指定我们将缓存的参数的名称。
WebUserControl.ascx.cs
public partial class WebUserControl1 : System.Web.UI.UserControl
{
public string MatchDescription { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
object description = this.Context.Application["MatchDescription"];
if (description != null)
{
this.MatchDescription = description.ToString();
}
else
{
this.MatchDescription = "Not set";
}
Label1.Text = "Match description: " + this.MatchDescription;
}
}
这将检查MatchDescription 值是否存在。由于父页面中代码的工作方式,您应该永远不会看到“未设置”,尽管在您的实现中它可能很有用,以防该值未设置。
Global.asax
在你的项目中添加一个Global.asax文件并添加如下方法:
public override string GetVaryByCustomString(HttpContext context, string custom)
{
if (custom == "MatchDescription")
{
object description = context.Application["MatchDescription"];
if (description != null)
{
return description.ToString();
}
}
return base.GetVaryByCustomString(context, custom);
}
这是检查与缓存控件关联的MatchDescription 的位。如果没有找到该控件将正常创建。使用context.Application 是因为我们需要一种方法来在父页面、用户控件和 global.asax 文件之间传递描述值。
WebForm.aspx.cs
public partial class WebForm : System.Web.UI.Page
{
private static string[] _descriptions = new string[]
{
"Description 1",
"Description 2",
"Description 3",
"Description 4"
};
protected override void OnPreInit(EventArgs e)
{
//Simulate service call.
string matchDescription = _descriptions[new Random().Next(0, 4)];
//Store description.
this.Context.Application["MatchDescription"] = matchDescription;
base.OnPreInit(e);
}
protected void Page_Load(object sender, EventArgs e)
{
var control = LoadControl("WebUserControl.ascx") as PartialCachingControl;
this.Form.Controls.Add(control);
//Indicate whether the control was cached.
if (control != null)
{
if (control.CachedControl == null)
{
Label1.Text = "Control was cached";
}
else
{
Label1.Text = "Control was not cached";
}
}
}
}
请注意,在此代码中,我在 OnPreInit 方法中进行/模拟服务调用。这是必要的,因为它发生在 GetVaryByCustomString 方法之前的页面生命周期中。
请记住,如果一个控件已被缓存,例如在Page_Load 方法中访问它,将需要这种形式的代码:
if (control is PartialCachingControl &&
((PartialCachingControl)control).CachedControl =!= null)
{
WebUserControl1 userControl = (WebUserControl1)((PartialCachingControl)control).CachedControl;
}
参考资料:
我的回答灵感来自:Any way to clear/flush/remove OutputCache?
我在这个问题中找到了Pre_Init 提示:
Output Caching - GetVaryByCustomString based on value set in PageLoad()
这篇知识库文章讨论了为什么 PartialCachingControl.CachedControl 属性总是可以返回 null:
http://support.microsoft.com/kb/837000