ARTICLE

Inserting File And Retrieving it From SQL Server in Asp.Net

Posted by Krishna Garad Articles | ASP.NET Programming February 11, 2011
Here we will learn how we can insert a file into a database and then how we can retrieve the file from the database.
Reader Level:
Download Files:
 


Introduction:

Here we will learn how we can insert a file into a database and then how we can retrieve the file from the database.

On this I have seen so many people that face problems such as inserting a file and then retrieving that file from the database. This article will demonstrate the basic idea and a basic method to perform our task.

Background:

First inserting files into the database is not as easy as inserting a string or integer data. Whenever we want to insert files or images we must convert them into a byte array to be inserted into the Database.

This article also explains for you how to use a muulti-tier architecture design with which we can avoid unnecessary errors. I will explain how to perform this task and everything step-by-step; follow the steps bellow.

Step's:

Create Database and table named Articles and TblUploadDownLoad with the following script.

Create Table TblUploadDownLoad
(
FileId Int Primary Key,
[FileName]Varchar(200),
Extension char(10),
FileData VarBinary(max)
)


Also create a stored procedure for adding files, getting filename and id and for getting data of file on the basis of fileid.

1. For adding Files

Create Procedure Sp_AddFiles
(
@fname Varchar(200),
@ext char(10),
@fdata VarBinary(max)
)
As
Begin
Insert Into
TblUploadDownLoad(FileName,Extension,FileData)
Values(@fname,@ext,@fdata)
End

2. For retriving filename and id of file.

Create Procedure Sp_GetFileNames
As
Begin
Select
FileId,FileName From TblUploadDownLoad
End

3. For Retriving File Data and extension of the file

Create Procedure Sp_GetFile
(
@fid int
)
As
Begin
Select
FileData,Extension From TblUploadDownLoad Where FileId=@fid
End

Now our database work has been done. Now we will create our Data Access Layer Class which will transfer our data from our Logic Class to DataBase and retrieve the Data From Database. Here are three methods written for a particular task; we will see how they work. Before any task cover your application configuration. Here I'm storing my connection string in web.config file. Just go to config file and change the connection string according to your settings.

Web.config

<connectionStrings>
 <
add name="sqlcn" providerName="System.Data.SqlClient" connectionString="Data Source=Server2;User Id=sa;Password=123;DataBase=ARTICLES"/
</connectionStrings>

1. Declaration:

static SqlConnection sqlcn;
static SqlCommand sqlcmd;
static SqlDataAdapter sqlda;
static SqlDataReader sqldr;
static int _records;
static string _ext;

public static string Ext
{
get { return DataHelper._ext; }
set { DataHelper._ext = value; }
}
static DataHelper()
{
sqlcn = new SqlConnection(ConfigurationManager.ConnectionStrings["sqlcn"].ConnectionString);// this is stored in web.confige file.
}
public static int Records
{
get { return DataHelper._records; }
set { DataHelper._records = value; }
}


2. Method To Execute The Stored Procedure for adding file to our database. Which will take name of the procedure and required parameter as input.

public static void ExecuteProcedure(string _procedurename, SqlParameter[] sqlparam)
{
    try
    {
        sqlcn.Open();//opening connection
        sqlcmd = new SqlCommand(_procedurename, sqlcn);//preparing command //object
        foreach (SqlParameter p in sqlparam)
        {
           sqlcmd.Parameters.Add(p);
           //attaching parameters required to procedure.
        }
        sqlcmd.CommandType = CommandType.StoredProcedure;
        _records = sqlcmd.ExecuteNonQuery();
        //executing the query
    }
    catch (Exception)
    {

        throw;
    }
    finally
    {
        sqlcn.Close();
    }
}


3. Method to retrieve resultset only filenames and id from Database which will return dataset object. You might have a doubt about what is ResultSet; it's nothing new; whenever we make a request for data to Database, first the Database will prepare a Resultset object and it returns this ResultSet object.

public static DataSet GetFileNames(string _sql, SqlParameter[] Param)
{
    try
    {
        sqlcmd = new SqlCommand(_sql, sqlcn);
 
        foreach (SqlParameter p in Param)
        {
            sqlcmd.Parameters.Add(p);

        }
        sqlcmd.CommandType = CommandType.StoredProcedure;
        sqlcn.Open();
        DataSet ds = new DataSet();
        sqlda = new SqlDataAdapter(sqlcmd);
        sqlda.Fill(ds);
        return ds;

    }
    catch (Exception)
    {

        throw;
    }
    finally
    {
        sqlcn.Close();
    }
 
}


