2013-10-17 68 views
2

我正在使用c#MVC 4並嵌入了報表查看器aspx頁來呈現來自SSRS的報告。我正在使用Sql Server 2008R2,Microsoft.ReportViewer.WebForms版本11.0。問題報告查看器和會話

首先我面對的問題,

我使用的是項目中的會話變量來保存相對於網站的值。這些與SSRS無關,例如UserId。

在web.config我有

注:超時設置高得離譜的這個測試場景。

Simarlarly我已經在ReportServer數據庫中將SessionTimeout關鍵字的ConfigurationInfo更新爲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(); 
      } 
     } 

我面對

當我登錄的問題,我已經在會話中設置的值。 當我打開報告時,報告在一秒鐘內就可以正常運行並顯示在頁面上。

在幕後,我注意到一行被插入報告服務器臨時數據庫中,過期日期爲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

嗯,你有沒有嘗試過使用ReportViewer.KeepSessionAlive屬性? –

+0

@DTs - 我已經試過了,但在幾次嘗試之中,我可能沒有做對 - 你能否詳細說明 – Kamal

回答

3

我遇到了同樣的問題。看起來,當ReportViewer放入Session的對象被訪問時,它們會嘗試ping報告服務器。如果報告已過期,則會拋出ReportServerException,這是在用戶仍在查看過期報告時的預期行爲,而不是在該頁面上不再存在時。

不幸的是,在用戶離開包含ReportViewer的頁面後,這些會話條目不會被清理乾淨。出於某種原因,訪問會話中的鍵列表將觸發報告服務器被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事件中調用它。