HttpWebRequest simplemente puede utilizar la caché de IE, por lo que si todas las imágenes estarán en esa caché de todos modos, y el costo de re-escribir el archivo (pero no tener que descargarlo) es aceptable, puede simplemente hacer uso de eso.
Si usted necesita para manejar por sí mismo, sin embargo, a continuación:
dado:
string uri; //URI of the image.
DateTime? lastMod; // lastModification date of image previously recorded. Null if not known yet.
string eTag; //eTag of image previously recorded. Null if not known yet.
Vas a tener que almacenar estos al final de este, y recuperarlos de nuevo (cuando no una nueva imagen) al principio.Eso depende de usted, teniendo en cuenta que, el resto funciona:
var req = (HttpWebRequest)WebRequest.Create(uri);
if(lastMod.HasValue)
req.IfModifiedSince = lastMod.Value;//note: must be UTC, use lastMod.Value.ToUniversalTime() if you store it somewhere that converts to localtime, like SQLServer does.
if(eTag != null)
req.AddHeader("If-None-Match", eTag);
try
{
using(var rsp = (HttpWebResponse)req.GetResponse())
{
lastMod = rsp.LastModified;
if(lastMod.Year == 1)//wasn't sent. We're just going to have to download the whole thing next time to be sure.
lastMod = null;
eTag = rsp.GetResponseHeader("ETag");//will be null if absent.
using(var stm = rsp.GetResponseStream())
{
//your code to save the stream here.
}
}
}
catch(WebException we)
{
var hrsp = we.Response as HttpWebResponse;
if(hrsp != null && hrsp.StatusCode == HttpStatusCode.NotModified)
{
//unfortunately, 304 when dealt with directly (rather than letting
//the IE cache be used automatically), is treated as an error. Which is a bit of
//a nuisance, but manageable. Note that if we weren't doing this manually,
//304s would be disguised to look like 200s to our code.
//update these, because possibly only one of them was the same.
lastMod = hrsp.LastModified;
if(lastMod.Year == 1)//wasn't sent.
lastMod = null;
eTag = hrsp.GetResponseHeader("ETag");//will be null if absent.
}
else //some other exception happened!
throw; //or other handling of your choosing
}
E-tags son más confiables que la última modificación, cuando se aplica correctamente (teniendo en cuenta las resoluciones inferiores a un segundo sobre los cambios, y que reflejan diferentes respuestas debido a la diferente Accept- * encabezados). Sin embargo, algunas implementaciones son problemáticas (IIS6 en una granja de servidores web sin un ajuste en particular, Apache con mod-gzip) por lo que puede valer la pena sacar el código relacionado con las etiquetas electrónicas y simplemente ir por la fecha.
Editar: Si quería ir más allá al implementar el almacenamiento en caché HTTP, también podía almacenar caducas y max-age (use este último si están ambos presentes y no está de acuerdo con el anterior) y omita la descarga por completo si es más temprano que esos valores sugieren. He hecho esto y funciona bien (tenía un caché en la memoria de objetos creados por el XML devuelto por varios URI, y si el XML era reciente o no había cambiado, volví a utilizar el objeto), pero puede ser irrelevante para sus necesidades (si desea estar más fresco de lo que sugiere el servidor, o si siempre estará fuera de esa ventana).
Esto puede ser de su interés: https://developers.google.com/speed/docs/best-practices/caching#LeverageBrowserCaching – rboarman
¿Tiene control sobre el servidor web? Si no, ¿es compatible con el almacenamiento en caché, Etags, ... al servir esas imágenes? –
No estoy seguro de cómo funcionaría esto a través de HTTP, pero podría probar [propiedad CreationTime de FileInfo] (http://msdn.microsoft.com/en-us/library/system.io.filesysteminfo.creationtime.aspx). La razón por la que no estoy seguro es que no puedo decir si el valor de la propiedad sería la fecha de creación real o si sería la fecha en que la accedió por última vez (soy un tanto ignorante sobre el tema). Vale la pena echar un vistazo aunque. – MilkyWayJoe