Reports Never Stop Loading With VS 2010

I’ve received a number of questions from people who have run into problems after upgrading their web application from VS 2008 to VS 2010.  Once upgraded, the report viewer shows the loading indicator indefinitely - the report never loads.  So what happened?

In an earlier post, I talked about the changes we made to AsyncRendering.  Asynchronous rendering no longer renders the report content in an iframe.  Instead, it uses ASP.Net AJAX to perform an asynchronous postback to get the report data.  In most of the cases I’ve seen, this change is at the heart of the problem.

With the iframe model, the report data was retrieved through the report viewer’s HTTP handler.  This request is distinct from a request to the ASPX page itself that contains the report viewer control.  The communication between the browser and the web front end would be something like this:

  1. Browser makes a GET request to the ASPX page to get the page content and a loading indicator for the report
  2. Browser makes a GET request to the HTTP handler to get the HTML for the report (this is the iframe content)
  3. Browser makes GET requests to the HTTP handler to get all the images in the report

But with VS 2010, there are no more frames.  Instead, we use ASP.Net postbacks to render the report.  The new communication sequence is:

  1. Browser makes a GET request to the ASPX page to get the page content and a loading indicator for the report.
  2. Browser makes a POST request to the ASPX page to get the HTML for the report (this content is in an UpdatePanel).
  3. Browser makes GET requests to the HTTP handler to get all the images in the report

In step 2, previously only the ReportViewer code would run to get the report content.  But now the request to get the report content runs the ASP.Net page, including any code you have placed in the page.

Why does this matter?  In the cases I’ve seen in the forums and on Connect, code was added to the load event of the page that altered the state of the report viewer.   The most common example I’ve seen is user code calling SetParameters in the load event, though there are several methods and properties that will trigger this.  Changing the parameter values tells the ReportViewer that it needs to restart report processing.  Effectively, it tells the viewer to return to step 1 – put the loading indicator in the browser and restart report processing.  If you do this during every postback, the viewer never successfully completes step 2.  It just goes into an infinite loop.

Calling methods like SetParameters isn’t cheap.  Each call triggers a round trip to the report server.  So it’s a call you want to minimize anyway.  By only calling SetParameters during the initial GET request or only when parameter values have actually changed, you can improve the performance of your application and break the loop.  A simple check of IsPostBack before calling SetParameters is usually sufficient.