2010-03-31 73 views
0

我将图像存储在SQL Server 2000数据库(BLOB类型)中。我的ASP.NET应用程序中有一个Web页面,它需要向最终用户显示大量图像,并且我想通过IHttpAsyncHandler处理浏览器对图像的请求。我在代码项目"Asynchronous HTTP Handler for Asynchronous BLOB DataReader." 上发现了一个模拟器帖子但由于某些原因,在完成“BeginProcessRequest”方法和“EndProcessRequest”方法完成后页面冻结从未获得调用。任何人都可以看看这个帖子,让我知道这个帖子最新的错误?或者我需要做什么来完成这项任务(通过IHttpAsyncHandler读取BLOB)?BLOB通过IHttpAsyncHandler读取

在这篇文章的源代码是为下

public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) 
{ 
    try 
    { 
     // image to retrieve 
     // this needs to change if setup a different path schema in the httpHandles web.config 
     string imgId = context.Request.Url.Segments[context.Request.Url.Segments.Length - 1]; 

     SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalBLOB"].ConnectionString); 
     conn.Open(); 
     SqlCommand cmd = conn.CreateCommand(); 
     cmd.CommandText = "select image from BLOBTest where imgId='" + imgId + "'"; 
     // store our Command to be later retrieved by EndProcessRequest 
     context.Items.Add("cmd", cmd); 

     // start async DB read 
     return cmd.BeginExecuteReader(cb, context, 
      CommandBehavior.SequentialAccess | // doesn't load whole column into memory 
      CommandBehavior.SingleRow |   // performance improve since we only want one row 
      CommandBehavior.CloseConnection); // close connection immediately after read 
    } 
    catch (Exception exc) 
    { 
     // will return an image with the error text 
     this.renderError(context, "ERROR: " + exc.Message); 
     context.Response.StatusCode = 500; 
     context.Response.End(); 
     // just to avoid compilation errors 
     throw; 
    } 
} 

/// <summary> 
/// Provides an end method for an asynchronous process. 
/// </summary> 
/// <param name="result">An IAsyncResult that contains information about the status of the process.</param> 
public void EndProcessRequest(IAsyncResult result) 
{ 
    HttpContext context = (HttpContext)result.AsyncState; 

    try 
    { 
     // restore used Command 
     SqlCommand cmd = (SqlCommand)context.Items["cmd"]; 
     // retrieve result 
     using (SqlDataReader reader = cmd.EndExecuteReader(result)) 
     { 
      this.renderImage(context, reader); 
     } 
    } 
    catch (Exception exc) 
    { 
     // will return an image with the error text 
     this.renderError(context, "ERROR: " + exc.Message); 
     context.Response.StatusCode = 500; 
    } 
} 

#endregion 

#region IHttpHandler Members 

public bool IsReusable 
{ 
    get { return true; } 
} 

public void ProcessRequest(HttpContext context) 
{ 
    // should never get called 
    throw new Exception("The method or operation is not implemented."); 
} 

#endregion 

/// <summary> 
/// Render a BLOB field to the Response stream as JPEG 
/// </summary> 
/// <param name="context">HttpContext of current request</param> 
/// <param name="myReader">open SqlDataReader to read BLOB from</param> 
private void renderImage(HttpContext context, SqlDataReader myReader) 
{ 
    // Size of the BLOB buffer. 
    const int bufferSize = 1024;    
    long startIndex = 0; 
    byte[] outbyte = new byte[bufferSize]; 
    long retval; 

    myReader.Read(); 

    context.Response.Clear(); 
    context.Response.ContentType = "image/jpeg"; 

    do 
    { 
     retval = myReader.GetBytes(0, startIndex, outbyte, 0, bufferSize); 
     // reposition the start index 
     startIndex += bufferSize; 
     // output buffer 
     context.Response.BinaryWrite(outbyte); 
     context.Response.Flush(); 
    } while (retval == bufferSize); 
} 

/// <summary> 
/// Renders an Error image 
/// </summary> 
/// <param name="context">HttpContext of current request</param> 
/// <param name="msg">message text to render</param> 
private void renderError(HttpContext context, string msg) 
{ 
    context.Response.Clear(); 
    context.Response.ContentType = "image/jpeg"; 
    // calculate the image width by message length 
    Bitmap bitmap = new Bitmap(7 * msg.Length, 30); 
    Graphics g = Graphics.FromImage(bitmap); 
    // create a background filler 
    g.FillRectangle(new SolidBrush(Color.DarkRed), 0, 0, bitmap.Width, bitmap.Height); 
    // draw our message 
    g.DrawString(msg, new Font("Tahoma", 10, FontStyle.Bold), new SolidBrush(Color.White), new PointF(5, 5)); 
    // stream it to the output 
    bitmap.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg); 
} 
+0

说实话,没有看到*你的*代码,我们真的不会有太大的帮助。 SO还有一些其他问题已经涵盖了通过HTTPHandler将图像流(数据库blob)作为图像返回:http://stackoverflow.com/questions/385681/how-to-know-which-image-has -been-requested-c-asp-net/385948#385948,http://stackoverflow.com/questions/385945/problem-using-ihttphandler and http://stackoverflow.com/questions/386142/ihttphandler-example-required -for-image-type-files-c-asp-net/386171#386171(它有进一步的链接到提供Blob流的文章)。 – 2010-03-31 22:58:53

+0

我试图使用相同的代码从那篇文章/后我在我的问题中提到。您可以将该帖子想象为我的源代码。 – shaniirfan 2010-04-01 01:41:22

回答

0

我知道这是一个非常晚的答复,但也许这可以帮助一些其他球员。

我希望您的连接字符串具有异步处理= true。

此外,您还需要在RenderImage函数中添加内容处置标题。

context.Response.AddHeader("Content-Disposition", "attachment; filename=imagefilename.extension"); 

终于在做while while循环后添加Context.Response.End()调用。