4. Method to retrieve the filedata which is in binary form from Database. Which will take Name of the procedure and required parameter as input.

public static byte[] GetFileFromDB(SqlParameter[] Param, string _procname)
{
    try
    {

        byte[] file = null;
        sqlcn.Open();
        SqlCommand sqlcmd = new SqlCommand(_procname, sqlcn);
        sqlcmd.CommandType = CommandType.StoredProcedure;
        foreach (SqlParameter para in Param)
        {
            sqlcmd.Parameters.Add(para);
        }

        sqldr = sqlcmd.ExecuteReader();
        if (sqldr.Read())
        {
            file = (byte[])sqldr[0];
            _ext = sqldr[1].ToString();
        }
 
        return file;

    }
    catch (Exception)
    {

        throw;
    }
    finally
    {
        sqldr.Close();
        sqlcn.Close();
    }
}


Now our DataHelper Class is also ready. Now we are ready to consume our DataHelper class. In what way you want to consume it you can. Here I'm using it through one more layer class i.e. Upload.cs which also contain methods to transfer the data from our presentation layer to Data Layer. This class contain three methods for particular task. Like adding file, getting filenames and id and retrieving filedata.

These methods perform their work of transfering data only. Now we will see how those methods work.

1. For adding files, you can see here how you can prepare parameter which are required for our stored procedure.

public bool UploadFile(string _filename, byte[] _filedata, string _ext)
{
    string _spname = "Sp_AddFiles";// our Sp name
    SqlParameter[] Param = new SqlParameter[3];
    Param[0] = new SqlParameter("@fname", SqlDbType.VarChar, 200);
    Param[0].Value = _filename;
    Param[1] = new SqlParameter("@ext", SqlDbType.Char, 10);
    Param[1].Value = _ext;
    Param[2] = new SqlParameter("@fdata", SqlDbType.VarBinary);
    Param[2].Value = _filedata;
    DataHelper.ExecuteProcedure(_spname, Param);
    if (DataHelper.Records > 0)
        return true;
    else
        return false;
}


2. For retrieving filenames and Id of files. Here you can see how you can collect the Dataset object return by our DataHelper class.

public DataSet GetFileNames()
{
    string _sql = "Sp_GetFileNames";
    SqlParameter[] Param = new SqlParameter[0];
    DataSet ds = DataHelper.GetFileNames(_sql, Param);
    return ds;
}

3. This method is for retrieving actual file content which are present in binary form in our database. Our DataHelper class only returns the byte array of that binary data. This method takes the field as input and again return the byte array.

public byte[] GetFile(int _fid)
{
    byte[] _file = null;
    SqlParameter[] Param = new SqlParameter[1];
    Param[0] = new SqlParameter("@fid", SqlDbType.Int);
    Param[0].Value = _fid;
    _file = DataHelper.GetFileFromDB(Param, "Sp_GetFile");
    _ext = DataHelper.Ext;
    return _file;
}


Now our business logic class is also ready; now we are ready to transfer and to retrive data from DataHelper and Presentation Layer. Now we will move to Presentation Layer.

1. Design Screen to Add files to Data like bellow.
upload.jpg
In button click write this code to read the file selected by user into a byte array. And pass this data to our business logic class. First create the object of our business logic class like:

Upload obj = new Upload();

Button_click event.

try
{
if (FileUpload1.HasFile)
{
Int32 intfileSize = 0;
 
Stream fileStream = null;
// Gets the Size of the File
intfileSize = FileUpload1.PostedFile.ContentLength;
// Reads the File
fileStream = FileUpload1.PostedFile.InputStream;
byte[] fileContent = new byte[intfileSize + 1];
int intStatus = 0;
intStatus = fileStream.Read(fileContent, 0, intfileSize);
string ext=System.IO.Path.GetExtension(FileUpload1.FileName.ToString());
if (obj.UploadFile(FileUpload1.FileName.ToString(),fileContent,ext))
{
Label1.Visible = true;
Label1.Text = "File Uploaded";
}
}

}
catch (Exception)
{

Throw;
}


This will read the file data and prepare the byte array as well; it calls the Method of our business logic class for inserting the data.

Now we will see how we can retrieve this uploaded file again; just design the screen like bellow.
download.bmp
Now in Page_Load bind the DropDownList with filenames and Id of that file like bellow.

