我有以下情况:
Microsoft Report Viewer 2010用于在ASP.NET Web应用程序中以本地模式显示报表(.rdlc文件)。通过在ASPX页面后面的代码中分配数据源来提供报告数据。这是一个例子:
if(!IsPostBack){
ReportViewer1.Reset();
ReportDataSource reportDataSource = new ReportDataSource();
reportDataSource.Name = "DataContainerType";
reportDataSource.Value = DatasourceOnPage;
reportDataSource.DataSourceId = "DatasourceOnPageID";
reportDataSource.DataMember = "DataSourceView";
ReportViewer1.ProcessingMode = ProcessingMode.Local;
ReportViewer1.LocalReport.DisplayName = "ReportName";
ReportViewer1.LocalReport.ReportEmbeddedResource = "Reportfile.rdlc";
ReportViewer1.LocalReport.DataSources.Add(reportDataSource);
}
通常这很有效,我们收到的每份报告都很好。
当我打开页面直到工作进程回收,然后尝试刷新报表或在报表页面上进行任何类型的回发,我得到(未处理的)异常“ASP.NET会话已过期” 。
异常信息: 异常类型:AspNetSessionExpiredException 例外消息:死于ASP.NET-Sitzung ist abgelaufen oder konnte nicht gefunden> werden。 在Microsoft.Reporting.WebForms.ViewerDataOperation..ctor() 在Microsoft.Reporting.WebForms.HttpHandler.GetHandler(String operationType) 在Microsoft.Reporting.WebForms.HttpHandler.ProcessRequest(HttpContext context) at> System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionS> tep.Execute() 在System.Web.HttpApplication.ExecuteStep(IExecutionStep步,布尔&> completedSynchronously)
IIS设置为每天早上5点回收。我们在web.config中使用InProc设置,显然,会话丢失了。如果我正确理解ASP.NET行为,未处理的异常应该导致工作进程终止。当下一个请求到达时,应该有一个新的工作进程。
如果会话超时设置为低,则会导致相同的异常。这看起来很奇怪,因为根据我的阅读,报告查看器应该ping服务器以使会话保持活动状态。
我试图捕获异常,但在我在页面加载中访问它之前,它被抛出到ReportViewer控件内部。如果我取出IsPostBack,上面的代码仍然执行,但它没有效果。
我尝试使用状态服务器而不是在会话中保持会话,因此它不会丢失会话,但这会导致报表查看器出现其他错误。它似乎无法将其会话数据存储在状态服务器中。
环境是Windows Server 2003 .NET 4.0 Report Viewer 2010
我可以在哪里处理错误,没有工作进程终止,或者让报告使用stateserver?
答案 0 :(得分:1)
我现在通过使用从基页类派生的自定义页面来解决它。我现在检查会话是否是新的,然后重定向到同一页面,从而从头开始重新加载报告。
我还使用了一个脚本来保持会话处于活动状态,因为报表查看器本身并没有这样做。但由于我对会话检查感到满意,我禁用了它。
public class ReportPage: System.Web.UI.Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
#region check for lost session
if (Context.Session != null)
{
if (Session.IsNewSession)
{
string cookieHeader = Request.Headers["Cookie"];
if ((null != cookieHeader) && (cookieHeader.IndexOf("ASP.NET_SessionId") >= 0))
{
Response.Redirect(Request.Url.ToString());
}
}
}
#endregion check for lost session
#region generate keepsessionalive script
StringBuilder sb = new StringBuilder();
sb.Append("$(function () {setInterval(KeepSessionAlive, " + GetSessionTimeoutInMs() + ");");
sb.Append("});");
sb.Append("function KeepSessionAlive() {");
sb.Append(string.Format("$.post('{0}', null);", ResolveUrl("~/KeepSessionAlive.ashx")));
sb.Append("};");
// register on page
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "SessionKeepAlive", sb.ToString(), true);
#endregion generate keepsessionalive script
}
private int GetSessionTimeoutInMs()
{
return (this.Session.Timeout * 60000) - 10000;
}
}
keep-alive-script调用一个http处理程序(.ashx文件),每次调用它时都会触及会话(实际上不确定是否有必要)。这是记录:
public class KeepSessionAlive : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
context.Session["KeepSessionAlive"] = "KeepAlive!";
}
public bool IsReusable
{
get
{
return false;
}
}
}
答案 1 :(得分:0)
您是否尝试将工作进程数限制为1?
我遇到了同样的问题,为我解决的问题是A) setting a specfic time of day for recycle
(您已经拥有)和B) limit worker processes to max of 1 in app pool settings
。