将数据库中的图像检索到图像标记中

我的Web应用程序允许用户发送报告,并且最多可以将5个图像作为varbinary(MAX)插入数据库(SQL Server)。 我现在正在找到一种方法来检索用户发送的特定报告的所有图像。 以前,我曾经通过aspx页面逐个检索图像1。 但是当用户只插入5个图像时,我遇到了一个问题。我的另外4个图像标签将显示空图像。 所以现在我试图找到一种方法,如果我可以在1个图像标签中基于报告检索这些图像。 图像与之前的报告存储在同一个表中,现在我将其更改为2个表。 MemberReport是报告的所有详细信息,MemberReportImage是报告的所有图像。

下面的代码允许我根据memberreportid将我的MemberReportImage表中的第一个图像检索到图像标记中,但是我想一次检索具有相同memberreportid的所有图像而不是图像标记。 正如我认为它需要一个循环来获取所有图像,但我不知道该怎么做。 所以我需要有人来帮助我。 谢谢!

protected void Page_Load(object sender, EventArgs e) { string strQuery = "select image from MemberReportImage where memberreportid='" + Session["memberreportid"] + "'"; SqlCommand cmd = new SqlCommand(strQuery); DataTable dt = GetData(cmd); if (dt != null) { download(dt); } } private DataTable GetData(SqlCommand cmd) { DataTable dt = new DataTable(); SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString); SqlDataAdapter sda = new SqlDataAdapter(); cmd.CommandType = CommandType.Text; cmd.Connection = con; try { con.Open(); sda.SelectCommand = cmd; sda.Fill(dt); return dt; } catch { return null; } finally { con.Close(); sda.Dispose(); con.Dispose(); } } private void download(DataTable dt) { // check if you have any rows at all // no rows -> no data to convert! if (dt.Rows.Count  if not, you can't do anything! if (dt.Rows[0].IsNull("image")) return; Byte[] bytes = (Byte[])dt.Rows[0]["image"]; Response.Buffer = true; Response.Charset = ""; Response.Cache.SetCacheability(HttpCacheability.NoCache); Response.ContentType = "image/jpg"; Response.BinaryWrite(bytes); Response.End(); } 

你可以在那里做很多例子。 这个答案分为两部分。 首先,您需要(在您的UI页面上)确定存在哪些图像,并根据查询结果显示\隐藏图像。 接下来,您需要使用页面(或更恰当的HttpHandler)在页面上显示图像。 我在下面嘲笑了一个快速示例。 我试图评论代码,以帮助您阅读它。

你的ASPx页面(Html)

 

这是一个包含5张图片的简单页面。 您的页面将会更加复杂,但这仅用于演示目的。 接下来,我们将使用页面加载事件(或任何其他事件)从数据库中查找图像并隐藏未上载的图像。

ASPx页面(代码)

 protected void Page_Load(object sender, EventArgs e) { Session["memberreportid"] = 1; //TODO: Remove this var query = "SELECT TOP 1 * FROM MemberReport where memberreportid=@p1"; //create the format string for each image. Note the last variable is {0} for additional formating string imageSource = string.Format("/viewImage.ashx?memberreportid={0}&imageID={1}", Session["memberreportid"], "{0}"); //set our URL to our Image handler for each image Image1.ImageUrl = string.Format(imageSource, 1); Image2.ImageUrl = string.Format(imageSource, 2); Image3.ImageUrl = string.Format(imageSource, 3); Image4.ImageUrl = string.Format(imageSource, 4); Image5.ImageUrl = string.Format(imageSource, 5); //execute our command. Note we are using parameters in our SQL to circumvent SQL injection using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["conString"].ConnectionString)) { var cmd = new SqlCommand(query, con); cmd.CommandType = System.Data.CommandType.Text; cmd.CommandTimeout = 3000; cmd.Parameters.AddWithValue("@p1", Session["memberreportid"]); con.Open(); var reader = cmd.ExecuteReader(); while (reader.Read()) { //hide each image if the image is null or not a byte array (should always be a byte array) if (reader["image1"] == null || !(reader["image1"] is byte[])) Image1.Visible = false; if (reader["image2"] == null || !(reader["image2"] is byte[])) Image2.Visible = false; if (reader["image3"] == null || !(reader["image3"] is byte[])) Image3.Visible = false; if (reader["image4"] == null || !(reader["image4"] is byte[])) Image4.Visible = false; if (reader["image5"] == null || !(reader["image5"] is byte[])) Image5.Visible = false; //we only want the first row so break (should never happen anyway) break; } con.Close(); } } 

正如您从上面所看到的,我们只是根据找到的ID进行查询以查找上传的图像。 如果图像为空(或不是字节[]),则隐藏图像控件。

最后一部分是使用HttpHandler(New Item列表中的GenericHandler)。 HttpHandler可能是你最好的选择,因为你不需要所有页面生成事件,并且可以直接挂钩到HttpHandler上下文。 从这里开始,您可以在ASPx页面中完成您想要做的所有事情(我的个人实现)。 请注意,默认情况下,HttpHandler无法访问会话状态。

添加一个名为viewImage.ashx的新GenericHandler(或任何你想要的)并添加以下代码。 这是评论,以帮助阅读。

viewImage.ashx代码。

 using System; using System.Configuration; using System.Data.SqlClient; using System.Web; namespace WebApplication1 { ///  /// Summary description for viewImage ///  public class viewImage : IHttpHandler { ///  /// process the request ///  /// the current request handler public void ProcessRequest(HttpContext context) { ///extract our params from the request int memberID = 0, imageID = 0; if (!int.TryParse(context.Request["memberreportid"], out memberID) || memberID <= 0 || !int.TryParse(context.Request["imageID"], out imageID) || imageID <= 0) { this.transmitError(); return; } //build our query var query = string.Format("SELECT TOP 1 image{0} FROM MemberReport where memberreportid=@p1", imageID); //execute the query using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["conString"].ConnectionString)) { try { var cmd = new SqlCommand(query, con); cmd.CommandType = System.Data.CommandType.Text; cmd.CommandTimeout = 3000; //set the member command type cmd.Parameters.AddWithValue("@p1", memberID); con.Open(); var reader = cmd.ExecuteReader(); while (reader.Read()) { string psudoFileName = string.Format("memberReport_{0}_image{1}.png", memberID, imageID); byte[] binary = reader[0] as byte[]; context.Response.ContentType = "image/png"; context.Response.AppendHeader("Content-Disposition", string.Format("filename=\"{0}\"", psudoFileName)); context.Response.AppendHeader("Content-Length", binary.Length.ToString()); context.Response.BinaryWrite(binary); //todo: Implement your caching. we will use no caching context.Response.Cache.SetCacheability(HttpCacheability.NoCache); //we only want the first row so break (should never happen anyway) break; } con.Close(); } catch (Exception ex) { //TODO: Maybe some logging? } this.transmitError(); } } ///  /// transmits a non-image found ///  void transmitError() { var context = HttpContext.Current; if (context == null) return; //set the response type context.Response.ContentType = "image/png"; //set as no-cache incase this image path works in the future. context.Response.Cache.SetCacheability(HttpCacheability.NoCache); //transmit the no-image found error context.Response.TransmitFile(context.Server.MapPath("no-image.png")); } public bool IsReusable { get { return false; } } } } 

现在,您应该只需要在页面上显示图像,并且能够在上传图像时显示\隐藏图像。

希望这可以帮助。