Display dynamically created pdf embedded in browser (IE9) - asp.net

I am trying to display a dynamically created PDF (Byte()) loading the default viewer int he client browser. The following code works with all browsers except the microsoft ones consistently. IE9 Wants to run MSXML 3.0 SP11 in response to the page. Here is the code generating the page:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim pdfData() As Byte
'load PDF Data
If pdfData.Length < 1 Then
Response.Write("ERROR - No data")
Response.End()
Return
End If
Response.Clear()
Response.AddHeader("Content-Disposition", "inline;filename=newcomp.PDF")
Response.AddHeader("Content-Length", pdfData.Length.ToString())
Response.AddHeader("Pragma", "no-cache")
Response.ContentType ="application/pdf"
Response.BinaryWrite(pdfData)
Response.Flush()
HttpContext.Current.ApplicationInstance.CompleteRequest()
End Sub
I call the page like this: http://localhost/DisplayPdf.aspx?newcomp.pdf
You can try it yourself with this link: http://www.netvaluecentral.com/DisplayPdf.aspx?newcomp.pdf
Any ideas?

Related

Server.Execute() executes click handler again after calling asp file

I'm trying to generate a PDF using Winnovative Tools. In my click handler which fires after clicking on the "Print PDF button", I have the code below.
I expect control to resume to the printPDF_Click sub routine after calling Server.Execute() but instead it calls the printPDF_Click sub routine from scratch which causes a loop because Server.Execute() will be called again and so on.
It works as expected when I set preserveForm as False but then I lose my form data and the point is retaining it.
Private Sub printPDF_Click(sender As Object, e As EventArgs) Handles printPDF.Click
Dim outTextWriter As IO.TextWriter = New IO.StringWriter()
Server.Execute("Default_v3.aspx?isWinnovative=true", outTextWriter)
Dim baseUrl As String = HttpContext.Current.Request.Url.AbsoluteUri
Dim htmlStringToConvert As String = outTextWriter.ToString()
Dim downloadBytes As Byte() = PdfHelper.CreatePdf(htmlStringToConvert, baseUrl)
Dim response As HttpResponse = HttpContext.Current.Response
response.Clear()
response.AddHeader("Content-Type", "binary/octet-stream")
response.AddHeader("Content-Disposition", ("attachment; filename=" + (
"Rendered.pdf" + ("; size=" + downloadBytes.Length.ToString))))
response.Flush()
response.BinaryWrite(downloadBytes)
response.Flush()
response.End()
End Sub

The file format and extension doesn't match excel while downloading from .net website

I have created an ASP.net website with the back end code in Vb I have generated a button to save the contents in an excel file but when Excel tries to open the file I get the following message.
* Format and extension of 'FileName.xls' don't match. The file could be corrupted or unsafe. Unless you trust its source, don't open it. Do you want to open it anyway?
I am attaching my aspx.vb code
Protected Sub Button3_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button3.Click
Response.Clear()
Response.AddHeader("content-disposition", "attachment;filename=FileName.xls")
Response.Charset = ""
Response.ContentType = "application/vnd.xls"
Dim stringWrite As New System.IO.StringWriter()
Dim htmlWrite As System.Web.UI.HtmlTextWriter = New HtmlTextWriter(stringWrite)
GridView5.RenderControl(htmlWrite)
Response.Write(stringWrite.ToString())
Response.[End]()
End Sub

asp.net can't continue after response.binarywrite

I have the following code which successfully writes a pdf to the client. The problem is that I can't get any code after this to execute. It's the last step of a wizard, and despite putting this in the ActiveStepChanged handler, it never makes it to the confirmation/final page.
Response.Clear()
Response.ContentType = Nothing
Response.AddHeader("content-disposition", "attachment; filename=" & FileName)
Response.BinaryWrite(data)
Response.Flush()
Basically, there's a checkbox that the user checks if they want to download the file when they hit the Finish button. I don't want to have a separate button to download the file because users have been known to get confused and think that by pressing the download button that they've completed the necessary steps and never complete their application (we're talking about non computer literate users here). So it all works, except it doesn't make it to the confirmation step when they select that option.
How can I ensure that processing continues after downloading the file?
The best way is to write this code in a HttpHandler and call Response.End after Response.Flush.
I figured this one out myself. Basically, I placed the response.binarywrite code (listed in op) in the code behind of its own empty webform. I then call then use the javascript openwindow function in ScriptManager.RegisterClientScriptBlock to open it.
Code in original page:
Me.Session("PrintApplication") = data
Me.Session("PrintApplicationFileName") = FileName
ScriptManager.RegisterClientScriptBlock(Me, Me.GetType, "PrintReport", "window.open('PrintApplication.aspx');", True)
Code in PrintApplication.aspx:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Me.Session("PrintApplicationFileName") <> Nothing Then
Dim data As Byte() = Me.Session("PrintApplication")
Dim FileName As String = Me.Session("PrintApplicationFileName")
Me.Session("PrintApplication") = Nothing
Me.Session("PrintApplicationFileName") = Nothing
Response.Clear()
Response.ContentType = Nothing
Response.AddHeader("content-disposition", "attachment; filename=" & FileName)
Response.BinaryWrite(data)
Response.Flush()
Response.End()
End If
End Sub
Works perfectly

