为什么不能在Web API2中设置Cache-Control标头

问题描述 投票:3回答:1

要重现该问题:使用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标头仍然只是其默认值:

Cache-Control is set to default value instead of what was specified in Web Api controller method

如果将上面的代码更改为

HttpContext.Current.Response.AppendHeader("foobar", "no-cache, no-store, must-validate");

它实际上设置了标题:

It does add the foobar header

我在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一起使用?

asp.net-mvc asp.net-web-api asp.net-web-api2 cache-control
1个回答
0
投票

您的CacheControlAttribute在我看来不错,不确定为什么它不起作用。我一直在寻找较少的自定义解决方案,而真正帮助我的是通过RegisterGlobalFiltersApp_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
        });
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.