HTTP ETag in Windows 8-Apps verwenden

Das ETag ist ein HTTP Header-Feld, das eingesetzt werden kann, um das erneute Laden von nicht veränderten Dateien zu vermeiden.

Fallbeispiel:

Man lädt Daten für eine App aus einer XML-Datei von einem Webserver. Bei jedem Start der App möchte man garantieren, dass die aktuellen Daten vorhanden sind. Das geht natürlich nur, wenn bei jedem Start der App die XML-Datei auf dem Server abgerufen -und auf Veränderungen überprüft wird. Dazu müsste man aber erst die komplette Datei herunterladen und parsen. Wenn sich die Datei auf dem Server nicht geändert hat, ist der immer wiederkehrende Vorgang des Herunterladens und Parsens überflüssig. Um diesen Überfluss zu vermeiden, kann man das ETag einsetzen.

Durch das ETag wird mitgeteilt, ob sich die Ressource verändert hat. Ist dies der Fall, verändert sich auch das ETag. Man muss also nur das ETag zwischenspeichern und bei jedem Start überprüfen. Hat sich das ETag verändert, wird die XML-Datei heruntergeladen und geparst. Hat sich das ETag nicht verändert, gibt es eine HttpRequestException mit der Information: „304 (Not Modified)“ und man weiß, dass man auf dem aktuellsten Stand ist.

Code-Beispiel

EtagMain

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
private async void EtagMain()
{
  // Initial Setup
  string eTag = String.Empty;
  string requestUri = "https://www.bennyn.de/samples/test.xml";
  HttpClient httpClient = new HttpClient();
  httpClient.BaseAddress = new Uri(requestUri);
 
  // See if we ever got an ETag
  string key = "ETag";
  object localEtag = LoadLocalSetting(key);
 
  // If we do not have a locally stored ETag, then get one from the server
  if (localEtag == null)
  {
    eTag = await GetETag(httpClient);
    SaveLocalSetting(key, eTag);
  }
  else
  {
    // Get locally stored ETag
    eTag = localEtag.ToString();
    // Look if the resource has changed (Recognizable by changed ETag)
    httpClient.DefaultRequestHeaders.Add("If-None-Match", eTag);
    try
    {
      eTag = await GetETag(httpClient);
      // Save new ETag (if the resource has been updated, otherwise there will be a HttpRequestException)
      SaveLocalSetting(key, eTag);
    }
    catch(HttpRequestException exception)
    {
      // 304 (Not Modified)
    }
  }
}

LoadLocalSetting

1
2
3
4
5
private object LoadLocalSetting(string key)
{
  Windows.Storage.ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
  return localSettings.Values[key];
}

SaveLocalSetting

1
2
3
4
5
private void SaveLocalSetting(string key, string value)
{
  Windows.Storage.ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
  localSettings.Values[key] = value;
}

GetETag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private async Task<string> GetETag(HttpClient httpClient)
{
  String eTag = String.Empty;
  HttpResponseMessage response = await httpClient.GetAsync(httpClient.BaseAddress);
  response.EnsureSuccessStatusCode();
 
  // Receive new ETag
  IEnumerable<string> values = null;
  if (response.Headers.TryGetValues("ETag", out values))
  {
    IEnumerator<string> enumerator = values.GetEnumerator();
    while (enumerator.MoveNext())
    {
      eTag += enumerator.Current;
    }
  }
 
  return eTag;
}

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.