July 4, 2010 by Christoff Truter C# ASP.NET SQL
Generally I am not a huge fan of storing images in a database, I do however
believe that there is a time/place where this might be desirable - but personally
I would avoid it all together (wont go into too much details).
But for those of you feeling the urge/calling to go this route, lets have a quick look at how
to achieve this using SQL and ASP.net.
First of all, lets have a look at the SQL (backend) side of things:
Create a simple table for storing the images, note the type "image" which will contain
the binary data.
CREATE TABLE [dbo].[images]( [imageID] [int] IDENTITY(1,1) NOT NULL, [title] [varchar](255) NOT NULL, [contentType] [varchar](255) NOT NULL, [contents] [image] NOT NULL, CONSTRAINT [PK_images] PRIMARY KEY CLUSTERED ( [imageID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
CREATE PROCEDURE [dbo].[addImage] @title VARCHAR(255), @contentType VARCHAR(255), @contents IMAGE AS BEGIN INSERT INTO images(title, contentType, contents) VALUES(@title, @contentType, @contents) END
CREATE PROCEDURE [dbo].[viewImage] @imageID INT AS BEGIN SELECT contentType, contents FROM images WHERE imageID = @imageID END
CREATE PROCEDURE [dbo].[viewImages] AS BEGIN SELECT imageID, title FROM images END
<table> <tr> <td> Title </td> <td> <asp:TextBox runat="server" ID="txtTitle"></asp:TextBox> </td> </tr> <tr> <td> Image </td> <td> <asp:FileUpload runat="server" ID="fuImage" /> </td> </tr> <tr> <td colspan="2"> <asp:Button runat="server" ID="btnUpload" Text="Upload" onclick="btnUpload_Click" /> </td> </tr> </table>C# CodeBehind
protected void btnUpload_Click(object sender, EventArgs e) { using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Default"].ConnectionString)) { using (SqlCommand command = new SqlCommand("addImage", connection)) { connection.Open(); command.CommandType = CommandType.StoredProcedure; command.Parameters.AddWithValue("@title", txtTitle.Text); command.Parameters.AddWithValue("@contentType", fuImage.PostedFile.ContentType); command.Parameters.AddWithValue("@contents", fuImage.FileBytes); command.ExecuteNonQuery(); } } }
<%@ WebHandler Language="C#" Class="Handler" %> using System; using System.Web; using System.Data; using System.Configuration; using System.Data.SqlClient; public class Handler : IHttpHandler { public void ProcessRequest(HttpContext context) { Int32 imageID = 0; if (Int32.TryParse(context.Request.QueryString["imageID"], out imageID)) { using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Default"].ConnectionString)) { using (SqlCommand command = new SqlCommand("viewImage", connection)) { connection.Open(); command.CommandType = CommandType.StoredProcedure; command.Parameters.AddWithValue("@imageID", imageID); using (SqlDataAdapter adapter = new SqlDataAdapter(command)) { DataTable dt = new DataTable(); adapter.Fill(dt); context.Response.ContentType = dt.Rows[0].Field<string>("contentType"); context.Response.BinaryWrite(dt.Rows[0].Field<byte[]>("contents")); } } } } } public bool IsReusable { get { return false; } } }
<asp:ListView runat="server" ID="lvImages" ItemPlaceholderID="phImages"> <LayoutTemplate> <table> <asp:PlaceHolder runat="server" ID="phImages"></asp:PlaceHolder> </table> </LayoutTemplate> <ItemTemplate> <tr> <td> <%# Eval("title") %> </td> <td> <img src="Handler.ashx?imageID=<%# Eval("imageID") %>" /> </td> </tr> </ItemTemplate> </asp:ListView>C# CodeBehind
protected DataTable viewImages() { using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Default"].ConnectionString)) { using (SqlCommand command = new SqlCommand("viewImages", connection)) { connection.Open(); command.CommandType = CommandType.StoredProcedure; using (SqlDataAdapter adapter = new SqlDataAdapter(command)) { DataTable dt = new DataTable(); adapter.Fill(dt); return dt; } } } } protected void Page_Load(object sender, EventArgs e) { lvImages.DataSource = viewImages(); lvImages.DataBind(); }
context.Response.AddHeader("Content-Disposition", "attachment; filename=somefile.jpg");
Re: Default Image December 14, 2010 by Christoff Truter
Personally I wouldn't store a default image - a bit unnecessary. I would leave it as a null, e.g. if null return default image location in virtual directory instead of ashx handler.