报表查看器和会话问题

本文关键字:会话 问题 报表 | 更新日期: 2023-09-27 18:35:41

我正在使用 c# MVC 4,并嵌入了一个报表查看器 aspx 页来呈现来自 SSRS 的报表。我正在使用 Sql Server 2008R2,Microsoft.ReportViewer.WebForms 版本 11.0。

首先是我面临的问题,

我在项目中使用会话变量来保存相对于站点的值。这些与 SSRS 无关,例如 UserId。

在 web.config 中,我有

注意:对于此测试方案,超时设置得高得离谱。

西马拉利,我已经将报表服务器数据库中的键 SessionTimeout 的配置信息更新为 60(再次使用荒谬的值进行测试)。

我的报表查看器代码如下,用于打开:

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();
            }
        }

我面临的问题

登录时,我在会话中设置了值。当我打开报表时,报表在一秒钟内即可正常执行并显示在页面上。

在后台,我注意到在报表服务器临时数据库中插入了一行,过期日期为 1 分钟后(使用我的配置)。

会话密钥已添加到我的

HttpContext.Current.Session.Keys

在这一点上一切都很好,我什至关闭了报告页面。

此时,我等待一分钟,这意味着会话在报表服务器TempDB中过期。

然后,我导航到一个页面,该页面的操作使用 HttpContext.Current.Session 作为值。同样,此操作与报告无关。但是,当它尝试检索密钥时,我收到以下错误

Microsoft.Reporting.WebForms.ReportServerException: The report execution <key> has expired or cannot be found. (rsExecutionNotFound)

我一直在谷歌上搜索这个,但没有找到解决我的问题的有效解决方案,因为大多数人似乎在长时间运行的报告中遇到过这种情况,其中报告会话在执行完成之前超时。

有什么想法吗?

如果需要更多信息,请发表评论,我会更新问题。

提前致谢

报表查看器和会话问题

我遇到了同样的问题。似乎在访问报表查看器放入会话中的对象时,它们会尝试对报表服务器执行 ping 操作。如果报表已过期,则会引发 ReportServerException,当用户仍在查看过期的报表时,这是预期行为,但当用户不再位于该页上时则不是。

遗憾的是,在用户离开包含报表查看器的页面后,不会清理这些会话条目。出于某种原因,访问会话中的键列表将触发对报表服务器执行 ping 操作,从而在完全不相关的页面上引发此异常。

虽然我们无法获取密钥列表,但我们可以访问的一件事是会话中的条目数。使用此信息,我们可以遍历 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 语句中的类型检查将删除尚未过期的报告。

我建议从包含报表查看器的页面的 onunload 事件调用它。

关于帕特里克·布朗的答案需要考虑的事情:在删除 try 块中的会话值之前请三思而后行,可能属于其他浏览器窗口/选项卡。