Asp .Net FileUpload and Image Handler

This article is written by Pon Saravanan  on 10-Nov-09 Last modified on :14-Jan-10

Subscribe to my RSS Feed!

Asp .Net FileUpload to save image to the DataBase

I have worked in GridView for displaying different kind of data. The interesting portion is when there is a possibility to attach image, photo. This is not a very big task. But if it is done properly, the result will be very useful to the end user.

For this article I would like to extend bit further to add some image viewing capability to the GridView using HttpHandler. The following is the intention of this article.
1) ASP.Net FileUpload to upload the image to the web server
2) Read it as a byte array and don’t save it to the file system
3) Update the  byte array to save it to the database
4) Load the grid with image control and reference the image path to a HttpHandler
5) Develop the HttpHandler to read the data into a byte array
6) In HttpHandler render the data as image and set the content type as image

Asp.Net File Upload to upload file

The uploaded data can be easily accessed using the object PostedFile, if you want to save use the PostedFile.SaveAs () method to save to a file system. But our intention is to save it to a DB so we just access the byte array into a variable and push it to database later.

As explained earlier the File Upload is going to be in the GridView. And the selected file has to be uploaded to the web server using a PostBack. So we use a submit button along with the FileUpload in the ItemTemplate. (For further information regarding wiring command to the buttons in the ItemTemplate, read here Asp .net GridView with templates)

Fetch data from File Upload Control into a byte array

In the RowCommand event of the GridView after the CommandName is verified, the Command argument can be used to fetch the current row (based on the assumption that the command argument is bound with the Container.DataItemIndex in the markup).
Once the row is available use the FindControl to get the FileUpload, PostedFile object has an InputStream, with that the byte array can be populated with the uploaded file.

Update the Database with byte array

We are using Northwind Database for the sample, this time we have taken the employees table. Basically the update query will be
Update Employees set Photo=@Photo where EmployeeId=@EmployeeId
So we need two SqlParameters to pass the Employee id and the byte array. Byte array we have just seen how to fetch it and the employee id can be taken from the Datakeys. Remember to assign DataKeyNames in the markup to GridView as EmployeeId (for this sample).

HttpHandler to show the image in GridView

Fetch the data for the respective employee

The data for the photo in the table can not be viewed without converting it to image. To make the development simpler and easier to manage, we don’t save the image uploaded by Asp .Net FileUpload  to the file location or to disk. I have experienced lot of troubles if we are saving the data to the disk. So now I am going to stream the content to the client with response. HttpHandler is the best to handle this.

HttpHandler will retrieve the data from the database into a byte array. To get the respective row from employees table we need the EmployeeId. This employee id can be passed as a parameter to the Handler as we do for URLs.

Render the image

After the data has been fetched from the table, then content can be rendered into the response stream using context.Response.OutputStream.Write().We need to set the Content Type as image before rendering. There are few content types available for images(Note: we can detect the content type of the uploaded image using Asp .Net FileUpload ). I have chosen bitmaps for this sample. It is a good practice to save the content type, file name of the uploaded file(using Asp .Net FileUpload ) along with file data in the database. So that later when we streaming we can stream them with proper content type.

Source Code

Markup

<%@ Page Language="VB" AutoEventWireup="false"
        CodeFile="Default.aspx.vb" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
       
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:GridView runat="server" AutoGenerateColumns="false"
        AllowSorting="true" ID="GridView1"
        ShowFooter="true" DataKeyNames="EmployeeId">
        <Columns>
            <asp:BoundField DataField="LastName" HeaderText="LastName" />
            <asp:BoundField DataField="FirstName" HeaderText="FirstName" />
            <asp:TemplateField>
                <ItemTemplate>
                    <asp:Image runat="server"
                    ImageUrl='<%# "DbImageHandler.ashx?EmployeeId=" & eval("EmployeeId") %>' />
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField>
                <ItemTemplate>
                    <asp:FileUpload runat="server" ID="FileUpload1" />
                    <asp:Button runat="server" ID="btnSubmit" Text="Submit"
                     CommandName="UPLOAD" CommandArgument="<%# Container.DataItemIndex %>" />
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>
    </form>
</body>
</html>
 

Code-Behind

