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

本文关键字:图像 图像检索 数据库 | 更新日期: 2023-09-27 18:30:49

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

下面的代码允许我根据成员报告ID从我的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 <= 0)
        return;
    // check if your row #0 even contains data -> 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)

<form id="form1" runat="server">
    <div>
        <asp:Image ID="Image1" runat="server" />
        <asp:Image ID="Image2" runat="server" />
        <asp:Image ID="Image3" runat="server" />
        <asp:Image ID="Image4" runat="server" />
        <asp:Image ID="Image5" runat="server" />
    </div>
</form>

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

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查找上传的图像。如果图像为 null(或不是字节 []),则隐藏图像控件。

最后部分是使用 HttpHandler(来自 New Item 列表的 GenericHandler)。HttpHandler 可能是您最好的选择,因为您不需要所有页面生成事件,可以直接挂接到 HttpHandler 上下文中。从这里,您可以在ASPx页面(我的个人实现)中执行几乎所有您想执行的操作。注意:默认情况下,HttpHandler 无权访问会话状态。

添加一个名为 viewImage.ashx 的新 GenericHandler(或您想要的任何代码)并添加以下代码。再次对此进行注释以帮助通读。

viewImage.ashx code.

using System;
using System.Configuration;
using System.Data.SqlClient;
using System.Web;
namespace WebApplication1
{
    /// <summary>
    /// Summary description for viewImage
    /// </summary>
    public class viewImage : IHttpHandler
    {
        /// <summary>
        /// process the request
        /// </summary>
        /// <param name="context">the current request handler</param>
        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();   
            }
        }
        /// <summary>
        /// transmits a non-image found
        /// </summary>
        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;
            }
        }
    }
}

现在,这应该是您在页面上显示图像所需的全部内容,并且可以在上传图像时显示''隐藏图像。

希望这有帮助。