我有一个带有公共(public) int
属性 SelectedCatID
的 webusercontrol
。我在其他页面和其他控件中使用此控件,如下所示:
<NewStore:LeftMenuLinks runat="server" SelectedCatID="<%#CatIDToSelect%>" />
如何根据SelectedCatID
输出缓存此控件?我尝试过的一切都失败了。
我得到的最接近的结果是将其缓存,但它不会因SelectedCatID
而变化,保持选择相同的菜单项直到缓存过期。如果没有缓存,控件将按预期工作。
最佳答案
我明白了为什么您最初使用的 VaryByControls 方法不起作用。遗憾的是,您将其从问题中删除了,所以我对此的研究只能写在一篇博客文章中。更新:有问题的博客文章:http://tabeokatech.blogspot.be/2014/09/outputcache-on-user-controls.html .
总而言之,VaryByControls 是 VaryByParams 的缩写,对属性没有任何作用:它只查看 POST 值。事实上,它曾经适用于具有静态值的属性,这似乎是一个错误 - VaryByControls 中的任何字符串都会使该部分起作用。这个问题接受的答案是错误的:Vary by control properties using PartialCaching in ASP.NET 。
没有内置方法可以根据控件属性值进行更改。
无论如何,这没有意义,因为需要创建用户控件来具有属性值,并且您希望避免创建它们,而是缓存它们呈现的标记 - 如果缓存标记,则缓存的用户控件字段在代码隐藏中为空是为他们服务的。 这是通过将 PartialCachingControl 而不是实际的用户控件注入(inject)到页面中来实现的。此 PartialCachingControl 检查缓存,并且仅在不存在缓存版本时创建控件。
至于使其发挥作用,我看到两种选择:
如果每页只有 1 个用户控件,则可以使用 VaryByCustom 方法。为了使事情变得简单,您可以编写一个返回该页面的属性值的接口(interface),并在托管用户控件的每个页面上实现它,例如:
interface INumberProvider { int GetNumber(); } // and the page: public partial class _Default : Page, INumberProvider { public int GetNumber() { return this.SomeNumberPropertyOrWhatever; } ...
在 Global.asax 中,将当前处理程序转换为 INumberProvider 并获取数字:
public override string GetVaryByCustomString(HttpContext context, string custom) { if (custom == "INumberProvider") { var page = context.CurrentHandler as INumberProvider; if (page != null) { return page.GetNumber().ToString(); } } return base.GetVaryByCustomString(context, custom); }
在您的控制中,您显然会添加:
OutputCache Duration="180"VaryByCustom="INumberProvider"VaryByParam="None"Shared="true"
如果每页只有一个用户控件,那么这应该非常简单。如果您每页需要多个用户控件,那么您就不走运了:
- 通过编写自定义 WebControl 来围绕用户控件构建您自己的包装器。添加所需的属性,捕获所呈现的用户控件的输出,并使用包含 SelectedCatID 的键将其插入到 HttpContext.Current.Cache 中。基本上编写您自己的自定义 PartialCachingControl。 还有选项 3:
- 决定缓存毕竟没那么重要
关于asp.net - 使用 webusercontrol 获取输出缓存以在 ASP.net 中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25525641/