我已经写出以下代码来处理Gridview.RowCommand上应该发生的文件下载。它适用于我使用它的其他地方(在gridview或类似控件之外的linkbutton)。
此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例程以及Response的生成中。
非常感谢任何帮助。
编辑
刚刚在Chrome的控制台中发现了这个错误:
未捕获的Sys.WebForms.PageRequestManagerParserErrorException:Sys.WebForms.PageRequestManagerParserErrorException:无法解析从服务器收到的消息。
答案 0 :(得分: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
答案 1 :(得分:0)
我相信这是因为您的应用程序正在尝试在updatePanel中使用Response方法。这将失败有几个原因: 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来创建文件,但您可以使用您需要的任何方法。