在MVC 3中禁用部分视图上的缓存

时间:2012-01-09 10:24:11

标签: c# asp.net-mvc-3 caching partial-views outputcache

我有一个问题,部分视图在不应该被缓存时被缓存。此部分视图用于显示页面上的登录/注销。它使用下面的简单代码来确定要显示的链接

@if(Request.IsAuthenticated) {    
    <a href="@Url.Action("LogOff", "Account", new { area = "" })">Log Off</a> 
}
else {
    <a href="@Url.Action("LogOn", "Account", new { area = "" })">Log On</a>
}

使用

从我的MVC3应用程序中的所有页面调用此部分视图
@Html.Partial("_HeaderView")  

在我的大多数控制器中,我都定义了输出缓存,因此我可以利用缓存内容。

[OutputCache(Duration = 86400, VaryByParam = "*")]

现在我的问题是,当我不想要部分视图时,整个页面都被缓存了。这导致了错误的行为,即使用户没有登录,它有时会显示LogOff等。有没有办法缓存所有内容,除了有问题的部分视图?

5 个答案:

答案 0 :(得分:18)

您可以通过使用以下内容装饰显示_HeaderView部分的控制器来禁用缓存:

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult HeaderView()
{
    return PartialView("_HeaderView");
}

答案 1 :(得分:9)

您正在寻找的是Donut Caching。这是一篇很棒的文章,解释它是什么以及如何使其发挥作用http://www.devtrends.co.uk/blog/donut-output-caching-in-asp.net-mvc-3

答案 2 :(得分:3)

我们应该在Web.config文件中设置缓存配置文件,而不是在页面中单独设置缓存值以避免冗余代码。我们可以使用OutputCache属性的CacheProfile属性来引用配置文件。除非页面/方法覆盖这些设置,否则此缓存配置文件将应用于所有页面。

<system.web>
  <caching>
    <outputCacheSettings>
      <outputCacheProfiles>
        <add name="CacheProfile" duration="60" varyByParam="*" />
      </outputCacheProfiles>
    </outputCacheSettings>
  </caching>
</system.web>

如果要从返回部分视图[_HeaderView]的操作中禁用缓存,可以通过修改特定的操作方法来覆盖配置缓存设置,如下所示:

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult RenderPartialView()
{
    return PartialView("_HeaderView");
}

希望这会对你有帮助!

答案 3 :(得分:1)

这对我有用..

 public ActionResult LogOff()
 {
     AuthenticationManager.SignOut();  
     var url = Url.Action("Index", "Web"); 
     HttpResponse.RemoveOutputCacheItem(url);           
     return RedirectToAction("Index", "Web");
 }

答案 4 :(得分:1)

在回到MVC之后花了一点时间才想出这个。只需将Cache设置直接放在Partial Header View中即可。与显示用户名时一样。无需全局或服务器端代码。唯一的问题是一旦页面被缓存,登录后就不会立即刷新。但是,我们会在初次浏览产品时保持速度。在我们的案例中,我们可以权衡


    @if ( Request.IsAuthenticated)
    {
            @* when we are authenticated, don't cache any more! *@
    HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    HttpContext.Current.Response.Cache.SetNoStore();
    HttpContext.Current.Response.Cache.SetNoServerCaching();
            @*@Html.Raw(DateTime.Now.ToString())*@
    @Html.ActionLink("Welcome " + ( String.IsNullOrEmpty(((System.Security.Claims.ClaimsIdentity)User.Identity).FindFirstValue("UserName")) ? User.Identity.Name : ((System.Security.Claims.ClaimsIdentity)User.Identity).FindFirstValue("UserName")), "Index", "Manage", routeValues: new { Area = "Store" }, htmlAttributes: new { title = "Manage"})
    }
    else
    {
    }