如何使用 Gridview 的链接按钮从数据库下载 image/pdf 文件?

How to download image/pdf file from database using Gridview's linkbutton?

这是我的问题。我有一个用户控件,它将使用 gridview 中的 link 按钮下载二进制文件(图像、pdf 等)。

<asp:GridView Visible="true" ID="GridView1" runat="server" HeaderStyle-BackColor="#3AC0F2" HeaderStyle-ForeColor="White"
RowStyle-BackColor="#A1DCF2" AlternatingRowStyle-BackColor="White" AlternatingRowStyle-ForeColor="#000"
AutoGenerateColumns="false">
<Columns>
            <asp:BoundField DataField="ID" HeaderText="ID"/>
    <asp:BoundField DataField="FileName" HeaderText="File Name"/>
    <asp:TemplateField HeaderText="Action" ItemStyle-HorizontalAlign = "Center">
        <ItemTemplate>
         <asp:LinkButton ID="lnkDownload" runat="server" Text="Download" OnClick="DownloadFile" CommandArgument='<%# Eval("Id") %>'></asp:LinkButton>
         <asp:LinkButton ID="lnkDelete" runat="server" Text="Delete" OnClick="DeleteFile"  CommandArgument='<%# Eval("Id") %>'></asp:LinkButton>
        </ItemTemplate>
    </asp:TemplateField>
</Columns>
</asp:GridView>

隐藏代码:

Protected Sub DownloadFile(sender As Object, e As EventArgs)
    Dim id As Integer = Integer.Parse(TryCast(sender, LinkButton).CommandArgument)
    Dim bytes As Byte()
    Dim fileName As String, contentType As String

    Using con As New SqlConnection(DataSource.ConnectionString)
        Using cmd As New SqlCommand()
            cmd.CommandText = "select FileName, PatImage, FileType from DB where Id=@Id"
            cmd.Parameters.AddWithValue("@Id", id)
            cmd.Connection = con
            con.Open()
            Using sdr As SqlDataReader = cmd.ExecuteReader()
                sdr.Read()
                bytes = DirectCast(sdr("PatImage"), Byte())
                contentType = sdr("FileType").ToString()
                fileName = sdr("FileName").ToString()
            End Using
            con.Close()
        End Using
    End Using
    Response.Clear()
    Response.Buffer = True
    Response.Charset = ""
    Response.Cache.SetCacheability(HttpCacheability.NoCache)
    Response.ContentType = contentType
    Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName)
    Response.BinaryWrite(bytes)
    Response.Flush()
    Response.End()
End Sub

但是如果我的父 aspx 页面中有 UpdatePanel,这将不起作用。所以我用谷歌搜索,找到了答案;也就是在RowDataBound中放置一段代码:

Private Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
    Dim lb As LinkButton = TryCast(e.Row.FindControl("lnkDownload"), LinkButton )
    ScriptManager.GetCurrent(Me.Page).RegisterAsyncPostBackControl(lb)
End Sub

又出现了新的错误。那就是我无法使用 RowDataBound 中的代码在我的 GridView 中找到我的 linkButton。

所以我再次用谷歌搜索,发现我应该在我的 aspx 页面 ClientIDMode="AutoID" 中添加一个 属性。但这仅适用于框架 4.x。我不能那样做,因为我目前使用的是 3.5。我现在的情况有什么补救措施吗?

A已经找到答案,我只是更改了我的RowDataBound内容,参考代码:

Private Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
    If e.Row.RowType = DataControlRowType.DataRow Then
        Dim LButton = CType(e.Row.FindControl("lnkDownload"), System.Web.UI.WebControls.LinkButton)
        Dim scriptManager__1 = ToolkitScriptManager.GetCurrent(Me.Page)
        If scriptManager__1 IsNot Nothing Then
            scriptManager__1.RegisterPostBackControl(LButton)
        End If
    End If
End Sub