问题 在子操作上使用OutputCacheAttribute的VaryByHeader


使用ASP.NET MVC 3中的[OutputCacheAttribute],您可以非常灵活地输出缓存。利用'VaryByHeader'属性按主机名进行缓存是很有用的。例如:

[OutputCache(Duration = 60, VaryByHeader = "host")]
public ActionResult Foo()
{
    return this.View();
}

但是,对于子操作,您无法应用'VaryByHeader'。该框架抛出以下异常:

子操作的OutputCacheAttribute仅支持Duration,   VaryByCustom和VaryByParam值。请不要设置CacheProfile,   Location,NoStore,SqlDependency,VaryByContentEncoding或   子动作的VaryByHeader值。

我的问题是,为什么?

我们为什么不能在子操作中使用VaryByHeader,因为它会提供冲突的方差,因为父操作可能指定了不同的VaryByHeader值?

如果我想根据主机名不同地缓存子操作,这意味着什么,我将如何处理它?


4062
2018-02-16 22:47


起源

只是好奇,做孩子的行为导致另一个HTTP得到?也许这个想法的设计者认为,既然没有 第二 回发后,不需要通过不同的http标头进行缓存。 - Davin Tryon
不,子操作只是同一请求中的抽象。 - Ben Lakey


答案:


VaryByHeader 影响实际的HTTP响应标头;所以你可能是正确的,MVC团队阻止了这一点,以防止与父行动发生冲突。

要根据主机名进行缓存,您无法使用 VaryByCustom?像(免责声明:根本没试过):

[OutputCache(Duration = 60, VaryByCustom = "host")]
public ActionResult Foo()
{
    return View();
}

然后是(在你的Global.asax.cs中)

public override string GetVaryByCustomString(HttpContext context, string arg)
{
    if (arg == "host")
    {
        return context.Request.Headers["host"];
    }

    // whatever you have already, or just String.Empty
    return String.Empty;
}

13
2018-02-21 23:26



通过使用VaryByHeader,已经可以基于主机名进行缓存。例如,在2主机名方案中,子操作将缓存两次,一次用于主机A,一次用于主机B.您不需要使用VaryByCustom。 (虽然你的方法确实也可以工作,并且可能与VaryByHeader的实现非常相似)。 - Ben Lakey
当然,但既然你不能使用 VaryByHeader 在你的ChildAction ...... :) - bhamlin