You need to provide the ability for a user to upload a file to the web server that will be processed later, so you want to store the file in the database.
Implement the solution described in Recipe 15.2, but when the user clicks a button to initiate the upload process, instead of writing the file to the filesystem, use the input stream containing the uploaded file along with ADO.NET to write the file to a database.
For the .aspx
file, follow the steps for
implementing the .aspx
file in Recipe 15.2.
In the code-behind class for the page, use the .NET language of your choice to:
Process the Upload button click event and verify that a file has been uploaded.
Open a connection to the database.
Build the command used to add the data to the database and insert the file data.
The application we’ve written to demonstrate this
solution uses the same .aspx
file as
Recipe 15.2s example (see
Example 15-4). The code-behind for our application is
shown in Example 15-11 (VB) and Example 15-12 (C#). The initial output is the same as
Recipe 15.2s example output
and is shown in Figure 15-3.
Storing an uploaded file in a database is useful when a complete, unmodified record of the upload is required to be set apart from the web server’s filesystem, when the file contains sensitive information, or when additional metadata needs to be stored with the file. It is also quite common to store the uploaded data in a database and then process the data either immediately or by another program outside of the web application, although we don’t go into that here.
The example we’ve written to demonstrate this
solution includes a button to initiate the upload process and uses
the input stream containing the uploaded file along with ADO.NET to
write the file to a database. The example uses the same code as
Recipe 15.2, changing only the actions
performed in the btnUpload_ServerClick
method of
the code-behind. After verifying that a file is actually uploaded, a
connection is made to the database.
An OleDbCommand
is then created with the
CommandText
property set to a parameterized SQL
INSERT
statement to store the filename, the file
size, and the contents of the file in the database. A parameterized
query is used to handle the binary data contained in the file.
The FileData
column of our database needs to be
able to handle the binary data contained in the file. For SQL Server,
the data type should be VarBinary or image
. Even
if the uploaded files are text files, it is best to use a binary
field for storage of the data. Text files can contain Unicode or
UTF-8 encoded characters that SQL Server cannot store in text fields,
which results in a SQL exception being thrown.
Next, three parameters are added to the parameter collection of the
command object and the values are set with the uploaded file
information. Because our example uses OleDb
, which
does not support named parameters like the SQL provider does, the
parameters must be added in the same order they appear in the
INSERT
statement.
The Filename
and Filesize
parameters each require creating the parameter and setting the value.
The Filedata
parameter is created in the same
manner; however, the value must be set to a byte array. This requires
creating a new BinaryReader
stream from the posted
file input stream and then using the ReadBytes
method of the BinaryReader
to create the required
byte array.
The last step is to set the connection property of the command to the
connection opened earlier and executing the command. The
ExecuteNonQuery
method of the command object is
used because no data is being returned by the command.
Recipe 15.2 for the base code used for this recipe and a discussion of the size limits on uploaded files
Example 15-11. Storing uploaded file to database code-behind (.vb)
Private Sub btnUpload_ServerClick(ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles btnUpload.ServerClick Dim dbConn As OleDbConnection Dim dcmd As OleDbCommand Dim bReader As BinaryReader Dim strConnection As String Dim filename As String Dim filesize As Integer Try 'make sure file was specified and was found filename = txtUpload.PostedFile.FileName.Trim If ((filename.Length > 0) And _ (txtUpload.PostedFile.ContentLength > 0)) Then'get the connection string from web.config and open a connection
'to the database
strConnection = _
ConfigurationSettings.AppSettings("dbConnectionString")
dbConn = New OleDbConnection(strConnection)
dbConn.Open( )
'build the command used to add the data to the database
dcmd = New OleDbCommand
dcmd.CommandText = "INSERT INTO FileUpload " & _
"(Filename, Filesize, FileData) " & _
"VALUES " & _
"(?, ?, ?)"
'create the paramters and set the values for the file data
dcmd.Parameters.Add(New OleDbParameter("Filename", _
filename))
filesize = txtUpload.PostedFile.ContentLength
dcmd.Parameters.Add(New OleDbParameter("Filesize", _
filesize))
bReader = New BinaryReader(txtUpload.PostedFile.InputStream)
dcmd.Parameters.Add(New OleDbParameter("FileData", _
bReader.ReadBytes(filesize)))
'insert the file data
dcmd.Connection = dbConn
dcmd.ExecuteNonQuery( )
End If Finally If (Not IsNothing(dbConn)) Then dbConn.Close( ) End If If (Not IsNothing(bReader)) Then bReader.Close( ) End If End Try End Sub 'btnUpload_ServerClick
Example 15-12. Storing uploaded file to database code-behind (.cs)
private void btnUpload_ServerClick(object sender, System.EventArgs e) { OleDbConnection dbConn = null; OleDbCommand dcmd = null; BinaryReader bReader = null; string strConnection = null; string filename = null; int filesize; try { // make sure file was specified and was found filename = txtUpload.PostedFile.FileName.Trim( ); if ((filename.Length > 0) && (txtUpload.PostedFile.ContentLength > 0)) {// get the connection string from web.config and open a connection
// to the database
strConnection =
ConfigurationSettings.AppSettings["dbConnectionString"];
dbConn = new OleDbConnection(strConnection);
dbConn.Open( );
// build the command used to add the data to the database
dcmd = new OleDbCommand( );
dcmd.CommandText = "INSERT INTO FileUpload " +
"(Filename, Filesize, FileData) " +
"VALUES " +
"(?, ?, ?)";
// create the paramters and set the values for the file data
dcmd.Parameters.Add(new OleDbParameter("Filename",
filename));
filesize = txtUpload.PostedFile.ContentLength;
dcmd.Parameters.Add(new OleDbParameter("Filesize",
filesize));
bReader = new BinaryReader(txtUpload.PostedFile.InputStream);
dcmd.Parameters.Add(new OleDbParameter("FileData",
bReader.ReadBytes(filesize)));
// insert the file data
dcmd.Connection = dbConn;
dcmd.ExecuteNonQuery( );
} } // try finally { if (dbConn != null) { dbConn.Close( ); } if (bReader != null) { bReader.Close( ); } } // finally } // btnUpload_ServerClick