System.OutOfMemoryException when exporting GridView to Excel

I have a sub that exports a ASP Gridview to excel, it works fine, however, when there are a large amount of rows I get this error:
Exception of type 'System.OutOfMemoryException' was thrown.
Any ideas how to solve this? Here is my export to excel sub:
Protected Sub btnExportMonthlyUK_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnExportMonth.Click
Dim title As String
title = "MonthlyReportUK"
Response.Clear()
Response.AddHeader("content-disposition", String.Format("attachment;filename={0}.xls", title))
Response.Charset = ""
Response.ContentType = "application/vnd.xls"
Response.ContentEncoding = Encoding.Unicode
Response.BinaryWrite(Encoding.Unicode.GetPreamble())
Dim strWr As New StringWriter()
Dim HtmlWr As New HtmlTextWriter(strWr)
monthlyReportsIE.AllowPaging = False
monthlyReportsIE.DataBind()
monthlyReportsIE.RenderControl(HtmlWr)
Response.Write(strWr.ToString())
Response.End()
End Sub
You can try rendering the control directly to the output stream by using a StreamWriter and avoid creating a large string in memory. You can also try setting Response.Buffer to False and the server will send the output to the client directly as it is processed.
Protected Sub btnExportMonthlyUK_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnExportMonth.Click
Dim title As String
title = "MonthlyReportUK"
Response.Clear()
Response.AddHeader("content-disposition", String.Format("attachment;filename={0}.xls", title))
Response.Charset = ""
Response.ContentType = "application/vnd.xls"
Response.ContentEncoding = Encoding.Unicode
Response.BinaryWrite(Encoding.Unicode.GetPreamble())
Response.Buffer = False
monthlyReportsIE.AllowPaging = False
monthlyReportsIE.DataBind()
Using strWr As new StreamWriter(response.OutputStream)
Using htmlWr As new HtmlTextWriter(strWr)
monthlyReportsIE.RenderControl(htmlWr)
End Using
End Using
Response.End()
End Sub
If this answer is not valid in your case, then you should consider an external library to do the job, because exporting large Excel files as HTML is memory consuming.
Check this sample about how to export the datatable of gridview.

Response.write and ASP.NET controls

Please see the code below:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Response.Write("<table><tr><td>some text</td></tr></table>")
Response.Flush()
Threading.Thread.Sleep(3000)
Response.Write("<table><tr><td>some text</td></tr></table>")
Response.Flush()
Threading.Thread.Sleep(3000)
Response.Write("<table><tr><td>some text</td></tr></table>")
Response.Flush()
Threading.Thread.Sleep(3000)
Response.Write("<table><tr><td>some text</td></tr></table>")
Response.Flush()
Threading.Thread.Sleep(3000)
End Sub
The code works as I would expect i.e. a HTML table is generated and written to the screen, then after three seconds another table is generated and added to the screen etc.
I have a webpage that dynamically adds x number of tables (http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.table%28v=vs.110%29.aspx) to a webpage. However, Response.Flush does not seem to work. I have created the simple code below to explain the problem:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Dim Table1 As New Table
Dim r As New TableRow()
Dim c As New TableCell()
c.Text = "Test 1"
r.Cells.Add(c)
Table1.Rows.Add(r)
Response.Flush()
Threading.Thread.Sleep(3000)
Dim Table2 As New Table
Dim r2 As New TableRow()
Dim c2 As New TableCell()
c.Text = "Test 2"
r.Cells.Add(c)
Table1.Rows.Add(r)
End Sub
Is it possible to flush table1 to the client, then wait a few seconds then flush table2 or do you have to write a string to response.write?
To use Response.Flush in that way you need to output all the HTML code yourself using Response.Write.
You can't use web controls as they are not rendered until the page is complete. The web controls only exist as objects until the Page_Render stage where the entire page is rendered as HTML code and then sent to the browser.

Resources