我们有一个相当标准的电子商务方案,其中包含类别中的产品分页列表。无论好坏,大约80%的访问者从未浏览过第一页,根据类别,可能会有5-10多个结果页面,这些页面的查看次数要少得多。 (是的,我们会优化第一页上显示的内容并进行良好的搜索 - 但这是一个不同的讨论)
我们无法缓存每一页结果,因为我们受到内存的限制,但缓存每个类别的第一页结果的好处将是巨大的。
我知道我可以使用对象缓存来存储有问题的数据集,但这可能是使用输出缓存,也许是使用response.Cache对象吗?
页面生命周期中的哪个位置可以完成?预呈现?
很简单,URL类似于“/ ProductList?Category = something& Page = 1”而且我想要逻辑类似(伪代码):
If paramater "Page" equals 1
Use output caching: vary by param = "categoryName; page"
else
Don't use caching at all, just render the page from scratch.
我们在IIS 6 / win2003上使用ASP.NET 2.0。
答案 0 :(得分:31)
您可以通过编程方式执行相同的操作,而不是使用OutputCache指令,如下所示:
if (yourArbitraryCondition) {
OutputCacheParameters outputCacheSettings = new OutputCacheParameters();
outputCacheSettings.Duration = 60;
InitOutputCache(outputCacheSettings);
}
从OnInit执行此操作应该可以正常工作。显然,您可以通过在OutputCacheParameter上设置各种属性来调整缓存行为,该属性具有与指令相同的旋钮(事实上,这是我们在使用指令时生成的)。
关键是你只是有条件地执行这个逻辑,而指令使它成为无条件的。
<强>更新强>
作为替代方案,您可以使用构建上述代码的低级缓存API。 e.g。
HttpCachePolicy cache = Response.Cache;
cache.SetCacheability(HttpCacheability.Public);
cache.SetExpires(Context.Timestamp.AddSeconds(60));
cache.VaryByParams["categoryName"] = true;
基本上,这是做同样事情的另一种方式,不使用任何标记为“不应该被调用”的API。最后,无论哪种方式都有效,请选择。
答案 1 :(得分:5)
编辑: 我更喜欢David Ebbo的回答。
您可以使用
<%@ OutputCache Duration="60" VaryByParam="none" VaryByCustom="pageOne" %>
以一种方式实现它,返回第一页的固定键和所有其他页的随机键。您可以(并且应该)让scavenging机制处理内存,但如果必须,可以使用HttpResponse.RemoveOutputCacheItem
删除缓存项。
public override string GetVaryByCustomString(HttpContext ctx, string custom)
{
if(custom == "pageOne")
{
if(ctx.Request["page"] == "1")
{
return "1";
}
HttpResponse.RemoveOutputCacheItem("/Default.aspx");
return Guid.NewGuid().ToString();
}
return base.GetVaryByCustomString(ctx, custom);
}
答案 2 :(得分:4)
我认为最好的方法是使用HttpCachePolicy.AddValidationCallback
请参阅http://www.hanselman.com/blog/AdvancedASPNETCachingAndAddValidationCallBack.aspx - 这是一个完整的例子,可以准确回答这个问题。
答案 3 :(得分:1)
你仍然可以使用outputcache指令,在我看来,不是通过一堆缓存螺母和螺栓丢弃你的页面代码,你最好使用基于在Global中处理它的可重用解决方案。 asax你通常会采用任何VaryByCustom方案。
因此,例如,如果您使用转发器的分页方法,您可能只是在搜索方案中想要从缓存中排除特定页面上的任何回发。 Here是一个代码示例。在捕获您希望避免缓存的任何条件之后,该方法仅需要使用HttpContext对象来访问Response.Cache.SetNoServerCaching()。我希望这会有所帮助。
答案 4 :(得分:0)
我认为您应该能够将OutputCache directive与VaryByParam属性设置为以分号分隔的字符串列表,用于改变输出缓存。
除非你想在Page == 1?
时只缓存