C# 缓存控制头未在响应中发送,尽管已在响应对象上配置

C# 缓存控制头未在响应中发送,尽管已在响应对象上配置,c#,asp.net-web-api,http-caching,C#,Asp.net Web Api,Http Caching,我试图在ASP.NET MVC Web API中设置缓存头,但IIS的响应表明缓存控制值集被忽略 我最初的假设是在System.Web.Http.Cors中使用EnableCorsAttribute,这在本用例中是必要的。但是,即使没有该属性,响应缓存控制头仍然是“私有”的 我有什么地方做错了吗 // GET api/<version>/content // [EnableCors(origins: "*", headers: "*", methods: "*")]

我试图在ASP.NET MVC Web API中设置缓存头,但IIS的响应表明缓存控制值集被忽略

我最初的假设是在System.Web.Http.Cors中使用EnableCorsAttribute,这在本用例中是必要的。但是,即使没有该属性,响应缓存控制头仍然是“私有”的

我有什么地方做错了吗

    // GET api/<version>/content
    // [EnableCors(origins: "*", headers: "*", methods: "*")]
    public HttpResponseMessage Get(HttpRequestMessage request)
    {
        int cacheMaxAgeSeconds;

        string cacheMaxAgeString = request.GetQueryString("cache-max-age") ?? request.GetQueryString("cache-max-age-seconds");

        string rawUri = request.RequestUri.ToString();

        try
        {
            cacheMaxAgeSeconds = cacheMaxAgeString == null ? Config.ApiCacheControlMaxSeconds : int.Parse(cacheMaxAgeString);
        }
        catch (Exception ex)
        {
            cacheMaxAgeSeconds = Config.ApiCacheControlMaxSeconds;

            //... 
        }

        try
        {
            //...

            var response = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StringContent("...", Encoding.UTF8, "application/json")
            };

            response.Headers.CacheControl = new CacheControlHeaderValue
            {
                Public = true,
                MaxAge = TimeSpan.FromSeconds(cacheMaxAgeSeconds)
            };

            return response;
        }
        catch (Exception apiEx)
        {
            //...
        }
    }
下面的代码在vanilla WebApi应用程序(System.Web.Http 4.0.0.0)中正确设置“缓存控制:公共,最大年龄=15”。所以问题可能不是WebApi本身造成的

您的项目中可能有一些改变缓存设置的魔法(想想全局操作过滤器或类似的东西)。或者,您可能正在使用重写HTTP头的代理

    public HttpResponseMessage Get()
    {
        var content = new JavaScriptSerializer().Serialize(new { foo = "bar" });

        var response = new HttpResponseMessage(HttpStatusCode.OK)
        {
            Content = new StringContent(content, Encoding.UTF8, "application/json")
        };

        response.Headers.CacheControl = new CacheControlHeaderValue
        {
            Public = true,
            MaxAge = TimeSpan.FromSeconds(15)
        };

        return response;
    }

// returns in the response: "Cache-Control: public, max-age=15"

几周后,我发现了答案:


运行debug生成时,缓存控制标头似乎设置为“private”。当我使用发布版本运行时,问题就消失了。

添加另一个可能导致此问题的因素:

您通过Owin管道运行

在这种情况下,您需要在定义为以下内容的Owin中间件中设置头:

class MiddleWare : OwinMiddleware
{
    public MiddleWare(OwinMiddleware next)
    : base(next)
    {
    }
    public override async Task Invoke(IOwinContext context)
    {
        context.Response.Headers["Cache-Control"] = "no-cache, no-store, must-revalidate";
        context.Response.Headers["Pragma"] = "no-cache";
        context.Response.Headers["Expires"] = "0";
        await Next.Invoke(context);
    }
}

您是否有理由尝试在这里滚动自己的缓存周期?是的,我实际上希望调用方能够指定缓存周期。该值从查询字符串中读取并输入到缓存控制头values.hmm中,如果有人知道这个值的答案,那么(上述nuget包的创建者)可能值得在twitter上与他联系。打得好。在我这么做之前,我会先看看这个项目,看看是否有什么不同的做法。将在我有机会检查时更新。在IE11积极缓存ajax响应时遇到问题,该中间件实现了这一点。谢谢
class MiddleWare : OwinMiddleware
{
    public MiddleWare(OwinMiddleware next)
    : base(next)
    {
    }
    public override async Task Invoke(IOwinContext context)
    {
        context.Response.Headers["Cache-Control"] = "no-cache, no-store, must-revalidate";
        context.Response.Headers["Pragma"] = "no-cache";
        context.Response.Headers["Expires"] = "0";
        await Next.Invoke(context);
    }
}