HttpWebRequest は IE キャッシュを使用するだけなので、とにかくすべての画像がそのキャッシュにあり、ファイルを書き換えるコスト (ダウンロードする必要はない) が許容できる場合は、それを利用することができます。
ただし、自分で処理する必要がある場合は、次のようにします。
与えられた:
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.
これの最後にこれらを保存し、最初に (新しい画像ではない場合) 再度取得する必要があります。それはあなた次第です、それを考えると、残りはうまくいきます:
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 タグは、正しく実装されている場合、最終変更よりも信頼性が高くなります (変更が 1 秒未満で解決され、異なる Accept-* ヘッダーによる異なる応答が反映されることに注意してください)。ただし、一部の実装にはバグがあります (Web ファーム上の IIS6、特定の微調整なしの Apache、mod-gzip を使用した Apache)。
編集: HTTP キャッシュの実装をさらに進めたい場合は、expires と max-age (両方が存在し、前者と一致しない場合は後者を使用) を保存し、それらよりも早い場合はダウンロードを完全にスキップすることもできます。値が示唆します。私はこれを実行しましたが、うまく機能します (さまざまな URI によって返された XML から作成されたオブジェクトのメモリ内キャッシュがあり、XML が新しいか変更されていない場合は、オブジェクトを再利用しました)。あなたのニーズには関係ないかもしれません (サーバーが提案するよりも新鮮であることを気にしている場合、または常にそのウィンドウの外にいる場合)。