Monday, June 11, 2012

Downloading file using GridView in Asp.Net.



In some of the cases we want to give file listing with download option. Here I am explaining, How to download file using GridView in Asp.Net?

For this task, I have created my Database table like this-
FileDetails(FileId,FileName,FilePath)


Here-

FileId -  Auto generated filed, to maintain primary key for file
FileName - Name of Uploaded file
FilePath - Complete file path for uploaded file
 

In this example, I am designing GridView with three columns, Here FileId and FilePath will be invisible mode, FileName will be displayed to the user. based on user action FileId and FilePath will be fetched from GridView and these values will be used for further processing.  
 

.aspx code-

 <asp:GridView ID="grdFileDetails" runat="server" AutoGenerateColumns="false" OnRowCommand="grdFileDetails_RowCommand">
        <EmptyDataTemplate>
            <div style="color: Red; text-align: center; width: 700px">
                No Data Found.
            </div>
        </EmptyDataTemplate>
        <Columns>
            <asp:TemplateField HeaderText="File ID" ItemStyle-HorizontalAlign="Left">
                <ItemTemplate>
                    <asp:Label ID="lblFileId" runat="server" Text='<%# Eval("FileId") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="File Name" ItemStyle-HorizontalAlign="Left">
                <ItemTemplate>
                    <asp:Label ID="lblFileName" runat="server" Text='<%# Eval("FileName") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="File Path" Visible="false">
                <ItemTemplate>
                    <asp:Label ID="lblFilePath" runat="server" Text='<%# Eval("FilePath") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Download">
                <ItemTemplate>
                    <asp:Button ID="btnDownLoad" runat="server" Text="Download" CommandName="download"  CommandArgument='<%# Eval("FilePath") %>' />
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

 
In above code, I have taken 4 columns in GridView, but here File ID and File Path is hidden, I am not showing File Path and File ID. I am passing FilePath value using CommandArgument property, this value will be used in server side code to download file. For button I have set CommandName= "download" so that button click can be handled in RowCommand() event of GridView.

        <ItemTemplate>
            <asp:Button ID="btnDownLoad" runat="server" Text="Download" CommandName="download"  CommandArgument='<%# Eval("FilePath") %>' />
        </ItemTemplate>

 

The output of this .aspx will be -

Downloading file using GridView.

Now .cs code-

 protected void grdFileDetails_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            try
            {
                //Code to download file
                if (e.CommandName == "download")
                {
                    string filepath = Convert.ToString(e.CommandArgument);

                    byte[] data = System.IO.File.ReadAllBytes(filepath);
                    Response.Clear();
                    Response.ClearHeaders();
                    Response.AddHeader("Content-Type", "Application/octet-stream");
                    Response.AddHeader("Content-Length", data.Length.ToString());
                    Response.AddHeader("Content-Disposition", "attachment; filename=" + filepath);
                    Response.BinaryWrite(data);
                    Response.End();
                }

            }

            catch (Exception)
            {
                 throw;
            }
        }


In above code, I have implemented GridVIew_RowCommand() event , here first I am checking commandName value using e.CommandName.

To get particular file path here I am using e.CommandArgument like this-

   string filepath = Convert.ToString(e.CommandArgument);

 After getting File path I have used Response object to download file like this-
 
   Response.BinaryWrite(data);
 
Here data will contain binary data that will be downloaded as a file. Before download the file it is must that we have to set some settings using Response.AddHeader() method. Here we have to set Content-Type and  Content-Length for downloading object.  Now if you will click on download button then related file will be downloaded.

Thanks

5 comments:

  1. Replies
    1. Could not find a part of the path 'C:\Program Files (x86)\Common Files\Microsoft Shared\DevServer\10.0\emp_resume\Case_studies.pdf'.

      Delete
    2. HI Sayantan,
      The error itself show that file is not present in given path.
      You should give correct path for each file in filepath field in table.

      Try and let me know.

      Delete
    3. gridview_rowcommand is not working in my code but iam not getting any errors

      Delete
  2. hi ,
    iam not getting errors but iam unable to download a file here over my code


    cs.code
    private void bindgrid()
    {


    con = new SqlConnection(str);
    con.Open();
    SqlDataAdapter da = new SqlDataAdapter("select Code,Tiltle,Abstract from btechcivilmajorswprjcts ", con);
    DataSet ds = new DataSet();
    da.Fill(ds);
    GridView1.DataSource = ds;
    GridView1.DataBind();

    con.Close();
    }
    protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
    {
    try
    {
    //Code to download file

    if (e.CommandName == "download")
    {
    string filepath = Convert.ToString(e.CommandArgument);

    byte[] data = System.IO.File.ReadAllBytes(filepath);
    Response.Clear();
    Response.ClearHeaders();
    Response.AddHeader("Content-Type", "Application/octet-stream");
    Response.AddHeader("Content-Length", data.Length.ToString());
    Response.AddHeader("Content-Disposition", "attachment; filename=" + filepath);
    Response.BinaryWrite(data);
    Response.End();
    }

    }


    catch (Exception)
    {
    throw;
    }

    ReplyDelete