在 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 中禁用局部视图上的缓存的主要内容,如果未能解决你的问题,请参考以下文章
使用 MVC5 C# 和 Razor 在局部视图中运行 javascript