使用HttpHandlerstream数据库图像

很长一段时间,当我在本地机器上处理涉及基于数据库的图像的Web应用程序项目时,我已经注意到一些烦人的事情。 当地我的意思是这是一个典型的环境与VS 2008和SQL Server 2005在我的工作站上。 每当我使用HttpHandler在本地显示图像时,只有一些图像在每个页面上呈现。

但是,当我将应用程序推送到托pipe环境时,问题通常会消失。 但是,我只是推出了一个新的项目到一个托pipe环境,并遇到了与我本地相同的问题 – 这一次,站点和数据库在托pipe环境中的同一台服务器上。 有没有人在这里发生了什么?

这是处理程序:

[WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class FeaturedHandler : IHttpHandler { Business biz = new Business(); public void ProcessRequest(HttpContext context) { if (context.Request.QueryString["ListingID"] != null) { int listingID = Convert.ToInt32(context.Request.QueryString["ListingID"]); DataSet ds = biz.GetFeaturedImageByID(listingID); DataRow row = ds.Tables[0].Rows[0]; byte[] featureImage = (byte[])row["Photo"]; context.Response.ContentType = "image/jpeg"; context.Response.OutputStream.Write(featureImage, 0, featureImage.Length); } else throw new ArgumentException("No ListingID parameter specified"); } public bool IsReusable { get { return false; } } } 

我曾尝试在单独的服务器上使用数据库,但遇到同样的问题。 我应该使用DataReader吗?

更新我应该使用一个DataReader,因为我正在读取二进制数据。

我最终通过将IsReusable属性的值更改为true来获取所有图像:

  public bool IsReusable { get { return true; } } 

显然,这将处理程序保存在内存中,并能够处理多个请求。 设置为false时,必须为每个传入请求创build一个新的处理程序实例。

这样:

每当我使用HttpHandler在本地显示图像时,只有一部分图像在每个页面上呈现。

你的意思是说,在不同的图像应该出现的地方出现同样的图像,或者出现一些图像,有些图像根本不出现?

在你的情况下,通过切换isReusable到真正的差异是new Business(); 将被调用一次为多个图像。 如果isReusable为false,则new Business(); 将被称为每个图像一次。 这意味着,如果你每页有几个图像new Business(); 将被称为这个特定的页面几次。

另外我强烈build议改变这一点:

 if (context.Request.QueryString["ListingID"] != null) { int listingID = Convert.ToInt32(context.Request.QueryString["ListingID"]); 

有:

 string listingIdParam = context.Request.QueryString["ListingID"]; if (listingIdParam != null) { int listingID = Convert.ToInt32(listingIdParam); 

这将为您节省通常仅在重负载下才会出现的空引用exception。 同样,以上将防止向请求提供错误的图像,特别是当isReusable为真时。

我不能确定问题是什么,但我可以肯定地说,设置isReusable标志只是一个解决方法,并不能解决您的问题。 另外当像这样的问题只能在特定的环境下重现时,意味着它是一个线程问题,或者在请求处理(不同的Web服务器 – IIS6,IIS7,开发服务器)方面有所不同。

也许张贴Business类和它的构造可以摆脱一些光。 另外我build议实施某种错误日志logging来处理exception,并检查它们。

如果您直接提供图片,请不要忘记设置正确的caching标题,即etags和过期。 如果你不这样做,你真的会打你的数据库,并用尽你的带宽。

你需要处理下面的http头文件:

  • ETag的
  • 过期
  • 上一次更改
  • 如果-匹配
  • 如果 – 无 – 匹配
  • 如果-Modified-Since的
  • 如果未修饰的,因为
  • 除非-Modified-Since的

例如http处理程序可以检查: http : //code.google.com/p/talifun-web/wiki/StaticFileHandler