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

Posted

技术标签:

【中文标题】在 MVC 3 中禁用局部视图上的缓存【英文标题】:Disable caching on a partial view in MVC 3 【发布时间】:2012-02-05 21:36:52 【问题描述】:

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

@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。有没有办法缓存所有内容,除了有问题的部分视图?

【问题讨论】:

尼克,抱歉不得不在这里添加评论。无论如何,当我删除 Nostore 并将持续时间更改为 1 时它会起作用。现在唯一的问题是当用户登录时,他们会被带到主页但我必须明确刷新它才能使更改生效(以显示注销而不是登录)。 【参考方案1】:

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

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult HeaderView()

    return PartialView("_HeaderView");

【讨论】:

嗨尼克。感谢您的输入。但是我没有与局部视图关联的控制器操作(无论如何现在)。我使用 Html.Partial() 调用它。使用上述方法进行控制器操作是唯一的解决方法吗? 也许您可以添加一个共享控制器并添加一个返回 PartialView("_HeaderView"); 的 HeaderView 操作并用我上面的答案中的注释装饰。希望这会给你你需要的控制,而不是一个巨大的变化。让我知道这是否适合您或您需要更多说明。 谢谢尼克。我将实施这些更改,并告诉你进展如何。 嗨尼克。当我放入 outputcache 注释时,部分视图根本不显示。这就是我的 2 个控制器操作的样子 [OutputCache(Duration=86400, VaryByParam="")] public ActionResult Index() return View(); [OutputCache(Duration = 0, VaryByParam = "")] [ChildActionOnly] public ActionResult HeaderView() return PartialView("_HeaderView");从索引页面中,我调用 Html.Action 来显示部分视图 刚刚做了一些测试,似乎我也可以使用Location = OutputCacheLocation.None而不是Duration = 0,这更加清楚:)【参考方案2】:

您正在寻找的是所谓的甜甜圈缓存。这是一篇很棒的文章,解释了它是什么以及如何使它工作http://www.devtrends.co.uk/blog/donut-output-caching-in-asp.net-mvc-3

【讨论】:

我确实尝试过这个,但它并没有像预期的那样对我有用。我仍然遇到与在部分操作上使用 outputcache 属性相同的问题,即手动刷新主页。 我很乐意提供帮助,但看不到您拥有的代码会很困难 :) 不过它对我有用。当您测试时,请记住正确的浏览器设置(有时它们会覆盖服务器设置,并以防错误印象某些东西不起作用) 不,只是我玩得很慢。与流感一起工作显然不是一个好主意。但这现在有效。感谢您的帮助【参考方案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");

希望对您有所帮助!

【讨论】:

【参考方案4】:

这对我有用..

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

【讨论】:

+1 我尝试了所有其他解决方案,但效果不佳,这对我来说就像一个魅力......谢谢:) 注意:我不必使用 AuthenticationManager.Signout() .;【参考方案5】:

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

@if (Request.IsAuthenticated) @* 当我们通过身份验证时,不要再缓存了! *@ 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") 别的

【讨论】:

以上是关于在 MVC 3 中禁用局部视图上的缓存的主要内容,如果未能解决你的问题,请参考以下文章

MVC 3 防止部分视图缓存

使用 MVC5 C# 和 Razor 在局部视图中运行 javascript

如何在 MVC 4 中每 3 秒刷新一次局部视图?

MVC的局部视图

如何在 ASP.NET MVC 中使用 Ajax 调用刷新局部视图?

在 MVC 中从区域渲染局部视图