要重现该问题:使用Visual Studio 2015,使用MVC和Web API创建一个Asp.Net框架Web应用。创建一个Example
api控制器,如下所示:
using System.Web;
using System.Web.Http;
public class ExampleController : ApiController
{
public IHttpActionResult Get()
{
HttpContext.Current.Response.AppendHeader("Cache-Control", "no-cache, no-store, must-validate");
return Ok("foo");
}
}
就是这样。运行应用程序并检查Chrome中的开发工具,并且Cache-Control标头仍然只是其默认值:
如果将上面的代码更改为
HttpContext.Current.Response.AppendHeader("foobar", "no-cache, no-store, must-validate");
它实际上设置了标题:
我在Google上找不到任何有关此的信息。我已经尝试过使用动作过滤器属性方法来设置标题,这似乎是完全相同的问题。
如何覆盖Asp.Net Web API中的默认Cache-Control标头?
Edit:我不确定上面有什么问题,但是如果替换为动作过滤器,则可以使它工作,除非它是同步控制器方法:
using System;
using System.Web.Http.Filters;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
public class CacheControlAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext context)
{
if (context.Response != null)
{
context.Response.Headers.CacheControl = new CacheControlHeaderValue()
{
NoStore = true,
NoCache = true,
MustRevalidate = true,
MaxAge = new TimeSpan(0)
};
}
base.OnActionExecuted(context);
}
public override async Task OnActionExecutedAsync(HttpActionExecutedContext context, CancellationToken cancellationToken)
{
if (context.Response != null)
{
context.Response.Headers.CacheControl = new CacheControlHeaderValue()
{
NoStore = true,
NoCache = true,
MustRevalidate = true,
MaxAge = new TimeSpan(0)
};
}
await base.OnActionExecutedAsync(context, cancellationToken);
}
}
适用于同步控制器动作,但不适用于像这样的async
[CacheControl]
public async Task<IHttpActionResult> Get()
{
using(Model1 db=new Model1())
{
var result =await db.MyEntities.Where(n => n.Name == "foo").SingleOrDefaultAsync();
return Ok(result);
}
}
如何使它与async
一起使用?
您的CacheControlAttribute
在我看来不错,不确定为什么它不起作用。我一直在寻找较少的自定义解决方案,而真正帮助我的是通过RegisterGlobalFilters
的App_Start/FilterConfig.cs
强制执行no cache指令:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
// ...
filters.Add(new OutputCacheAttribute
{
NoStore = true,
Duration = 0,
VaryByParam = "*",
Location = System.Web.UI.OutputCacheLocation.None
});
}
}