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);
}
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). –
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