I am using c# MVC 4 and have embedded a Report Viewer aspx page to render reports from SSRS. I am using Sql Server 2008R2, Microsoft.ReportViewer.WebForms version 11.0.
Firstly the issue I am facing,
I am using session variables within the project to hold values relative to the site. These have nothing to do with SSRS, for example UserId.
In the web.config I have
Note: The timeout is set ridiculously high for this testing scenario.
Simarlarly I have updated ConfigurationInfo in the ReportServer database for the key SessionTimeout to 60 (again ridiculous value to test with).
My ReportViewer code is as follows to open the :
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ReportViewer1.Reset();
string Reportpath = Request["ReportName"];
string ServerUserName = ConfigurationManager.AppSettings["ReportServerUser"];
string ServerPassword = ConfigurationManager.AppSettings["ReportServerPwd"];
string ReportServerDomain = ConfigurationManager.AppSettings["ReportServerDomain"];
string ReportsPath = ConfigurationManager.AppSettings["ReportsPath"];
ReportViewer1.ProcessingMode = ProcessingMode.Remote;
// Get report path from configuration file
ReportViewer1.ServerReport.ReportServerUrl = new Uri(ConfigurationManager.AppSettings["ReportServer"]);
ReportViewer1.ServerReport.ReportPath = String.Format(ReportsPath + "/" + Reportpath);
IReportServerCredentials irsc = new CustomReportCredentials(ServerUserName, ServerPassword, ReportServerDomain);
ReportViewer1.ServerReport.ReportServerCredentials = irsc;
ReportViewer1.ShowPrintButton = false;
#region Parameters for report
Microsoft.Reporting.WebForms.ReportParameter[] reportParameterCollection = new Microsoft.Reporting.WebForms.ReportParameter[1];
reportParameterCollection[0] = new Microsoft.Reporting.WebForms.ReportParameter();
reportParameterCollection[0].Name = "Example";
reportParameterCollection[0].Values.Add("Example");
ReportViewer1.ServerReport.SetParameters(reportParameterCollection);
#endregion Parameters for report
ReportViewer1.ServerReport.Refresh();
}
}
The issue I am facing
When I login, I have values set in the session. When I open a report, the report executes fine in under a second and displays on the page.
Behind the scenes, I've noticed a row gets inserted in the Report Server Temp DB with an expiration date of 1 minute later (with my config).
A session key gets added to my
HttpContext.Current.Session.Keys
At this point all is fine and I even close the report page.
At this point I wait a minute which would mean that the session expires in the ReportServerTempDB.
I then navigate to a page whose action uses HttpContext.Current.Session for a value. Again, this action has nothing to do with reports. However when it tries to retrieve the key I get the following error
Microsoft.Reporting.WebForms.ReportServerException: The report execution <key> has expired or cannot be found. (rsExecutionNotFound)
I have been Googling this and have not found a working solution for my problem as most people seem to have had this with long running reports where the report session timed out before the execution was complete.
Any ideas?
Please comment if any more info is needed and I'll update the question.
Thanks in advance
I ran into the same issue. It appears that when the objects that the ReportViewer puts in Session are accessed, they try to ping the report server. If the report has expired, a ReportServerException gets thrown, which is expected behavior when a user is still viewing an expired report, but not when they're no longer on that page.
Unfortunately, these Session entries don't get cleaned up after the user leaves the page containing the ReportViewer. And for some reason, accessing the list of keys in the Session will trigger the report server to be pinged, thus raising this exception on completely unrelated pages.
While we can't get the list of keys, one thing we do have access to is the number of entries in Session. Using this information, we can walk through each item in Session and determine if it's one of those associated with the ReportViewer, and remove it.
[WebMethod]
public static void RemoveReportFromSession()
{
var i = HttpContext.Current.Session.Count - 1;
while (i >= 0)
{
try
{
var obj = HttpContext.Current.Session[i];
if (obj != null && obj.GetType().ToString() == "Microsoft.Reporting.WebForms.ReportHierarchy")
HttpContext.Current.Session.RemoveAt(i);
}
catch (Exception)
{
HttpContext.Current.Session.RemoveAt(i);
}
i--;
}
}
The catch block helps to remove reports that have already expired (and thus throw an exception when accessed), while the type check in the if-statement will remove reports that have not yet expired.
I recommend calling this from the onunload event of the page that contains your ReportViewer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With