if (!IsPostBack)
{
    DataSet ds = obj.GetFileNames();
    DropDownList1.DataSource = ds.Tables[0];
    DropDownList1.DataTextField = "FileName";
    DropDownList1.DataValueField = "FileId";
    DropDownList1.DataBind();

}

And in button click write following line of code.

try
{
    byte[] fileData = obj.GetFile(int.Parse(DropDownList1.SelectedValue));
    Response.ClearContent();
    Response.AddHeader("Content-Disposition", "attachment; filename=" + DropDownList1.SelectedItem.Text.ToString());
    BinaryWriter bw = new BinaryWriter(Response.OutputStream);
    bw.Write(fileData);
    bw.Close();
    Response.ContentType = ReturnExtension(obj.Ext);
    Response.End();
}
catch (Exception)
{

    throw;
}


It will ask you what you want to do, either open that file or save that file. And now take a look at the ReturnExtension Method.

private string ReturnExtension(string fileExtension)
{
    switch (fileExtension)
    {
        case ".htm":
        case ".html":
        case ".log":
            return "text/HTML";
        case ".txt":
            return "text/plain";
        case ".docx":
            return "application/ms-word";
        case ".tiff":
        case ".tif":
            return "image/tiff";
        case ".asf":
            return "video/x-ms-asf";
        case ".avi":
            return "video/avi";
        case ".zip":
            return "application/zip";
        case ".xls":
        case ".csv":
            return "application/vnd.ms-excel";
        case ".gif":
            return "image/gif";
        case ".jpg":
        case "jpeg":
            return "image/jpeg";
        case ".bmp":
            return "image/bmp";
        case ".wav":
            return "audio/wav";
        case ".mp3":
            return "audio/mpeg3";
        case ".mpg":
        case "mpeg":
            return "video/mpeg";
        case ".rtf":
            return "application/rtf";
        case ".asp":
            return "text/asp";
        case ".pdf":
            return "application/pdf";
        case ".fdf":
            return "application/vnd.fdf";
        case ".ppt":
            return "application/mspowerpoint";
        case ".dwg":
            return "image/vnd.dwg";
        case ".msg":
            return "application/msoutlook";
        case ".xml":
        case ".sdxl":
            return "application/xml";
        case ".xdp":
            return "application/vnd.adobe.xdp+xml";
        default:
            return "application/octet-stream";
    }
}

You may wonder why we have taken the extension field in DataBase and again we are using this extension here only to specify the file type; either it is text, word or another file.

Conclusion:

In this way you can prepare your Upload/Download of file to Sql Server. You may think again why I wrote this article; there are so many articles that already exist. The reason is how to explain how you can do these things easily and how you can avoid the general errors occurring while inserting or retrieving data from DataBase. Any comments and queries are heartily appreciated.

Login to add your contents and source code to this article
post comment
     

This is really good. DOTNETPOOLS.COM

Posted by vinay singh Oct 08, 2012

Very Good article.To learn more on insert and retrieve file from sql server visit this links .http://jayeshsorathia.blogspot.com/2012/08/net-tips-c-tips-insert-or-save-file-into-sql-server-database-table.htmlhttp://jayeshsorathia.blogspot.com/2012/09/beginning-net-c-tips-get-or-retrive-stored-file-from-sql-server-database-table.html

Posted by jayesh sorathia Sep 13, 2012

No, I have Office 2010 installed. And if you keep selecting Yes through the messsages, it will tell you that Word or Excel has found some content and ask if you would like to recover it. If you select Yes, it opens fine. But the 3 or 4 steps through error messages is not going to be acceptable. I hope that explains it a little better. Thanks.

Posted by William Piersol Apr 05, 2011

I think you don't have the office 2007 or 2010 installed caue of that only it's not opening the files.

Posted by Krishna Garad Apr 05, 2011

Thanks for the great solution. I am having problems when retrieving Office 2007/2010 file. I get the following error when I select the Open option. Excel found unreadable content in “FileName” . Do you want to recover the contents of this workbook? If you select Yes to recover it, it opens fine. But the error message is unacceptable. It works fine for all document types I have found except Office 2007/2010. Has anyone else seen (And hopefully solved.) this issue? Thanks again.

Posted by William Piersol Apr 04, 2011
COMMENT USING
PREMIUM SPONSORS
DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and add new content to existing PDF documents from within your applications.
SPONSORED BY
  • PDF reports have never been easier to create. With our included WYSIWYG Designer, you can layout your reports, set up your data source and let DynamicPDF ReportWriter do the rest.