我来晚了,因为已经有一个被接受的答案和500点赏金奖励。但我仍想提供我的意见,关于如何实现这个。
它可以在控件本身中工作。您可以让控件将自己的输出存储在缓存中,并在Render
方法中使用缓存版本(如果找到)。我制作了一个非常简单的UserControl
进行测试。标记看起来像这样:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="TestUC.ascx.cs"
Inherits="Webforms_Test.UserControls.TestUC" %>
<div>
<asp:Label ID="curTime" runat="server"></asp:Label>
</div>
它只包含一个标签,当初始化时设置为DateTime.Now
。其后的代码如下:
public partial class TestUC : System.Web.UI.UserControl
{
private string cachedOutput = null;
public bool RenderFromCache = true;
protected void Page_Load(object sender, EventArgs e)
{
cachedOutput = HttpContext.Current.Cache["key"] as string;
if (cachedOutput == null)
{
curTime.Text = "UC:" + DateTime.Now.ToString("yy-MM-dd hh:mm:ss");
}
}
protected void Page_PreRender(object sender, EventArgs e)
{
if (cachedOutput == null || !RenderFromCache)
{
RenderFromCache = false;
StringBuilder b = new StringBuilder();
HtmlTextWriter h = new HtmlTextWriter(new StringWriter(b));
this.RenderControl(h);
cachedOutput = b.ToString();
HttpContext.Current.Cache.Insert("key", cachedOutput, null, DateTime.UtcNow.AddSeconds(10), TimeSpan.Zero);
RenderFromCache = true;
}
}
protected override void Render(HtmlTextWriter writer)
{
if (!RenderFromCache)
base.Render(writer);
else
writer.Write(cachedOutput);
}
}
在这个示例中,控件本身会检查其输出是否在缓存中找到,如果是,则
Render
方法将只写入缓存的输出。如果在缓存中未找到,则
PreRender
方法将正常运行
Render
方法并捕获输出并将其存储在缓存中。
在您的情况下,您当然需要更多的逻辑来检查控件上的相关属性,并使用该属性来检查是否存在缓存版本。
免责声明:这是一个非常简单的测试控件。我没有尝试弄清楚如何使所有这些与包含事件处理程序等控件一起工作。所以请根据实际情况进行理解...
VaryByControl
属性应该匹配要缓存的用户控件的 ID,而不仅仅是控件的任意属性。如果您在代码后台检查了控件是否存在,并设置了变量供NewStore:LeftMenuLinks
用户控件使用,那么它能正常工作吗? - Justin