2015-07-23 19 views
17

Ich versuche, Cache-Header in der ASP.NET MVC-Web-API festzulegen, aber die Antwort von IIS schlägt vor, dass die CacheControl-Werte ignoriert werden.Cache-Control-Header werden nicht als Antwort gesendet, obwohl sie im Antwortobjekt konfiguriert sind

Meine ursprüngliche Annahme war, dass ich das EnableCorsAttribute in System.Web.Http.Cors verwendete, das in diesem Anwendungsfall erforderlich ist. Aber auch ohne dieses Attribut ist der Cache-Control-Header der Antwort immer noch 'privat'.

Gibt es etwas, was ich hier falsch mache?

// 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) 
     { 
      //... 
     } 
    } 

Antwort

HTTP/1.1 200 OK 
Cache-Control: private 
Content-Type: application/json; charset=utf-8 
Date: Thu, 23 Jul 2015 10:53:17 GMT 
Server: Microsoft-IIS/7.5 
Set-Cookie: ASP.NET_SessionId=knjh4pncbrhad30kjykvwxyz; path=/; HttpOnly 
X-AspNet-Version: 4.0.30319 
X-Powered-By: ASP.NET 
Content-Length: 2367 
Connection: keep-alive 
+0

gibt es einen Grund, warum Sie versuchen, Ihre eigenen hier über etwas zu rollen wie https://github.com/filipw/AspNetWebApi-AusgabeCache? – BMac

+0

Ja, ich möchte, dass der Aufrufer die Cache-Zeit angeben kann. Der Wert wird aus der Abfragezeichenfolge gelesen und in die Headerwerte der Cache-Steuerelemente eingegeben. – gb2d

+0

hmm, wenn jemand die Antwort auf diese eine wissen wird, wird es https://twitter.com/filip_woj (Ersteller des obigen nugget-Pakets) sein, es lohnt sich, ihn auf Twitter zu erreichen. – BMac

Antwort

4

Die Antwort, das einige Wochen später abgeholt zu haben:

Cache-Control-Header erscheint 'privat' gesetzt zu werden, wenn Debug baut läuft. Das Problem verschwindet, wenn ich mit einem Release Build laufe.

6

-Code unten Sets "Cache-Control: public, max-age = 15" Vanille WebAPI Anwendung korrekt in (System.Web.Http 4.0.0.0). Also ... es ist wahrscheinlich nicht der WebApi selbst, der das Problem verursacht.

Möglicherweise haben Sie etwas Magie in Ihrem Projekt, das die Cache-Einstellungen ändert (denken Sie an globale Aktionsfilter oder Ähnliches). Oder vielleicht gehen Sie durch Proxy, der HTTP-Header neu schreibt.

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" 
1

Um eine andere Sache hinzufügen, die diese verursachen können:

Sie durch eine Owin Pipeline laufen.

In diesem Fall müssen Sie die Header in einer Owin Middleware wie folgt definiert einzustellen:

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); 
    } 
} 
+0

Ran in ein Problem mit IE11 aggressiv Caching Ajax Antworten und diese Middleware hat den Trick. Vielen Dank! – seangwright