2015-07-23 20 views
17

Sto provando a impostare le intestazioni della cache nell'API Web MVC di ASP.NET, ma la risposta di IIS suggerisce che i valori CacheControl vengono ignorati.Le intestazioni di Cache-Control non vengono inviate in risposta nonostante siano configurate sull'oggetto risposta

Il mio presupposto originale era che stavo usando EnableCorsAttribute in System.Web.Http.Cors, che è necessario in questo caso d'uso. Tuttavia, anche senza quell'attributo, l'intestazione di Cache-Control di risposta è ancora "privata".

C'è qualcosa che sto facendo male qui?

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

risposta

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

c'è un motivo si sta cercando di rotolare il proprio qui sopra qualcosa come https://github.com/filipw/AspNetWebApi-OutputCache? – BMac

+0

Sì, desidero effettivamente che il chiamante sia in grado di specificare il periodo di cache. Il valore viene letto dalla stringa di query e viene inserito nei valori dell'intestazione del controllo della cache. – gb2d

+0

hmm, se qualcuno saprà che la risposta a questo sarà https://twitter.com/filip_woj (creatore del pacchetto nuget sopra) potrebbe valere la pena di contattarlo su Twitter. – BMac

risposta

4

La risposta, dopo aver scelto questo alcune settimane più tardi:

intestazione Cache-Control sembra essere impostato a 'privati' quando si esegue il debug costruisce. Il problema scompare quando corro con una build di rilascio.

6

codice qui sotto insiemi di "cache-control: public, max-age = 15" in modo corretto in applicazione WebAPI vaniglia (System.Web.Http 4.0.0.0). Quindi ... probabilmente non è lo stesso WebApi a causare il problema.

Potresti avere un po 'di magia nel tuo progetto che modifica le impostazioni della cache (pensa ai filtri di azione globali o qualcosa di simile). O forse stai passando per proxy che riscrive le intestazioni 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" 
1

Per aggiungere un'altra cosa che può causare questo:

Si esegue attraverso un oleodotto Owin.

In tal caso, è necessario impostare le intestazioni in un middleware Owin definito come questo:

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

Si è imbattuto in un problema con IE11 in modo aggressivo nella cache delle risposte ajax e questo middleware ha fatto il trucco. Grazie! – seangwright