ReportViewer control fails with Sys.WebForms.PageRequestManagerServerErrorException: Failed to load viewstate.

Recently i was working on a very interesting scenario. Imagine you've have an ASP.NET web application that hosts ReportViewer web control.

The ReportViewer control pulls a Reporting Services 2008 R2 report. The report contains background images in report body, textbox etc along with DrillThrough actions. When the report is shown in the ReportViewer, there are still some background images getting rendered.  

This background operation is performed asynchronously with the help of streams and hence the report is still visible when the background images are still being rendered.

Before the ReportViewer completes rendering the background image streams, if you click on any of the drillthrough report link, it fails with the following exception.

Sys.WebForms.PageRequestManagerServerErrorException:
Failed to load viewstate. The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request. For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request.

In the Reporting services logs and HTTP logs for the corresponding time frame you would see the following,

HTTP:

09/07/2012 14:29:15 - 10.21.7.82 20480 servername POST /ReportServer/ReportExecution2005.asmx 401 569 0 1.1 servername - - -
09/07/2012 14:29:15 - 10.21.7.82 20480 servername POST /ReportServer/ReportExecution2005.asmx 401 622 0 1.1 servername - - -
09/07/2012 14:29:15 Userdetails 10.21.7.82 20480 servername POST /ReportServer/ReportExecution2005.asmx 500 2491 32 1.1 servername - - -
09/07/2012 14:29:15 - 10.21.7.82 20480 servername POST /ReportServer/ReportExecution2005.asmx 401 569 0 1.1 servername - - -
09/07/2012 14:29:15 - 10.21.7.82 20480 servername POST /ReportServer/ReportExecution2005.asmx 401 622 0 1.1 servername - - -
09/07/2012 14:29:15 Userdetails 10.21.7.82 20480 servername POST /ReportServer/ReportExecution2005.asmx 500 2491 31 1.1 servername - - -

Reporting Services Logs:

chunks!ReportServer_0-1!1238!09/07/2012-15:28:57:: v
VERBOSE: ### ReportSnapshot(7833434d-b2ad-4599-b265-7291dc11ae70) constructor of
existing snapshot.
library!ReportServer_0-1!1238!09/07/2012-15:28:57:: v
VERBOSE: Transaction
commit.
session!ReportServer_0-1!1238!09/07/2012-15:28:57:: v VERBOSE: Found
library!ReportServer_0-1!1238!09/07/2012-15:28:57:: e ERROR: Throwing
Microsoft.ReportingServices.Diagnostics.Utilities.StreamNotFoundException: ,
Microsoft.ReportingServices.Diagnostics.Utilities.StreamNotFoundException: The stream cannot be found. The stream identifier that is provided to an operation cannot be located in the report server database.;

But the issue doesn't happen when you view the report directly from Report manager / Report Server URL's and perform a DrillThrough operation.

Additionally, you'll have the below exception stack thrown by the ASP.NET application when the issue happens.

System.Web; TargetSite:Boolean
HandleError(System.Exception) ; Message:Exception of type 'System.Web.HttpUnhandledException' was thrown.;
InnerException:System.Web.HttpException (0x80004005): Failed to load viewstate. The control tree into which viewstate is being loaded must match the control
tree that was used to save viewstate during the previous request. For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request.
at System.Web.UI.Control.LoadViewStateRecursive(Object savedState) at
System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) at
System.Web.UI.Control.LoadViewStateRecursive(Object savedState) at
System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) at
System.Web.UI.Control.LoadViewStateRecursive(Object savedState) at
System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) at
System.Web.UI.Control.LoadViewStateRecursive(Object savedState) at
System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) at
System.Web.UI.Control.LoadViewStateRecursive(Object savedState) at
System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) at
System.Web.UI.Control.LoadViewStateRecursive(Object savedState) at
System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) at
System.Web.UI.Control.LoadViewStateRecursive(Object savedState) at
System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) at
System.Web.UI.Control.LoadViewStateRecursive(Object savedState) at
System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) at
System.Web.UI.Control.LoadViewStateRecursive(Object savedState) at
System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) at
System.Web.UI.Control.LoadViewStateRecursive(Object savedState) at
System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) at
System.Web.UI.Control.LoadViewStateRecursive(Object savedState) at
System.Web.UI.Page.LoadAllState() at
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint);StackTrace: at
System.Web.UI.Page.HandleError(Exception e) at
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) at
System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) at System.Web.UI.Page.ProcessRequest() at
System.Web.UI.Page.ProcessRequest(HttpContext context) at
System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)  

The reason behind why you see this behavior only from ReportViewer control and not from Report Manager is, As soon as you click on a drillthrough link, the page stops loading completely from Report Manager and Report Server reports, where in the ReportViewer WebForm continues to load the report after the drillthrough report is clicked.

How to FIX this issue?

1. Remove all the background images.

2. Force ReportViewer control not to use the web application session state by implementing the IReportServerConnection / IReportServerConnection2 interface in your application.

REF:

https://msdn.microsoft.com/en-us/library/microsoft.reporting.webforms.ireportserverconnection2.aspx
https://blogs.msdn.com/b/brianhartman/archive/2008/11/21/custom-credentials-in-the-report-viewer.aspx

https://msdn.microsoft.com/en-us/library/ms251661.aspx

Disabling session state (since these are server reports) allows the report to run faster. You will see a significant performance gain as well as not run into this issue.

HTH!

Selva.

[All the posts are AS-IS without any warranty]