我正在使用c#MVC 4并嵌入了一个Report Viewer aspx页面来呈现来自SSRS的报告。我使用的是Sql Server 2008R2,Microsoft.ReportViewer.WebForms版本11.0。
首先是我面临的问题,
我在项目中使用会话变量来保存相对于站点的值。这些与SSRS无关,例如UserId。
在web.config中我有
注意:对于此测试方案,超时设置得非常高。
Simarlarly我已经将ReportServer数据库中的ConfigurationInfo更新为关键SessionTimeout到60(再次测试的荒谬值)。
我的ReportViewer代码如下打开:
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();
}
}
我面临的问题
登录时,我在会话中设置了值。 当我打开报告时,报告会在一秒钟内正常执行并显示在页面上。
在幕后,我注意到在Report Server Temp DB中插入了一行,有效期为1分钟(使用我的配置)。
会话密钥被添加到我的
HttpContext.Current.Session.Keys
此时一切正常,我甚至关闭了报告页面。
此时我等待一分钟,这意味着会话在ReportServerTempDB中到期。
然后我导航到一个页面,其动作使用HttpContext.Current.Session作为值。同样,此操作与报告无关。但是,当它尝试检索密钥时,我收到以下错误
Microsoft.Reporting.WebForms.ReportServerException: The report execution <key> has expired or cannot be found. (rsExecutionNotFound)
我一直在谷歌搜索这个并没有为我的问题找到一个可行的解决方案,因为大多数人似乎已经有了长时间运行的报告,其中报告会话在执行完成之前超时。
有什么想法吗?
如果需要更多信息,请发表评论,我会更新问题。
提前致谢
答案 0 :(得分:2)
我遇到了同样的问题。看来,当访问ReportViewer放入Session的对象时,它们会尝试ping报表服务器。如果报告已过期,则抛出ReportServerException,这是用户仍在查看过期报告时的预期行为,而不是当它们不再在该页面上时。
不幸的是,在用户离开包含ReportViewer的页面后,这些Session条目不会被清除。由于某些原因,访问会话中的键列表将触发报表服务器被ping,从而在完全不相关的页面上引发此异常。
虽然我们无法获取密钥列表,但我们可以访问的一件事是Session中的条目数。使用此信息,我们可以遍历Session中的每个项目,并确定它是否与ReportViewer关联,并将其删除。
[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--;
}
}
catch块有助于删除已经过期的报告(因此在访问时抛出异常),而if语句中的类型检查将删除尚未过期的报告。
我建议从包含ReportViewer的页面的onunload事件中调用它。