好吧,似乎没有结束的文章,歌颂输出缓存和它将加快你的网站的多少。我现在已经阅读了数百篇关于这个主题的文章和问题,但我似乎仍然无法让它发挥作用。(我认为输出缓存可能会窃取我的灵魂)
我的要求很简单,我想根据参数缓存3页: Home、结果和细节。我也有一个小面积的页面,需要根据用户的变化。我还需要缓存到一个中央存储库,我选择了redis来保存我的数据。我还应该指出,这仍然是一个古老的web表单应用程序。
我最初的方法是尝试使用"VaryByCustom“选项提供自己的自定义字符串。Microsoft页面似乎让这看起来很简单:
https://msdn.microsoft.com/en-us/library/5ecf4420.aspx
这需要在GetVaryByCustomString文件中放置一个重写的方法“global.asax”。问题在于,大多数示例都使用HttpContext中始终可用的变量(浏览器、浏览器版本等)。尽管Microsoft和其他人似乎认为这是首选的“按自定义字符串缓存”方法,但我找不到任何允许页面定义字符串的工作示例。我见过一些使用会话并声称它可以工作(会话对我来说是空的)和context.user (有人说用户是空的)的例子,但是除了使用context.user之外,我没有看到任何实际的交付字符串的方法。在对主项目中的实现进行了一天的绞尽脑汁之后,我决定构建一个独立的项目来测试/验证概念。在这个项目中,只要我将自定义字符串作为字符串传递给SetVaryByCustom,我就能够使它正常工作。问题是,这与我所见过的任何例子都不匹配。示例显示"SomeKey“,GetVaryByCustomString返回"SomeValue”。对我起作用的基本上是"SomeValue“和"SomeValue”。这是我的密码:
public override string GetVaryByCustomString(HttpContext context, string arg)
{
if (arg != null)
{
return arg;
}
return base.GetVaryByCustomString(context, arg);
}这是第一次在页面上工作,设置了创建回发的下拉列表的值,但之后就没有了。因此,"OnselectedItemChanged“触发了一次,并根据所选内容创建了一组新的缓存条目,但从未再次触发。我试图修改几乎所有的缓存参数,以使其正常工作,但无论我尝试了哪些系列设置(以声明方式设置缓存、在代码中设置缓存、尝试各种VaryByParams组合、添加位置等),我都没有成功。
在尝试了两天后,我决定采取一种不同的方法。我回到了一种更传统/被接受的方法。我在web.config中创建了3个缓存配置文件:
<caching>
<cache disableExpiration="false" />
<outputCache defaultProvider="RedisOutputCacheProvider" enableOutputCache="true" enableFragmentCache="true" sendCacheControlHeader="true">
<providers>
<add name="RedisOutputCacheProvider"
type="LAC.OutputCacheProvider, LAC"
connectionString="192.168.XX.XX:6379,connectTimeout=10000"
dbNumber="5"
keyPrefix="LAC:OutputCache:" />
</providers>
</outputCache>
<outputCacheSettings>
<outputCacheProfiles>
<add name="Home" varyByParam="*" varyByCustom="user" duration="86400"/>
<add name="Results" varyByParam="*" varyByCustom="user" duration="7200" />
<add name="Details" varyByParam="*" varyByCustom="user" duration="7200"/>
</outputCacheProfiles>
</outputCacheSettings>
</caching>因此,每个页面都有一个根据用户字符串而变化的自定义,这将帮助我为经过身份验证的用户缓存一个新页面,而不是一个匿名页面。然后我添加了一个GetVaryByCustomString,它看起来像:
public override string GetVaryByCustomString(HttpContext context, string arg)
{
switch (arg)
{
case "user":
var identity = context.User.Identity.Name != "" ? context.User.Identity.Name : "Anonymous";
return string.Format("IsAuthenticated={0},Identity={1}", context.Request.IsAuthenticated, identity);
}
return string.Empty;
}我和以前一样接近完成这份工作,但还没有达到100%。主页工作正常,细节页面运行良好,但结果页面从不缓存。结果页面有一个过滤器,包含12个不同的下拉列表。所以它需要根据选择来存储页面的版本。我在所有页面的顶部加了一个时间戳,这样我就可以看到页面是否在缓存。每次我点击control-F5时,结果页面上的时间都会发生变化,这在其他2页中是不正确的。从来没有创建过缓存条目,也从来没有调用过GetVaryByCustomString。我已经三次检查了代码中的某种类型的“关闭缓存”设置,但据我所知,页面中没有禁用缓存的代码。我的global.asax文件继承自正确的类,我的自定义ouputcache提供程序似乎为工作的2页添加了正确的条目。当然,现在使用VaryByParam="*“的关键可以是内容,这要感谢viewstate (必须保留在BLECH上)!
因此,本质上,我在三个类似的页面上设置了缓存,其中一个不能工作。我不知道下一步该去哪里找。我希望像@kevinmontrose这样对这类事情有处理能力的人会同情我,把我推到一个能让我找到解决方案的方向。
更新:我已经和微软打开了一个箱子。
发布于 2015-09-22 08:28:33
你设置VaryByParam了吗?我现在忘记了细节,但我记得在发现这是强制性的之前,我被困住了。(我想在每一种情况下。(?))我认为也需要持续时间。(我指的是.aspx页面中的指令。)
发布于 2015-09-22 21:52:21
重新阅读您的问题时,我看到了这个问题:“我找不到任何允许页面定义字符串的工作示例。”我重读了一些文章,我很确定这是错误的方法。
我还没有对所有这些进行测试,但对于ex,如果您以标准示例为例:
<%@ OutputCache Duration="10" VaryByParam="None" VaryByCustom="minorversion" %>
似乎正在发生的事情是,您刚刚将字符串设置为查找,就这样。
当请求传入时,您将检查HTTP请求头--更改标头,这是您在页面中设置的--如果它存在,您可以做您想做的事情。
<%@ Application language="C#" %>
<script runat="server">
public override string GetVaryByCustomString(HttpContext context,
string arg)
{
// arg is your custom 'Vary' header.
if(arg == "minorversion")
{
return "Version=" +
context.Request.Browser.MinorVersion.ToString();
}
return base.GetVaryByCustomString(context, arg);
}
</script>我刚刚对这个基本示例进行了快速测试,并添加了一个标签,该标签将在页面加载时根据当前时间进行更新。我刷新了几次活页,直到10秒过去,时间才改变。所以这肯定管用。我认为关键是你设置了这个值,你就完成了,但是如果你愿意的话,你可以使用它。
..。再考虑一下,我认为您在页面中创建了标题,并从global.asax返回了值。在哪里??我认为它被发送到缓存系统,它决定了是否应该发送一个新的或缓存的页面。在上面的示例中,将检查并设置浏览器的次要版本,并且由于有一个缓存版本可用(在第一次加载之后),它会发送该版本,直到10秒结束。
VaryByCustom的文档位于一个“缓存页面的不同版本”的部分,所以这就是本文所要做的。如果出现具有不同浏览器的人,则检查浏览器版本--然后缓存系统检查该浏览器版本的页面版本是否可用。如果没有,创建一个新页面;如果是,发送缓存的版本。
https://stackoverflow.com/questions/32707370
复制相似问题