首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >输出缓存,VaryByParam/VaryByCustom

输出缓存,VaryByParam/VaryByCustom
EN

Stack Overflow用户
提问于 2015-09-22 02:16:34
回答 2查看 2.6K关注 0票数 1

好吧,似乎没有结束的文章,歌颂输出缓存和它将加快你的网站的多少。我现在已经阅读了数百篇关于这个主题的文章和问题,但我似乎仍然无法让它发挥作用。(我认为输出缓存可能会窃取我的灵魂)

我的要求很简单,我想根据参数缓存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”。这是我的密码:

代码语言:javascript
复制
public override string GetVaryByCustomString(HttpContext context, string arg)
{
    if (arg != null)
    {
        return arg;
    }

    return base.GetVaryByCustomString(context, arg);
}

这是第一次在页面上工作,设置了创建回发的下拉列表的值,但之后就没有了。因此,"OnselectedItemChanged“触发了一次,并根据所选内容创建了一组新的缓存条目,但从未再次触发。我试图修改几乎所有的缓存参数,以使其正常工作,但无论我尝试了哪些系列设置(以声明方式设置缓存、在代码中设置缓存、尝试各种VaryByParams组合、添加位置等),我都没有成功。

在尝试了两天后,我决定采取一种不同的方法。我回到了一种更传统/被接受的方法。我在web.config中创建了3个缓存配置文件:

代码语言:javascript
复制
<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,它看起来像:

代码语言:javascript
复制
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这样对这类事情有处理能力的人会同情我,把我推到一个能让我找到解决方案的方向。

更新:我已经和微软打开了一个箱子。

EN

回答 2

Stack Overflow用户

发布于 2015-09-22 08:28:33

你设置VaryByParam了吗?我现在忘记了细节,但我记得在发现这是强制性的之前,我被困住了。(我想在每一种情况下。(?))我认为也需要持续时间。(我指的是.aspx页面中的指令。)

票数 0
EN

Stack Overflow用户

发布于 2015-09-22 21:52:21

重新阅读您的问题时,我看到了这个问题:“我找不到任何允许页面定义字符串的工作示例。”我重读了一些文章,我很确定这是错误的方法。

我还没有对所有这些进行测试,但对于ex,如果您以标准示例为例:

<%@ OutputCache Duration="10" VaryByParam="None" VaryByCustom="minorversion" %>

似乎正在发生的事情是,您刚刚将字符串设置为查找,就这样。

当请求传入时,您将检查HTTP请求头--更改标头,这是您在页面中设置的--如果它存在,您可以做您想做的事情。

代码语言:javascript
复制
<%@ 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的文档位于一个“缓存页面的不同版本”的部分,所以这就是本文所要做的。如果出现具有不同浏览器的人,则检查浏览器版本--然后缓存系统检查该浏览器版本的页面版本是否可用。如果没有,创建一个新页面;如果是,发送缓存的版本。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32707370

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档