Asp.net缓存动态图片
实现原理:
首先,要知道原始图片的最后一次修改时间。
其次,获取本地缓存文件夹中该文件的时间。
最后,两个时间比较,如果本地缓存的时间大于原始图片最后一次修改的时间,那么就告诉浏览器本地已经有这个文件了,不用再去请求了,将HTTP状态值置为304即可;否则就去动态生成你需要的小图片,并且将这个小图片通过设置Last-Modified HTTP标头来实现本地访问时间。
好了,原理我们知道了,那代码怎么实现呢?
01
protected void Page_Load(object sender, EventArgs e)
02
{
03
string imgPath = string.IsNullOrEmpty(Request["imgPath"]) ? "" : Request["imgPath"].ToString();
04
05
Response.ContentType = "image/jpeg";
06
DateTime contentModified = System.IO.File.GetLastWriteTime(imgPath);
07
08
if (IsClientCached(contentModified))
09
{
10
Response.StatusCode = 304;
11
12
Response.SuppressContent = true;
13
}
14
else
15
{
16
17
Thumbnail.GenerateHighThumbnail(imgPath, 80, 80); //这里是生成缩略图的代码,网上到处都是,这里就不展现了。
18
19
Response.Cache.SetETagFromFileDependencies();
20
Response.Cache.SetAllowResponseInBrowserHistory(true);
23
}
24
25
26
}
27
28
private bool IsClientCached(DateTime contentModified)
29
{
30
string header = Request.Headers["If-Modified-Since"];
31
32
if (header != null)
33
{
34
DateTime isModifiedSince;
35
if (DateTime.TryParse(header, out isModifiedSince))
36
{
37
return isModifiedSince >= DateTime.Parse(contentModified.ToString());
38
}
39
}
40
41
return false;
42
}
重点说一下IsClientCached方法中的return isModifiedSince >= DateTime.Parse(contentModified.ToString());
这里contentModified本来就是DateTime类型,为什么还要把它转成字符串,然后再转回日期型呢?
我在这里折腾了好长时间,是因为我们取出原始图片最后一次修改的时间精确到毫秒,而通过Request.Headers["If-Modified-Since"];请求的结果是伦敦标准时间,没有毫秒值,所以如果不转换一下就会出现已经缓存的图片,由于毫秒的问题,使return isModifiedSince >= DateTime.Parse(contentModified.ToString()); 返回false,这里转换后将毫秒去掉后就可以正常了。