2

Gridview.RowCommand で発生するファイルのダウンロードを処理するために、以下のコードを書きました。私が使用した他の場所(グリッドビューまたは同様のコントロールの外側のリンクボタン)で機能します。

この 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 のコンソールで次のエラーを見つけました。

Uncaught Sys.WebForms.PageRequestManagerParserErrorException: Sys.WebForms.PageRequestManagerParserErrorException: サーバーから受信したメッセージを解析できませんでした。

4

2 に答える 2

1

結局のところ、ベスト プラクティスではない可能性がありますが (これについては、経験豊富な開発者に異議を唱えてもらいます)、私のコードは機能します。

RowDataBound サブシステムにポストバック コントロールを登録するときに、 aToolkitScriptManagerではなくa を使用していれば、少なくとも機能していたはずです。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 Toolkit .NET 3.5 のコントロールを使用している場合は、ToolkitScriptManager

参考までに、ScriptManager と ToolkitScriptManagerの違い

于 2013-04-15T09:30:21.893 に答える
0

これは、アプリケーションが updatePanel で Response メソッドを使用しようとしていることが原因だと思います。これはいくつかの理由で失敗し ます。

最も注目すべきは、あなたの例では、更新パネルによるものです。

代わりに、次のように、更新パネルでダウンロードを開始するページを開くことができます。

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 を使用してファイルを作成していますが、必要な方法は何でも使用できます。

于 2013-03-27T15:19:46.553 に答える