Imports System.Data.SqlClient
Imports System.Data
Imports System.IO
Partial Class _Default
    Inherits System.Web.UI.Page
    Protected Sub Page_Load(ByVal sender As Object, _
                            ByVal e As System.EventArgs) Handles Me.Load
        If (Not IsPostBack) Then
            LoadGrid()
        End If
    End Sub
   
    Private ReadOnly Property ConnectionString() As String
        Get
            Return "Server=.\SQLEXPRESS;Database=NorthWind;Trusted_Connection=True"
        End Get
    End Property
    Private ReadOnly Property Connection() As SqlConnection
        Get
            Dim ConnectionToFetch As New SqlConnection(ConnectionString)
            ConnectionToFetch.Open()
            Return ConnectionToFetch
        End Get
    End Property
    Public Function GetData() As DataSet
        Dim SelectQry = " Select * from Employees "
        Dim SampleSource As New DataSet
        Try
            Dim SampleDataAdapter As New SqlDataAdapter(SelectQry, ConnectionString)
            SampleDataAdapter.Fill(SampleSource)
        Catch ex As Exception
            Throw ex
        End Try
        Return SampleSource
    End Function
    Protected Sub LoadGrid()
        GridView1.DataSource = GetData().Tables(0)
        GridView1.DataBind()
    End Sub
    Protected Sub GridView1_RowCommand(ByVal sender As Object, _
                                       ByVal e As GridViewCommandEventArgs) _
                                       Handles GridView1.RowCommand
        If (e.CommandName = "UPLOAD") Then
            UpdateEmployee(Convert.ToInt32(e.CommandArgument))
        End If
    End Sub
    Protected Sub GridView1_RowDataBound(ByVal sender As Object, _
                                         ByVal e As GridViewRowEventArgs) _
                                         Handles GridView1.RowDataBound
        If (e.Row.RowState = DataControlRowState.Edit) Then
        End If
    End Sub
    Private Sub UpdateEmployee(ByVal RowID As Integer)
        Dim UpdateQuery = " Update Employees " & _
            " set Photo=@Photo " & _
            " where EmployeeId=@EmployeeId "
        Dim CurrentRow = GridView1.Rows(RowID)
        Dim Uploader As FileUpload = CurrentRow.FindControl("FileUpload1")
        Dim EmployeeId = GridView1.DataKeys(RowID).Value
        Dim UpdateCommand As New SqlCommand(UpdateQuery, Connection)
        Dim IdParam As New SqlParameter("EmployeeId", SqlDbType.Int)
        Dim PhotoParam As New SqlParameter("Photo", SqlDbType.Image)
        Dim PhotoData(Uploader.PostedFile.InputStream.Length) As Byte
        Uploader.PostedFile.InputStream.Read(PhotoData, 0, PhotoData.Length)
        IdParam.Value = EmployeeId
        PhotoParam.Value = PhotoData
        UpdateCommand.Parameters.Add(IdParam)
        UpdateCommand.Parameters.Add(PhotoParam)
        UpdateCommand.ExecuteNonQuery()
    End Sub
 
End Class
 

HttpHandler

<%@ WebHandler Language="VB" Class="DbImageHandler" %>
Imports System
Imports System.Web
Imports System.Data.SqlClient
Imports System.Data
Public Class DbImageHandler : Implements IHttpHandler
    Private ReadOnly Property ConnectionString() As String
        Get
            Return "Server=.\SQLEXPRESS;Database=NorthWind;Trusted_Connection=True"
        End Get
    End Property
    Private ReadOnly Property Connection() As SqlConnection
        Get
            Dim ConnectionToFetch As New SqlConnection(ConnectionString)
            ConnectionToFetch.Open()
            Return ConnectionToFetch
        End Get
    End Property
    Public Function GetData(ByVal EmployeeId As String) As DataSet
        Dim SelectQry = " Select * from Employees where " & _
            " EmployeeId =" & EmployeeId
       
        Dim SampleSource As New DataSet
        Try
            Dim SampleDataAdapter As New SqlDataAdapter(SelectQry, ConnectionString)
            SampleDataAdapter.Fill(SampleSource)
        Catch ex As Exception
            Throw ex
        End Try
        Return SampleSource
    End Function
    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
        context.Response.Clear()
        context.Response.ContentType = "image/bmp"
        Dim ImageBuffer As Byte()
        Dim EmployeeId As String = context.Request.Params("EmployeeId")
        ImageBuffer = GetData(EmployeeId).Tables(0).Rows(0)("Photo")
        context.Response.OutputStream.Write(ImageBuffer, 0, ImageBuffer.Length)
        context.Response.End()        
    End Sub
 
    Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property
End Class









GUEST
Hi, and how you deal with large file uploads? 11/11/2009 6:28:37 AM

GUEST
Great presentation. Looks are nice and code readablity, and sectionwise explanation is good. 1/15/2010 7:29:52 AM


Comments
   
Captcha Image
For you specially:  
Captcha Text Enter the text in the image.(Not Case sensitive)    




Spam Bot Trap