2013-03-27 2 views
2

Я выписал приведенный ниже код для обработки загрузки файла, который должен произойти в Gridview.RowCommand. Он работает в других местах, где я его использовал (linkbutton вне gridview или аналогичного элемента управления).Загрузить файл из 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 и в генерации ответа.

Любая помощь будет принята с благодарностью.

EDIT

Просто заметил эту ошибку в консоли Chrome:

Uncaught Sys.WebForms.PageRequestManagerParserErrorException: Sys.WebForms.PageRequestManagerParserErrorException: Сообщение, полученное от сервера не может быть проанализировано.

+0

слишком ситуационный? – Ortund

ответ

0

Я считаю, это связано с тем, что ваше приложение пытается использовать методы Response в 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 для создания файла, но вы можете использовать любой метод, который вам нужен.

+0

hmmm У меня была аналогичная проблема с linkButton в UpdatePanel, я просто настроил триггер ClientPostBack, чтобы справиться с этим, и это то, что я думал, что сделал в методе RowDataBound ... Я видел, как он работает один или два раза, хотя, но он не является надежным – Ortund

+0

В любом случае, я взял GridView из UpdatePanel, и он все еще бросает исключение ... – Ortund

+0

Вы пробовали это так, как я предложил? Чтобы создать отдельную страницу, выполните методы ответа? – jason

1

Так получилось, что, возможно, не самая лучшая практика (я откладываю более опытные разработчики, чтобы оспаривать это), мой код действительно работает.

По крайней мере, это сработало бы, если бы я использовал ToolkitScriptManager в отличие от ScriptManager при регистрации управления обратной передачи на моем RowDataBound подразделах:

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

Смежные вопросы