Asp.NET ReportViewer “report execution has expired or cannot be found” error when using session state service or SQL Server session state
We encountered an error like:
ReportServerException: The report execution
x5pl2245iwvvq055khsxzlj5 has expired or cannot be found.
(rsExecutionNotFound)]
Microsoft.Reporting.WebForms.ServerReportSoapProxy.OnSoapException(SoapException
e) +72
Microsoft.Reporting.WebForms.Internal.Soap.ReportingServices2005.Execution.ProxyMethodInvocation.Execute(RSExecutionConnection
connection, ProxyMethod`1 initialMethod, ProxyMethod`1
retryMethod) +428
Microsoft.Reporting.WebForms.Internal.Soap.ReportingServices2005.Execution.RSExecutionConnection.GetExecutionInfo()
+133
Microsoft.Reporting.WebForms.ServerReport.EnsureExecutionSession()
+197
Microsoft.Reporting.WebForms.ServerReport.LoadViewState(Object
viewStateObj) +256
Microsoft.Reporting.WebForms.ServerReport..ctor(SerializationInfo
info, StreamingContext context) +355
[TargetInvocationException: Exception has been thrown by the
target of an invocation.]
System.RuntimeMethodHandle._SerializationInvoke(Object
target, SignatureStruct& declaringTypeSig,
SerializationInfo info, StreamingContext context) +0
System.Reflection.RuntimeConstructorInfo.SerializationInvoke(Object
target, SerializationInfo info, StreamingContext context)
+108
System.Runtime.Serialization.ObjectManager.CompleteISerializableObject(Object
obj, SerializationInfo info, StreamingContext context) +273
System.Runtime.Serialization.ObjectManager.FixupSpecialObject(ObjectHolder
holder) +49
System.Runtime.Serialization.ObjectManager.DoFixups() +223
System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler
handler, __BinaryParser serParser, Boolean fCheck, Boolean
isCrossAppDomain, IMethodCallMessage methodCallMessage) +188
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream
serializationStream, HeaderHandler handler, Boolean fCheck,
Boolean isCrossAppDomain, IMethodCallMessage
methodCallMessage) +203
System.Web.Util.AltSerialization.ReadValueFromStream(BinaryReader
reader) +788
System.Web.SessionState.SessionStateItemCollection.ReadValueFromStreamWithAssert()
+55
System.Web.SessionState.SessionStateItemCollection.DeserializeItem(String
name, Boolean check) +281
System.Web.SessionState.SessionStateItemCollection.DeserializeItem(Int32
index) +110
System.Web.SessionState.SessionStateItemCollection.get_Item(Int32
index) +17
System.Web.SessionState.HttpSessionStateContainer.get_Item(Int32
index) +13
System.Web.Util.AspCompatApplicationStep.OnPageStartSessionObjects()
+71
System.Web.UI.Page.ProcessRequestMain(Boolean
includeStagesBeforeAsyncPoint, Boolean
includeStagesAfterAsyncPoint) +2065
This error occurs long after the report viewer page has closed. It occurs to any asp.net page in the application, rendering the entire application unusable until the user gets a new session.
The cause of the problem is that the ReportViewer uses session state. When a page retrieves session from any out-of-state session, the session variable of type Microsoft.Reporting.WebForms.ReportHierarchy is deserialized from the session storage. The deserialization could cause the object to connect to the report server when the report is no longer available.
The solution is simple but not pretty. We need to clean up the session variable when the report viewer page is closed. One way is to add some Javascript to the page to handle the window.onunload event. In the event handler, call a web service to clean up the session variable. The name of the session variable appears to be randomly generated. So we need to loop through the session variable to find a variable of the type Microsoft.Reporting.WebForms.ReportHierarchy. Microsoft has implemented pinging between the report viewer and the report server to keep the report alive on the server when the report viewer is up; I hope they will go one step further to take care of this problem.