如何实现VaryByCustom缓存?

时间:2011-03-15 15:22:56

标签: c# asp.net asp.net-mvc caching varybyparam

我正在尝试实现根据主机缓存某些页面的功能。这是因为我可以拥有具有相同参数的页面的多个版本,并且请求方面唯一的区别是正在请求的主机。

因此,例如,这两个URL将请求相同的页面,但它们的样式不同:

http://www.a.com/something/specific

http://www.b.com/something/specific

我正在阅读这里列出的例子:

http://msdn.microsoft.com/en-us/library/5ecf4420%28v=VS.90%29.aspx

但这对我没有意义。

我已将此添加到我的global.asax:

public override string GetVaryByCustomString(HttpContext context, string arg)
{
    if (arg == "host")
    {
        return "host=" + context.Request.Url.Host;
    }

    return base.GetVaryByCustomString(context, arg);
}

并且示例声明“要以编程方式设置自定义字符串,请调用SetVaryByCustom方法并将其传递给要使用的自定义字符串”,代码类似于以下内容:

Response.Cache.SetVaryByCustom("host");

问题是我不知道该怎么做。我已将前一行添加到MvcApplication_EndRequest,因为它似乎有意义,但我不认为这是正确的,因为当我在GetVaryByCustomString中设置断点时,它们永远不会被击中。

有人可以告诉我,我在这里缺少什么吗?或者如果我需要以不同的方式做到这一点?

编辑: RE Darin的答案如下,我已经用以下方式解决了我的行为:

[CustomOutputCache(CacheProfile = "FundScreener")] // or similar depending on the action

其中CustomOutputCacheAttribute定义为:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class CustomOutputCacheAttribute: OutputCacheAttribute
{
    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        AddLabelFilesDependency(filterContext);
        base.OnResultExecuted(filterContext);
    }

    private static void AddLabelFilesDependency(ControllerContext filterContext)
    {
        IConfigurationManager configurationManager = ObjectFactory.TryGetInstance<IConfigurationManager>();
        if (configurationManager == null 
            || filterContext == null 
            || filterContext.RequestContext == null
            || filterContext.RequestContext.HttpContext == null
            || filterContext.RequestContext.HttpContext.Response == null
            )
        {
            return;
        }
        string[] files = Directory.GetFiles(configurationManager.LabelsDirectoryPath, "*.xml");
        foreach(var file in files)
        {
            filterContext.RequestContext.HttpContext.Response.AddFileDependency(file);
        }
    }
}

其中配置文件定义为:

<add name="FundScreener"
     location="Server"
     enabled="true"
     varyByParam="*"
     duration="1200"
     sqlDependency="mmftms:offline.ScreenerData"/>

我需要更改吗?

4 个答案:

答案 0 :(得分:7)

您无需在MVC中调用SetVaryByCustom。您可以使用OutputCache属性。查看following blog post

答案 1 :(得分:4)

如果要为不同的主机使用不同的缓存,可以使用:

VaryByHeader = “宿主”

因为,这会使它在请求中使用标题“host”的值来改变缓存。您可以在控制器/操作的OutputCache指令中添加它,也可以在web.config中全局指定它。

如果您使用主机绑定,

将始终存在主机标头,这似乎适合您。

答案 2 :(得分:3)

每个请求都由缓存层调用

GetVaryByCustomString(...),您有机会检查请求和传入的参数,以决定如何“分类”此请求。因此,如果将VaryByCustom属性/属性设置为“host”,则可以在GetVaryByCustomString函数内编写返回主机的代码(如上例所示)。如果缓存层发现它已经使用您返回的值缓存了参数“host”,那么它将返回缓存的响应,否则它将执行请求并将其添加到缓存中。

答案 3 :(得分:0)

根据您的修改,将VaryByCustom="host"添加到您的FundScreener输出缓存配置文件。