C# 缓存控制:无存储,必须重新验证未发送到IIS7和x2B中的客户端浏览器;ASP.NETMVC

C# 缓存控制:无存储,必须重新验证未发送到IIS7和x2B中的客户端浏览器;ASP.NETMVC,c#,asp.net-mvc,iis-7,http-headers,cache-control,C#,Asp.net Mvc,Iis 7,Http Headers,Cache Control,我试图确保某个页面从未被缓存,并且在用户单击“后退”按钮时从未显示该页面: 但是,在IIS7/ASP.NET MVC中,当我发送这些头时,客户端会看到这些响应头: Cache-control: private, s-maxage=0 // that's not what I set them to Pragma: no-cache Expires: 0 缓存控制头怎么了?IIS7或ASP.NET本机是否覆盖了它?我已经检查了我的解决方案,没有覆盖此标题的代码 当我添加Response.Head

我试图确保某个页面从未被缓存,并且在用户单击“后退”按钮时从未显示该页面:

但是,在IIS7/ASP.NET MVC中,当我发送这些头时,客户端会看到这些响应头:

Cache-control: private, s-maxage=0 // that's not what I set them to
Pragma: no-cache
Expires: 0
缓存控制头怎么了?IIS7或ASP.NET本机是否覆盖了它?我已经检查了我的解决方案,没有覆盖此标题的代码

当我添加
Response.Headers.Remove(“缓存控制”)时首先,它没有区别:

Response.Headers.Remove("Cache-Control");
Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
Response.AppendHeader("Pragma", "no-cache");
Response.AppendHeader("Expires", "0");
添加
[OutputCache]
属性时:

[OutputCache(Location = OutputCacheLocation.None)]
public ActionResult DoSomething()
{
   Response.Headers.Remove("Cache-Control");
   Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
   Response.AppendHeader("Pragma", "no-cache");
   Response.AppendHeader("Expires", "0");

   var model = DoSomething();
   return View(model);
}
然后,客户端响应头更改为:

Cache-control: no-cache
Pragma: no-cache
Expires: 0
更接近,但仍然不是我想要发送的标题。这些标题在哪里被覆盖,我如何停止


编辑:我已经检查过,不正确的标题被发送到Chrome、FF、IE和Safari,因此这看起来是服务器问题,而不是浏览器相关问题。

通过反复试验,我发现在ASP.NET MVC中为IIS7正确设置标题的一种方法是:

Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.AppendCacheExtension("no-store, must-revalidate");
Response.AppendHeader("Pragma", "no-cache");
Response.AppendHeader("Expires", "0");
第一行将
缓存控制设置为
无缓存
,第二行添加其他属性
无存储,必须重新验证

这可能不是唯一的方法,但如果更直接的
响应,则提供了另一种方法。AppendHeader(“缓存控制”,“无缓存,无存储,必须重新验证”)失败

其他相关的IIS7缓存控制问题可通过以下方式解决:


我想给您的答案添加一些内容:
如果将缓存控件设置为比现有限制更严格的值,则可以。(即:当缓存为私有时,不设置缓存)

但是,如果要将限制性设置为小于现有限制性值的(即:当没有缓存时设置为private),则以下代码将不起作用:

Response.Cache.SetCacheability(HttpCacheability.Private);
因为SetCacheablitiy方法具有以下代码,并且仅在限制性更强时才设置缓存标志:

if (s_cacheabilityValues[(int)cacheability] < s_cacheabilityValues[(int)_cacheability]) {
    Dirtied();
   _cacheability = cacheability;
}
动作过滤器中提供了HttpResponseMessage的一个实例。您可以编写操作筛选器来设置缓存头值,如下所示:

public class ClientSideCacheAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        var response = actionExecutedContext.ActionContext.Response;
        response.Headers.CacheControl = new System.Net.Http.Headers.CacheControlHeaderValue
        {
            MaxAge = TimeSpan.FromSeconds(9999),
            Private = true,
        };
    }
}

如果您在MVC应用程序中全局需要这些头文件。添加这个类

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class CustomHeaders : System.Web.Mvc.ActionFilterAttribute
{
    [OutputCache(Location = System.Web.UI.OutputCacheLocation.None)]
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        context.RequestContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        context.RequestContext.HttpContext.Response.Cache.AppendCacheExtension("no-store, must-revalidate");
        context.RequestContext.HttpContext.Response.AppendHeader("Pragma", "no-cache");
        context.RequestContext.HttpContext.Response.AppendHeader("Expires", "0");

        base.OnActionExecuted(context);
    }
}
对于全局使用,将其添加到FilterConfig

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new CustomHeaders());
    }
}
或者仅在特定控制器上使用这些标头

[Authorize]
[CustomHeaders]
public class HomeController : Controller
{
    [AllowAnonymous]
    public ActionResult Index()

旁注:您可以对其他标题使用IIS和web.config。例如,在静态内容上,比如bundle(jquery、bootstrap)。查找CustomHeader、staticcontent等部分。

我无法在新的MVC3或MVC4应用程序中复制此问题。您可以检查IIS(HTTP响应头和输出缓存)中的设置吗?在IIS7中,我没有为输出缓存(服务器级或站点级)配置任何设置,只配置了一个响应头(X-Powered-By)我喜欢MVC和IIS只是决定在这里和那里随机中断自己的API并引入静默失败。IIS 8也适用,答案也是:这是唯一对我有效的方法,即使在Windows 10上的IIS 10上也是如此。非常感谢。设置“no cache”标题的其他答案没有导致输出“no store”值,这导致浏览器缓存某些内容,并在用户使用后退/前进浏览器按钮导航时加载。我强制IIS将响应标题设置为“private,no store,max age=0”通过Global.asax.cs和控制器操作过滤器,但IIS显示为“public,no store,max age=0”。最后,这个方法在IIS10中也适用于我。帮了大忙!ActionFilterAttribute OnActionRequested似乎需要ActionExecutedContext,而不是HttpActionExecutedContext。ActionExecutedContext不允许访问ActionContex(仅HttpContext.Response.Header,它没有CacheControl)有什么想法吗?(注意MVC不是WebAPI)
public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new CustomHeaders());
    }
}
[Authorize]
[CustomHeaders]
public class HomeController : Controller
{
    [AllowAnonymous]
    public ActionResult Index()