C# HTTP映像处理程序有时无法返回映像
我正在使用.NET HTTP处理程序(IsReusable设置为true)根据指定的ID返回一个图像。传递的URL看起来像这样C# HTTP映像处理程序有时无法返回映像,c#,httphandler,C#,Httphandler,我正在使用.NET HTTP处理程序(IsReusable设置为true)根据指定的ID返回一个图像。传递的URL看起来像这样ReadImage.ashx?ID=N。一旦句柄接收到请求,它将获取ID并在HTTP缓存中查找以前的base64编码图像,如下所示: byte[] image; if (context.Cache["image_" + id] != null) { image = Convert.FromBase64String(context.Cache["image_" +
ReadImage.ashx?ID=N
。一旦句柄接收到请求,它将获取ID并在HTTP缓存中查找以前的base64编码图像,如下所示:
byte[] image;
if (context.Cache["image_" + id] != null)
{
image = Convert.FromBase64String(context.Cache["image_" + id].ToString());
}
else
{
var dbImage = m_database.Images.Single(i => i.Id.Equals(id));
string filePath = context.Server.MapPath(string.Format("~/{base path}/{0}", dbImage.Filename));
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
image = new byte[fs.Length];
fs.Read(image, 0, image.Length);
context.Cache.Add("image_" + dbImage.Id, Convert.ToBase64String(image), null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(20), CacheItemPriority.Normal, null);
}
}
如果不存在,则继续从数据库获取文件名,从磁盘读取文件,将其编码为base64,并将字节存储在image
中,最后将图像缓存20分钟,如下所示:
byte[] image;
if (context.Cache["image_" + id] != null)
{
image = Convert.FromBase64String(context.Cache["image_" + id].ToString());
}
else
{
var dbImage = m_database.Images.Single(i => i.Id.Equals(id));
string filePath = context.Server.MapPath(string.Format("~/{base path}/{0}", dbImage.Filename));
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
image = new byte[fs.Length];
fs.Read(image, 0, image.Length);
context.Cache.Add("image_" + dbImage.Id, Convert.ToBase64String(image), null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(20), CacheItemPriority.Normal, null);
}
}
然后我最终将BinaryWrite
myimage
缓冲区写入当前上下文的输出流:
context.Response.ContentType = "image/png";
context.Response.BinaryWrite(image);
context.Response.Flush();
现在,这一切都运行得很好——但并非一直如此。我偶尔会得到一个损坏的图像,但刷新后图像(99%的时间)就在那里了
查看Chrome调试器中的网络流量,我可以看到我的处理程序在图像被破坏的情况下返回text/html
,而不是应该返回的image/png
。我曾尝试将我的处理程序包装在一个try catch
中,并记录异常详细信息,但它没有做任何事情——它只是继续将垃圾返回到请求页面
到目前为止,我已经尝试了一些方法:
图像
缓冲成4096个块位图
对象并返回该对象我是不是错过了这里显而易见的东西??我有点困惑,有人有什么建议吗?我猜。我的问题在于以下代码:
if (context.Cache["image_" + id] != null)
{
image = Convert.FromBase64String(context.Cache["image_" + id].ToString());
}
缓存可能随时失效。很可能在if语句的计算结果为true后,缓存项立即变为无效,最终第二个get将变为null。最好这样做(不是100%确定):
与其说是一个解决方案,不如说是一个更好的解决办法 我决定为它创建一个MVC操作,而不是使用通用处理程序。这里是行动,我没有一次失败,它似乎要快得多
[HttpGet]
public ActionResult GetImage(int id)
{
byte[] buffer;
if (HttpContext.Cache["image_" + id] == null)
{
var dbMediaItem = m_database.MediaItems.Single(i => i.Id.Equals(id));
string path = string.Format(Server.MapPath("~/{base path}/{0}"), dbMediaItem.Filename);
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
{
buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
HttpContext.Cache.Add("image_" + id, Convert.ToBase64String(buffer), null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(20), CacheItemPriority.Normal, null);
}
}
else
{
buffer = Convert.FromBase64String(HttpContext.Cache["image_" + id].ToString());
}
return base.File(buffer, "image/png");
}
不幸的是,如果我完全删除缓存,这个问题仍然存在(尽管稍微更糟),不过还是要感谢大家的提醒。