首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过IHttpAsyncHandler读取BLOB

通过IHttpAsyncHandler读取BLOB
EN

Stack Overflow用户
提问于 2010-04-01 06:40:31
回答 1查看 1.2K关注 0票数 0

我将图像存储在SQL Server 2000数据库(BLOB类型)中。我的ASP.NET应用程序中有一个网页,它需要向最终用户显示大量图像,我希望通过IHttpAsyncHandler处理浏览器对图像的请求。我在代码项目"Asynchronous HTTP Handler for Asynchronous BLOB DataReader."上找到了一个类似的帖子,但由于某些原因,页面在完成"BeginProcessRequest“方法和"EndProcessRequest”方法时冻结,而“EndProcessRequest”方法从未被调用。有没有人可以看看这篇文章,让我知道那篇文章有什么问题?或者我需要做什么来完成这个任务(通过IHttpAsyncHandler读取BLOB)?

这篇文章的源代码如下:

代码语言:javascript
复制
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);
}
EN

回答 1

Stack Overflow用户

发布于 2011-04-26 14:34:54

我知道这是一个很晚的回复,但也许这对其他人有帮助。

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

此外,您还需要在RenderImage函数中添加一个内容部署标头。

代码语言:javascript
复制
 context.Response.AddHeader("Content-Disposition", "attachment; filename=imagefilename.extension");

最后,在do while循环之后添加一个Context.Response.End()调用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2556981

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档