【问题标题】:Download file from gridview rowcommand从 gridview 行命令下载文件
【发布时间】:2013-03-27 13:26:17
【问题描述】:

我编写了以下代码来处理应该在 Gridview.RowCommand 上发生的文件下载。它适用于我使用过的其他地方(gridview 或类似控件之外的链接按钮)。

此 Gridview 位于 UpdatePanel 内。

Protected Sub gvBikeInsurance_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles gvBikeInsurance.RowDataBound
    If e.Row.RowType = DataControlRowType.DataRow Then
        Dim ibtnExportToPDF As ImageButton = TryCast(e.Row.FindControl("ibtnExportToPDF"), ImageButton)
        ScriptManager.GetCurrent(Me).RegisterPostBackControl(ibtnExportToPDF)

        Dim btnDelete As LinkButton = TryCast(e.Row.Cells(e.Row.Cells.Count - 1).Controls(0), LinkButton)
        btnDelete.OnClientClick = "return confirm('Are you sure you want to delete this insurance item');"
    End If
End Sub

Protected Sub gvBikeInsurance_RowCommand(sender As Object, e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles gvBikeInsurance.RowCommand

    Select Case e.CommandName
        Case "PDFExport"
            exportPolicy(e.CommandArgument)
    End Select
End Sub

Private Sub exportPolicy(ByVal BikeInsuranceID As Integer)
    Dim args As New List(Of MySqlParameter)
    args.Add(New MySqlParameter("xbikeinsuranceid", MySqlDbType.Int32))
    args(args.Count - 1).Value = BikeInsuranceID

    Dim dr As MySqlDataReader = db.execDB("InsuranceFiles_Select", CommandType.StoredProcedure, args.ToArray(), GeneralFunctions.ReturnType.DataReader, False)

    Dim output() As Byte
    If dr.HasRows Then
        dr.Read()
        output = dr("filedata")
    End If
    dr.Close()

    Dim outputstr As String = Text.Encoding.ASCII.GetString(output)

    Response.Clear()
    Response.ClearHeaders()
    Response.ContentType = "application/pdf"
    Response.AddHeader("Content-Disposition", String.Format("attachment;filename={0}", "Policy Schedule.pdf"))

    HtmlToPdf.ConvertHtml(outputstr, Response.OutputStream)

    Response.End()
End Sub

系统从表单中捕获用户信息并用它编写 HTML。此 HTML 用于创建一个 PDF 文件,然后应该自动下载该文件。

问题是文件似乎没有下载,除非我通过调试器逐步运行它。标准执行只显示 UpdateProgress 内容,该内容会在一段时间后消失。

这里的代码有什么问题吗?尤其是在 RowDataBound 和 RowCommand 例程以及响应的生成中。

任何帮助将不胜感激。

编辑

刚刚在 Chrome 的控制台中发现了这个错误:

未捕获的 Sys.WebForms.PageRequestManagerParserErrorException:Sys.WebForms.PageRequestManagerParserErrorException:无法解析从服务器接收到的消息。

【问题讨论】:

    标签: asp.net vb.net download response


    【解决方案1】:

    事实证明,虽然可能不是最佳实践(我让经验丰富的开发人员对此提出异议),但我的代码确实有效。

    如果我在 RowDataBound 子上注册回发控件时使用的是 ToolkitScriptManager 而不是 ScriptManager,至少它会起作用:

    Protected Sub gvBikeInsurance_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles gvBikeInsurance.RowDataBound
        If e.Row.RowType = DataControlRowType.DataRow Then
            Dim ibtnExportToPDF As ImageButton = TryCast(e.Row.FindControl("ibtnExportToPDF"), ImageButton)
            ToolkitScriptManager.GetCurrent(Me).RegisterPostBackControl(ibtnExportToPDF)
    
            Dim btnDelete As LinkButton = TryCast(e.Row.Cells(e.Row.Cells.Count - 1).Controls(0), LinkButton)
            btnDelete.OnClientClick = "return confirm('Are you sure you want to delete this insurance item');"
        End If
    End Sub
    

    当您将它添加到您的页面/母版页时,您将决定使用哪个。请注意,如果您使用 AJAX Control Tookit .NET 3.5 中的控件,则必须使用 ToolkitScriptManager

    供参考,ScriptManager and ToolkitScriptManager的区别

    【讨论】:

      【解决方案2】:

      我相信这是因为您的应用程序试图在 updatePanel 中使用响应方法。这将失败有几个原因: http://weblogs.asp.net/leftslipper/archive/2007/02/26/sys-webforms-pagerequestmanagerparsererrorexception-what-it-is-and-how-to-avoid-it.aspx

      最值得注意的是,在您的示例中,这是由于更新面板造成的。

      相反,您可以让更新面板打开一个开始下载的页面,如下所示:

      Private Sub exportPolicy(ByVal BikeInsuranceID As Integer)
      
       'store what you need to create the file in session variables
       Session("fileName") = foundAttachment.FileName
       Session("documentType") = foundAttachment.DocumentType
       Session("byteArray") = byteArray
      
      
      
      'this registers a Javascipt function with the page.  You need to create a page Called "Download.aspx"
       ScriptManager.RegisterStartupScript(Me.UpdatePanel1, Me.GetType, "ShowPopup", "window.open('DownloadPage.aspx');", True)
      End Sub
      

      现在,在您的 DownloadPage.Aspx 页面中:

       Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
          If (Not IsPostBack) Then
              Dim fileName As String = Session("fileName")
              Dim docType As String = Session("documentType")
              Dim byteArray() As Byte = Session("byteArray")
      
      
              If (byteArray.Length > 0) Then
                  Dim ms As MemoryStream = New MemoryStream(byteArray)
                  Dim sw As StreamWriter = New StreamWriter(ms)
      
                  Response.Clear()
                  Response.AddHeader("Content-Disposition", "attachment; filename=" & fileName)
                  Response.ContentType = docType
                  Response.BinaryWrite(byteArray)
                  Response.End()
                  Response.Flush()
              End If
      
          End If
      End Sub
      

      在我的示例中,我使用 byteArrays 创建文件,但您可以使用所需的任何方法。

      【讨论】:

      • hmmm 我在 UpdatePanel 中的 linkBut​​ton 也有类似的问题,我只是设置了一个 ClientPostBack 触发器来处理这个问题,这就是我认为我在 RowDataBound 方法中所做的事情。 . 我已经看到它按原样工作了一两次,但它并不可靠
      • 无论如何,我已经将 GridView 从 UpdatePanel 中取出,但它仍然抛出异常......
      • 您按照我建议的方式尝试了吗?有一个单独的页面做响应方法?
      • 其实ScriptManager和ToolkitScriptManager是有区别的。更改我上面的代码以使用 ToolkitScriptManager 解决了问题
      猜你喜欢
      • 2018-12-16
      • 2021-02-20
      • 1970-01-01
      • 1970-01-01
      • 2022-12-10
      • 1970-01-01
      • 1970-01-01
      • 2010-12-09
      • 1970-01-01
      相关资源
      最近更新 更多