简体   繁体   中英

How to download a file from a specific row in GridView

I need some assistance with downloading a file in a specific row in my GridView .

This is my code for the the GridView markup:

 <asp:GridView ID="GridView1" runat="server" 
                       AutoGenerateColumns="False"
                       DataKeyNames="id" 
                       CssClass="mydatagrid" 
                       Width="550px" 
                       BackColor="#DEBA84" 
                       BorderColor="#DEBA84" 
                       BorderStyle="None" 
                       BorderWidth="1px" 
                       CellPadding="3" 
                       CellSpacing="2" 
                       AllowSorting="true">
                    <Columns>
                          <asp:BoundField DataField="filename" HeaderText="Name" />
                          <asp:BoundField DataField="datestamp" HeaderText="Date" />
                          <asp:TemplateField ShowHeader="False">
                        <ItemTemplate>
                         <asp:Button ID="Button1" runat="server" 
                                            Text="Download" 
                                            ControlStyle-CssClass="btn btn-success" 
                                            CommandName="MyCommand" CommandArgument='<%# DataBinder.Eval(Container, "RowIndex") %>'/>
                                    </ItemTemplate>
             </asp:TemplateField>
          </Columns>
      <FooterStyle BackColor="#F7DFB5" ForeColor="#8C4510" />
      <HeaderStyle BackColor="#A55129" Font-Bold="True" ForeColor="White" width="250px" />
      <PagerStyle ForeColor="#8C4510" HorizontalAlign="Center" />
      <RowStyle BackColor="#FFF7E7" ForeColor="#8C4510" />
      <SelectedRowStyle BackColor="#738A9C" Font-Bold="True" ForeColor="White" />
      <SortedAscendingCellStyle BackColor="#FFF1D4" />
      <SortedAscendingHeaderStyle BackColor="#B95C30" />
      <SortedDescendingCellStyle BackColor="#F1E5CE" />
      <SortedDescendingHeaderStyle BackColor="#93451F" />
  </asp:GridView>

And then for downloading the file I have:

 protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if (e.CommandName.Equals("MyCommand"))
    {
        int rowIndex = int.Parse(e.CommandArgument.ToString());
        string val = (string)this.GridView1.DataKeys[rowIndex]["id"];
        string strQuery = "SELECT filename, filecontent, datestamp FROM FileTable where id=@id";
        SqlCommand cmd = new SqlCommand(strQuery);
        cmd.Parameters.Add("@id", SqlDbType.Int).Value = 1;
        DataTable dt = GetData(cmd);
        if (dt != null)
        {
            download(dt);
        }
    }
}
private DataTable GetData(SqlCommand cmd)
{
    DataTable dt = new DataTable();
    String strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
    SqlConnection con = new SqlConnection(strConnString);
    SqlDataAdapter sda = new SqlDataAdapter();
    cmd.CommandType = CommandType.Text;
    cmd.Connection = con;
    try
    {
        con.Open();
        sda.SelectCommand = cmd;
        sda.Fill(dt);
        return dt;
    }
    catch
    {
        return null;
    }
    finally
    {
        con.Close();
        sda.Dispose();
        con.Dispose();
    }
}
private void download (DataTable dt)
{
    Byte[] bytes = (Byte[])dt.Rows[0]["filecontent"];
    Response.Buffer = true;
    Response.Charset = "";
    Response.Cache.SetCacheability(HttpCacheability.NoCache);
    Response.ContentType = dt.Rows[0]["filecontent"].ToString();
    Response.AddHeader("content-disposition", "attachment;filename="
    + dt.Rows[0]["filename"].ToString());
    Response.BinaryWrite(bytes);
    Response.Flush(); 
    Response.End();
}

So what happens now is when I click on the download it always download the first row's file instead of the row I clicked on to download.

I know I need to specify on which row I have clicked in order to download the file, but not sure on how to accomplish it?

Thanks

It is because of this line

cmd.Parameters.Add("@id", SqlDbType.Int).Value = 1;

You then need to change from onclick to a grid command:

<asp:TemplateField>
    <ItemTemplate>
        <asp:Button ID="Button1" runat="server"Text="Download" 
                      ControlStyle-CssClass="btn btn-success" CommandName="MyCommand" CommandArgument='<%# DataBinder.Eval(Container, "RowIndex") %>'
    </ItemTemplate>
</asp:TemplateField>

And in your code behind

protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if(e.CommandName.Equals("MyCommand"))
    {
        int rowIndex = int.Parse(e.CommandArgument.ToString());
        string val = (string)this.grid.DataKeys[rowIndex]["id"];
        // you can run your query here
    }
}

In your case:

 protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if (e.CommandName.Equals("MyCommand"))
    {
        int rowIndex = int.Parse(e.CommandArgument.ToString());
        var val = this.GridView1.DataKeys[rowIndex]["id"];
        string strQuery = "SELECT filename, filecontent, datestamp FROM FileTable where id=@id";
        SqlCommand cmd = new SqlCommand(strQuery);
        cmd.Parameters.Add("@id", SqlDbType.Int).Value = val;
        DataTable dt = GetData(cmd);
        if (dt != null)
        {
            download(dt);
        }
    }
}

You need to also add the onrowcommand="ContactsGridView_RowCommand" to your Gridview

<asp:GridView ID="GridView1" runat="server" onrowcommand="ContactsGridView_RowCommand"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM