I'm trying to serve image data stored in a VARBINARY(MAX) field in the database using ASP.Net. Right now, the code is filling a data table, then pulling the byte array out of the DataRow and pushing the byte array into the response. I'm wondering if there's a way to more-or-less stream the data from the SQL Server into the response without having to marshal around these huge byte arrays (since the images are large, they cause OutOfMemoryExceptions). Is there a class/mechanism for that?
The current code looks more or less like:
DataTable table = new DataTable();
SqlDataAdapter adapter = new SqlDataAdapter(commandText, connectionString);
adapter.Fill(table);
DataRow row = table.Rows[0];
byte[] imageData = row[0] as byte[];
if(imageData != null)
{
Response.Clear();
Response.BinaryWrite(imageData);
Response.End();
}
Thanks in advance - any help is appreciated.
See Download and Upload Images from SQL Server for an article covering the topic, including efficient streaming semantics. You must use a SqlDataReader
opened with CommandBehavior.SequentialAccess
:
SequentialAccess Provides a way for
the DataReader to handle rows that
contain columns with large binary
values. Rather than loading the entire
row, SequentialAccess enables the
DataReader to load data as a stream.
You can then use the GetBytes or
GetChars method to specify a byte
location to start the read operation,
and a limited buffer size for the data
being returned.
The linked article provides full code for creating a Stream backed by an SqlDataReader, you can simply Stream.CopyTo
(HttpResponse.OutputStream)
, or use a byte[] chunked copy if you don't have .Net 4.0 yet.
This follow up article explains how to use a FILESTREAM column for efficient streaming of large VARBINARY data in and out of the database.