15

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

因此,例如,这两个 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

4 回答 4

6

您不需要调用SetVaryByCustomMVC。您可以使用该OutputCache属性。查看以下博客文章

于 2011-03-15T15:27:15.770 回答
4

如果你想为不同的主机设置不同的缓存,你可以使用:

VaryByHeader="主机"

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

如果您使用主机绑定,主机标头将始终存在,这对您来说似乎就是这种情况。

于 2011-03-15T15:39:14.323 回答
3

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

于 2011-03-15T15:27:54.400 回答
0

Based on your edit, add VaryByCustom="host" to your FundScreener output cache profile.

于 2011-03-15T15:33:56.557 回答