ASP.NET Web Api Cache Header

De Teilnehmer meines aktuellen Web Performance Optimierung Kurs haben es voll drauf. Die Fragen gehen richtig tief. Selbst an der Verbesserung der ASP.NET Web Api REST Services sind wir dran.

Mit einer gewissen Logik sind AJAX Calls auf REST Services per default nicht cachable. Der HTTP Header enthält

   1:  Cache-Control: no-cache
   2:  Pragma: no-cache
   3:  Content-Type: application/json; charset=utf-8
   4:  Expires: -1

Allerdings hat Microsoft bei ASP.NET Core durchaus die Möglichkeit eingebaut. Per ResponseCache Klassenattribut lässt sich das Caching wie von ASP.NET gewohnt steuern.

Das lässt sich durchaus nachbauen, indem man eine Klasse geerbt von ActionFilter baut. Action Filter werden in die Response Pipline ala IIS eingefügt. In diesem VB.NET Beispiel um den Antwort Header zu manipulieren.

   1:  Imports System.Net.Http.Headers
   2:  Imports System.Web.Http.Filters
   3:   
   4:  Friend Class ResponseCacheAttribute
   5:      Inherits ActionFilterAttribute
   6:      Public Property Duration As Integer
   7:      Public Overrides Sub OnActionExecuted(filterContext As HttpActionExecutedContext)
   8:   
   9:          filterContext.Response.Headers.CacheControl = New CacheControlHeaderValue() With {
  10:          .MaxAge = TimeSpan.FromMinutes(Duration),
  11:          .MustRevalidate = True,
  12:          .[Private] = True
  13:      }
  14:   
  15:      End Sub
  16:   
  17:  End Class

 

Ganz wichtig: der Aufruf muss per Ajax Call erfolgen, da der Browser eine Art Eigenleben entwickelt. Hier das JavaScript Code Schnippsel auf Basis von Jquery

   1:    $.ajax({
   2:      type: "Get",
   3:      url: "/api/Time",
   4:      contentType: "application/json; charset=utf-8",
   5:      data: "",
   6:      dataType: "json",
   7:      success: fertig,
   8:      error: fail
   9:      });

 

Der Web Api Controller liefert die Uhrzeit zurück.

   1:  Public Class TimeController
   2:      Inherits ApiController
   3:   
   4:      ' GET api/<controller>
   5:      <ResponseCache(Duration:=180)>
   6:      Public Function GetValues() As IEnumerable(Of String)
   7:          Return New String() {Date.Now}
   8:      End Function

Durch das HTTP Header Cache Attribut, unterbindet der Browser dann den Ajax Call für die genannte Dauer komplett. Im initalen Call sieht der Antwort Header wie folgt aus

   1:  HTTP/1.1 200 OK
   2:  Cache-Control: must-revalidate, max-age=10800, private
   3:  Content-Type: application/json; charset=utf-8
   4:  Server: Microsoft-IIS/10.0
   5:  X-AspNet-Version: 4.0.30319

Volle zwei Stunden muss nun der Benutzer auf neue Daten. Workaround API Url mit Versionsnummer oder Einsatz von Etag.

Kommentare sind geschlossen