2010-03-31 19 views
0

Je stocke des images dans la base de données SQL Server 2000 (type BLOB). Il y a une page web dans mon application ASP.NET qui doit montrer beaucoup d'images à l'utilisateur final et je veux gérer les requêtes du navigateur pour les images via un IHttpAsyncHandler. J'ai trouvé un message similaire sur codeproject "Asynchronous HTTP Handler for Asynchronous BLOB DataReader." Mais pour certaines raisons, la page se bloque à la fin de la méthode "BeginProcessRequest" et la méthode "EndProcessRequest" ne reçoit jamais d'appel. Quelqu'un peut-il regarder ce poste et laissez-moi savoir ce qui est faux dans ce poste? OU ce que je dois faire pour accomplir cette tâche (lecture BLOB via IHttpAsyncHandler)?BLOB Lecture via IHttpAsyncHandler

Le code source dans ce post est comme sous,

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

Pour être honnête, sans voir * votre * code, nous ne serons pas vraiment en mesure d'aider beaucoup. Il y a quelques autres questions sur SO qui couvrent déjà le retour d'un flot d'octets (votre blob de base de données) sous forme d'image via un HTTPHandler: 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 et http://stackoverflow.com/questions/386142/ihttphandler-example-required -pour-image-type-fichiers-c-asp-net/386171 # 386171 (qui a d'autres liens vers des articles sur le service Blob Streams). –

+0

J'ai essayé d'utiliser le même code à partir de cet article/article que j'ai mentionné dans ma question. Vous pouvez imaginer cet article comme mon code source. – shaniirfan

Répondre

0

Je sais que c'est très en retard réponse mais peut-être cela peut aider d'autres gars. J'espère que votre chaîne de connexion a un traitement asynchrone = true.

Vous devez également ajouter un en-tête de disposition de contenu dans votre fonction RenderImage.

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

finalement après la boucle Do While ajouter un appel Context.Response.End().