views:

232

answers:

1

Given an ASP.NET 2.0 page with the following code in a button click event...

Protected Sub btnQuickRpt_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles btnQuickRpt.Click
  Dim uniqueReportId As String = GenerateQuickReport()

  ' Opens the report on page reload.
  ClientScript.RegisterStartupScript(Me.GetType(), "openReport", "window.open('Reports/" & uniqueReportId & ".pdf');", True)
End Sub

After clicking the button associated with this code the window.open() code is run when the page is reloaded properly. However, if after that, the user navigates to another URL and then clicks the browser's back button, the "window.open()" code happens again making the user's report pop back up, unexpectedly, in their face.

Based on suggestions from similar style threads, I've toyed around with setting the cacheability of the page, but no combination produced the expected result of returning to this page, without prompt and without the window.open() code executing again.

Does anyone have a suggestion on how to handle this situation?

+1  A: 

Instead of using a server button to generate the report before the window is opened, use client script in a button to open the window with a page that creates the report and returns it in the response.

Create a page (for example GenerateReport.aspx) that generates the report and returns it directly in the response stream. In the Page_Load method:

Dim uniqueReportId As String = GenerateQuickReport()
Response.Clear();
Response.ContentType = "application/pdf";
Response.WriteFile(Server.MapPath("Reports/" & uniqueReportId & ".pdf"));
Response.End();

Now you just open that page from a button:

<input type="button" value="gimme teh repport!" onclick="window.open('GenerateReport.aspx','_blank');"/>

You can use an http handler instead of a regular page, it fit's a little better for what you do, but I showed you how to do it with a regular page as that is probably more familiar.

If you can create the report in memory instead of as a file, you can return it using Response.BinaryWrite so that you don't have to create the files at all.

Guffa
That's a fantastic answer and I was able to implement it to prove that it worked.The the sake of completeness, lets say I *did* want to generate the report before the window is opened. I have some "generating" messages/notices on the parent page, and with this proposed solution those would be missed. The report can take up to 20 seconds to generate, and your solution leaves the user at a blank page just waiting for the report to show up. Would you have any other suggestions to keep it more inline with current behavior?
ckittel
Make another page to open first in the window, which has a client script that requests the PDF page to open in the same window (body onload="window.location.href='GenerateReport.aspx';"). The first page will be visible while the browser is waiting for the PDF to be generated.
Guffa
Yeah, I thought you would come back with that exact answer, which is perfectly legit. I probably should have been more clear, in that want the user to still be viewing the parent page while the report is generating. I don't want the other page to become available until the report is ready. What actually happens in my current situation is that the report, after done generating, pops up *under* the current page (in FF, IE, Chrome) -- focus on the parent page is never lost. Maybe this is all a pipe dream to keep this behavior and have the back button still operate the way I want it?
ckittel
It might be possible to get closer to what you want. The key is to start the process with script that is already available on the page instead of doing a postback to add the script to the page. You might be able ot AJAX to start the generation of the PDF, then open it when you get the response.
Guffa