2010-11-29 3 views
1

Ich verwende eine Instanz von WebClient in meiner Silverlight-Anwendung, um eine Bilddatei zur Anzeige abzurufen. Um diese Anwendung zu bedienen, habe ich einen WCF REST Service eingerichtet. Im Folgenden ist ein Code-Snippet ich für diesen Dienst schrieb:Kann mit WebClient eine Datei aus dem Browser-Cache abgerufen werden, ohne nach einer neueren Version der Datei zu suchen?

DateTime modSince = WebOperationContext.Current.IncomingRequest.Headers[HttpRequestHeader.IfModifiedSince] 
    == null 
    ? DateTime.MinValue 
    : DateTime.Parse(WebOperationContext.Current.IncomingRequest.Headers[HttpRequestHeader.IfModifiedSince].ToString()); 

FileInfo fInfo = new FileInfo(filePath); 

if (fInfo.LastWriteTime > modSince) 
{ 
    WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg"; 
    WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.OK; 
    WebOperationContext.Current.OutgoingResponse.LastModified = fInfo.LastWriteTime; 
} 
else 
{ 
    WebOperationContext.Current.OutgoingResponse.SuppressEntityBody = true; 
    WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotModified; 
} 

Der Dienst wird so eingerichtet, dass über einen Antrag auf eine Bilddatei, die if-modified-since Attribut des Request-Header untersucht wird. Wenn dieser Wert kleiner als das letzte Mal ist, wenn die Datei geändert wird, wird die Datei zurückgegeben. Andernfalls wird eine 304-Nachricht zurückgegeben.

Wir sind daran interessiert, die Transaktion schneller zu machen. Da sich die Bilder selten, wenn überhaupt, ändern, ist es wünschenswert, den Cache nach einer Kopie des Bildes zu durchsuchen, bevor eine Anforderung an den Server gestellt wird, wodurch Netzwerklatenz eingespart wird. Bei dem Versuch, dies für IE zu implementieren, habe ich die Einstellungen für temporäre Internetdateien auf "Nie nach neueren Versionen gespeicherter Seiten suchen" geändert. Wenn ich die REST-Service-URL für ein Bild, das eine Kopie im Cache gespeichert hat, in die Adressleiste des Browsers eingebe, wird die Kopie aus dem Cache abgerufen, ohne dass der Server aufgerufen wird. Wenn die URL jedoch als Parameter für die OpenReadAsync-Methode des WebClient eingegeben wird, wird eine GET-Anforderung an den Server gesendet, die zu einer 304-Nachricht führt.

Gibt es eine Möglichkeit, den WebClient zu verwenden, um den Cache nachzuschlagen, ohne dass eine GET-Anforderung an den Server gesendet wurde?

Antwort

1

Sie können die Anfrage nicht von Code in Silverlight verhindern. Die Einstellung "NIE ÜBERPRÜFEN" ​​des IE wird nur verwendet, wenn keine Cachesteuerungsdirektiven vom Server vorhanden sind. Ich würde nicht empfehlen, sie zu verwenden.

Ich bin mir nicht sicher, warum Sie WCF Rest verwenden, um Bilder an den Client zu liefern, anstatt die Bilder einfach in einen Ordner auf dem Server zu legen und sie als statischen Standardinhalt abzurufen?

In beiden Fällen ist der richtige Ansatz für das Problem, dass der Server angibt, wie die Bilder zwischengespeichert werden sollen, indem ein Cache-Control-Header in die Antwort eingefügt wird. So etwas wie "Cache-Control: max-age = 86400".

+0

Ja, was ich nicht erwähnt habe, ist, dass der REST-Dienst eine vorhandene Datei nimmt und sie in ein anderes Format konvertiert. Technisch gibt es eine Bilddatei zurück. Wir können die Größenanpassung später implementieren. Was Ihre Lösung betrifft, habe ich es ausprobiert, aber nur mit dem Visual Studio Development Server getestet. Die App hat dort noch eine GET-Anfrage gestellt. Da Sie vorgeschlagen haben, dass dies tatsächlich funktionieren würde, habe ich meinen Dienst und meine App für IIS bereitgestellt und dort getestet. Über IIS sucht die App zuerst im Cache nach! Vielen Dank! –

2

Sie müssen die CahcePolicy auf dem WebClient setzen:

WebClient wc = new WebClient(); 
wc.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.CacheIfAvailable); 

Diese Microsoft.Win32.WinInetCache verwenden standardmäßig wird die Cache-Manager IE ist.


UPDATE

OK, ich wusste nicht, es SL ist. In diesem Fall, wenn das Bild klein ist, denke ich, dass es einfacher ist, Dinge zu vereinfachen, indem man vom Server trotzdem abruft. Wenn die Datei groß ist, legen Sie eine Methode offen, um das Datum zurückzugeben, an dem sie zuletzt geändert wurde, und implementieren Sie eine lokale Zwischenspeicherung mithilfe von Isolated Storage.

+0

Ich habe von dieser Lösung gehört, aber leider verwende ich Silverlight. In diesem Kontext scheint die WebClient-Klasse diese Eigenschaft nicht verfügbar zu machen. Hoffentlich gibt es eine andere Möglichkeit, auf den Cache-Manager zuzugreifen. –

+0

Ich habe ein Update gemacht. – Aliostad

Verwandte Themen