我在MVC网络应用程序中有相当奇怪的行为。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class NoCacheFilterAttribute : ActionFilterAttribute
{
ctx.Response.AddHeader("Cache-Control", "no-cache);
}
我将此过滤器类添加到GlobalFilterCollection中,以便它在每个操作上运行。
我试图在我的一个家庭控制器操作方法中有选择地覆盖此标头。 Response.Headers.Remove( “缓存控制”); Response.AddHeader(“Cache-Control”,“private,must-revalidate,proxy-revalidate”);
问题不在于这些代码正在设置正确的值。当我检查响应头中的值时,Cache-Control被设置为“private,s-maxage = 0”。我扫描了所有代码,看看我是否明确地在任何地方这样做,但我不认为自己这样做。奇怪的是如果我打电话 Response.Cache.SetNoStore();或Response.Cache的任何方法。然后Cache-Control的响应值发生变化。我不确定为什么Response.AddHeader或AppendHeader不起作用?
答案 0 :(得分:1)
" Cache-Control" ASP.NET中的响应标头是特殊的,不应该显式设置。相反,请使用已经找到Response.Cache
对象的第一类API。
答案 1 :(得分:0)
你可以在执行ctx.Response.AddHeader("Cache-Control", "no-cache)
之前添加一些条件逻辑来解决它吗?
基本上,您可以创建另一个名为[ApplyCache]的过滤器,以应用于您不想设置no-cache的操作方法,而在NoCacheFilterAttribute中,您可以执行此操作,
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class NoCacheFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext ctx)
{
if (!ctx.ControllerContext.ControllerDescriptor.GetFilters().Contains(new ApplyCache()) && !ctx.ActionDescriptor.GetFilters().Contains(new ApplyCache())
{
ctx.Response.Headers.Add("Cache-Control", "no-cache");
}
}
}
对于MVC,这可能是,
public class ApplyCache: System.Web.Mvc.ActionFilterAttribute
{
}
public class NoCache: System.Web.Mvc.ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext actionExecutedContext)
{
if (!actionExecutedContext.ActionDescriptor.IsDefined(typeof(ApplyCache), true))
{
actionExecutedContext.RequestContext.HttpContext.Response.AddHeader("Cache-Control", "no-cache");
}
}
}
并且您希望将两个过滤器添加到全局集合中。
public static void RegisterMvcFilters(GlobalFilterCollection filters)
{
filters.Add(new ApplyCache());
filters.Add(new NoCache());
}
答案 2 :(得分:0)
行。这就是我发现的。如果您在代码中使用(任何其他NuGet库可能正在设置标题),则代码中的任何时间都可以使用
Response.Cache.SetNoStore(); //or any other .SetXXX; methods
,标题被写入缓冲区,如果你发出以下代码(在ActionFilterAttribute中使用它的一些例子):
HttpContext ctx = HttpContext.Current;
ctx.Response.AppendHeader("Cache-Control", "private, must-revalidate, proxy-revalidate ");
ctx.Response.AddHeader("Cache-Control", "private, must-revalidate, proxy-revalidate ");
ctx.Response.Headers.Set("Cache-Control", "no-cache, no-store, must-revalidate, proxy-revalidate");
修改标题,不写入标题值。重置标头的唯一方法是发出以下代码行,然后发出上面的代码或调用Response.Cache.SetXXX方法。
ctx.Response.ClearHeaders();
Response.Cache没有提供重置使用.SetXXXX方法设置的响应标头值的机制。如果从未调用Response.Cache.SetXXX方法,则调用Response.AppendHeader,AddHeader或Headers.Set将无需调用Response.ClearHeaders();