ASP.NET MVC如何禁用自动缓存选项?


71

如何从ASP.NET MVC应用程序禁用自动浏览器缓存?

因为我在缓存时遇到问题,因为它缓存了所有链接。但是有时它会自动重定向到DEFAULT INDEX PAGE,并存储它的缓存,然后每次我单击该链接时,它都会将我重定向到DEFAULT INDEX PAGE。

因此,有人知道如何从ASP.NET MVC 4中手动禁用缓存选项吗?

Answers:


135

您可以使用OutputCacheAttribute来控制服务器和/或浏览器的特定操作或控制器中所有操作的缓存。

禁用控制器中的所有操作

[OutputCacheAttribute(VaryByParam = "*", Duration = 0, NoStore = true)] // will be applied to all actions in MyController, unless those actions override with their own decoration
public class MyController : Controller
{
  // ... 
}

禁用特定操作:

public class MyController : Controller
{
    [OutputCacheAttribute(VaryByParam = "*", Duration = 0, NoStore = true)] // will disable caching for Index only
    public ActionResult Index()
    {
       return View();
    }
} 

如果要对所有控制器中的所有操作应用默认的缓存策略,则可以通过编辑和查找方法来添加全局操作过滤器。在默认的MVC应用程序项目模板中添加了此方法。global.asax.csRegisterGlobalFilters

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new OutputCacheAttribute
                    {
                        VaryByParam = "*",
                        Duration = 0,
                        NoStore = true,
                    });
    // the rest of your global filters here
}

这将使它对OutputCacheAttribute所有操作应用上面指定的内容,这将禁用服务器和浏览器缓存。您仍然可以通过添加OutputCacheAttribute到特定的操作和控制器来覆盖此无缓存。


谢谢,让我检查它的
伟大之处,

嗯,是的,我想您是说您想在应用程序的每个控制器上使用它。我将更新我的答案以涵盖这两个方面。
moribvndvs 2012年

2
我以为它可以用,但是后来我开始得到Duration在控制器中必须为正数。
Loganj99

2
不能用ChildActions使用
T-moty

1
对于在其代码中寻找该RegisterGlobalFilters方法的任何人,有时它都存在于中,App_Start\FilterConfig.cs而不是中Global.asax.cs
Tawab Wakil

28

HackedByChinese遗漏了重点。他将服务器缓存与客户端缓存混为一谈。OutputCacheAttribute控制服务器缓存(IIS http.sys缓存),而不控制浏览器(客户端)的缓存。

我给你我的代码库的一小部分。明智地使用它。

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public sealed class NoCacheAttribute : FilterAttribute, IResultFilter
{
    public void OnResultExecuting(ResultExecutingContext filterContext)
    {
    }

    public void OnResultExecuted(ResultExecutedContext filterContext)
    {
        var cache = filterContext.HttpContext.Response.Cache;
        cache.SetCacheability(HttpCacheability.NoCache);
        cache.SetRevalidation(HttpCacheRevalidation.ProxyCaches);
        cache.SetExpires(DateTime.Now.AddYears(-5));
        cache.AppendCacheExtension("private");
        cache.AppendCacheExtension("no-cache=Set-Cookie");
        cache.SetProxyMaxAge(TimeSpan.Zero);
    }
}

用法:

/// will be applied to all actions in MyController
[NoCache]
public class MyController : Controller
{
    // ... 
}

明智地使用它,因为它实际上会禁用所有客户端缓存。唯一未禁用的缓存是“后退按钮”浏览器缓存。但是似乎真的没有办法解决它。也许只能使用javascript进行检测并强制页面或页面区域刷新。


此反缓存功能可以在商业网站上完美运行3年以上。使用提琴手检查http响应中的缓存头。
Softlion 2012年

12
我明白这一点。使用OutputCacheAttribute并设置NoStore = true时,将禁止浏览器缓存(响应头将类似于Cache-Control: public, no-store, max-age=0 Expires: Mon, 22 Oct 2012 20:19:26 GMT Last-Modified: Mon, 22 Oct 2012 20:19:26 GMT)。因此,它将防止服务器和浏览器缓存。我知道奇怪的是public,除了不存储外,它还会设置,但最终的效果是不存储和立即到期。
moribvndvs 2012年

您是说它不会缓存,因为会立即到期?
拉吉·塔玛库瓦拉

这对我也不起作用。浏览器缓存仍在发生。
欧比

1
无论有没有SetNoStore(),这对我也有用。内置的@HackedByChinese过滤器结果在Cache-Control: public, no-cache="Set-Cookie", no-store, max-age=0Expires+Vary设置中。该解决方案将导致Cache-Control: no-cache, proxy-revalidate, private, no-cache=Set-CookieExpires=-1Pragma=no-cache。由于它们都可以很好地控制浏览器缓存,因此不确定是什么问题。
安德鲁·贝克

13

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

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

而且,如果您想从特定操作或控制器中禁用缓存,则可以通过装饰该特定操作方法来覆盖配置缓存设置,如下所示:

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

希望这很清楚,对您有用。


感谢您添加web.config
Priyankara

9

如果要防止浏览器缓存,则可以从ShareFunction使用此代码

public override void OnResultExecuting(ResultExecutingContext filterContext)
{
        filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
        filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        filterContext.HttpContext.Response.Cache.SetNoStore();

        base.OnResultExecuting(filterContext);
}

必须保护访问修饰符
达斯·维德勋爵(Lord Darth Vader)'18年

5

对于页面解决方案,请在布局页面中进行以下设置:

<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">

2
您可以添加无商店以使其在Chrome中运行。<meta http-equiv="Cache-Control" content="non-cache, no-store, must-revalidate">
Kannan_PK

@Kannan_PK谢谢!我帮了我 我使用了meta上面列出的所有标签,但没有任何效果。您的评论应包含在答案中。
约瑟夫·卡兹曼

0

为了使所有人都能看到我的答案,我将评论移动到该问题的答案。

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">

这将在所有浏览器(IE,Firefox和Chrome)中都可以使用。很高兴听到我的回答为您工作@Joseph Katzman

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.