Saving Images to SQL Server with ASP.NET and ADO.NET
Last Updated: Nov 14, 2025
6 min read
Legacy Archive
Legacy Guidance:
This article demonstrates a classic pattern for storing images in SQL Server using ASP.NET and ADO.NET.
It is preserved for teams maintaining existing .NET Framework applications. For modern guidance on file storage,
cloud blobs, and CDN integration, explore the Tutorials section.
Introduction
Many web applications need to work with user-uploaded images such as profile pictures, product photos,
or document scans. The most common approach is to store the files on disk and keep only the path in the database.
However, legacy .NET Framework applications sometimes store the image itself directly in SQL Server.
This article shows how to upload an image from an ASP.NET page, convert it into a byte[],
and store it in a SQL Server column using ADO.NET. It also outlines the steps to retrieve the image and stream
it back to the browser.
Older code samples use the SQL Server IMAGE data type. While that type is deprecated in favor of
VARBINARY(MAX), you will still encounter IMAGE columns in existing databases,
so understanding the legacy pattern remains useful.
Designing a table for image storage
A typical legacy table for storing images might include an identity column, a caption or file name,
and a binary column for the image data. For example:
Example table for storing images
-- Legacy schema using IMAGE (deprecated type)
CREATE TABLE ImageTable
(
ImageID INT IDENTITY(1,1) PRIMARY KEY,
ImageName NVARCHAR(255) NOT NULL,
ImageData IMAGE NOT NULL
);
-- Recommended for newer databases:
-- Use VARBINARY(MAX) instead of IMAGE
-- ImageData VARBINARY(MAX) NOT NULL
In a typical ASP.NET application, the ImageID or ImageName is used to look up the
binary data when you need to render or download the image.
Uploading an image using ASP.NET and ADO.NET
On the ASP.NET side, you can use a file upload control (such as <input type="file">
or <asp:FileUpload>) along with a text box for the image name or caption, and a button
that triggers the upload logic.
The original article followed a pattern very similar to this: read the input stream of the posted file
into a byte[], then call ExecuteNonQuery to insert the bytes into the database. :contentReference[oaicite:1]{index=1}
C# upload handler: store image bytes in SQL Server
using System;
using System.Data.SqlClient;
using System.IO;
using System.Web.UI;
public partial class UploadImage : Page
{
protected void btnUpload_Click(object sender, EventArgs e)
{
if (!fileUpload.HasFile)
{
// Handle missing file
return;
}
// 1. Read the uploaded file into a byte[]
int imageLength = fileUpload.PostedFile.ContentLength;
byte[] imageBytes = new byte[imageLength];
using (Stream inputStream = fileUpload.PostedFile.InputStream)
{
inputStream.Read(imageBytes, 0, imageLength);
}
// 2. Insert the image into the database
const string connectionString = "your-connection-string-here";
const string sql = @"
INSERT INTO ImageTable (ImageData, ImageName)
VALUES (@ImageData, @ImageName);";
using (var conn = new SqlConnection(connectionString))
using (var cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@ImageData", imageBytes);
cmd.Parameters.AddWithValue("@ImageName", txtImageName.Text.Trim());
conn.Open();
cmd.ExecuteNonQuery();
}
}
}
Conceptually this code performs the same steps described in the original article:
Read the posted file’s input stream and get its content length.
Allocate a byte[] and fill it with the uploaded image data.
Create a SqlConnection and open it.
Create a SqlCommand with parameter placeholders.
Add parameters for the image bytes and the image name or identifier.
Execute the command using ExecuteNonQuery().
Close the connection.
Retrieving and streaming the image to the browser
To display an image that is stored in the database, you typically route the
<img> tag to an ASP.NET page or HTTP handler that streams the bytes.
The original algorithm used a MemoryStream, a Bitmap, and
Response.OutputStream to send the image back to the client. :contentReference[oaicite:2]{index=2}
A simplified version using an HTTP handler might look like this:
C# handler: stream image bytes from SQL Server
using System;
using System.Data.SqlClient;
using System.Web;
public class ImageHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string id = context.Request.QueryString["id"];
if (string.IsNullOrEmpty(id))
return;
const string connectionString = "your-connection-string-here";
const string sql = @"
SELECT ImageData
FROM ImageTable
WHERE ImageID = @ImageID;";
byte[] imageBytes = null;
using (var conn = new SqlConnection(connectionString))
using (var cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@ImageID", id);
conn.Open();
object result = cmd.ExecuteScalar();
if (result != null && result != DBNull.Value)
{
imageBytes = (byte[])result;
}
}
if (imageBytes == null)
return;
// Set an appropriate content type (adjust if you store different formats)
context.Response.ContentType = "image/jpeg";
context.Response.OutputStream.Write(imageBytes, 0, imageBytes.Length);
}
public bool IsReusable => false;
}
In your ASP.NET page, you can now reference the handler from an <img> tag:
When does it make sense to store images in the database?
Storing images in a database has pros and cons:
Pros: images are backed up with the database, permissions can be centralized,
and application code does not need to track file paths or clean up orphaned files.
Cons: the database can grow large quickly, which may affect backup and restore times;
large binary data can also have performance implications if not managed carefully.
Many teams choose a hybrid approach: small images or thumbnails are stored in SQL Server,
while larger photos or documents are stored on disk or in cloud storage with only a reference path
kept in the database.
Modern considerations
For new development on modern .NET and SQL Server versions, consider:
Using VARBINARY(MAX) instead of the deprecated IMAGE data type.
Storing large files in external storage (file shares, blob storage, or CDN-backed storage).
Keeping the database focused on relational data and metadata about the files.
Using streaming APIs and async I/O when working with large binary data.
The patterns in this article remain helpful when you maintain existing .NET Framework applications
built around database-stored images, but new projects can generally adopt more modern storage options.
Quick FAQ
Should I store images in SQL Server or on disk?
It depends on your requirements. Storing images in SQL Server keeps everything in one place and
ensures that database backups include the images. However, it can increase database size and backup times.
Many teams store small images or thumbnails in the database and keep large media files on disk or in cloud storage,
with only a reference path in the table.
Which data type is recommended for image storage today?
Older legacy code often uses the IMAGE data type in SQL Server. That type is deprecated.
For new schema design, use VARBINARY(MAX) instead, and handle image metadata such as file name
and content type in separate columns.
How do I stream an image back to an ASP.NET page?
Read the image bytes from SQL Server into a byte[] using ADO.NET, set
Response.ContentType to the correct MIME type (for example, image/jpeg),
and write the bytes to Response.OutputStream from a page or HTTP handler. The browser
can then render the image directly from the response.