Как обработать исключение истекшего сеанса просмотра отчетов - PullRequest
3 голосов
/ 29 июля 2010

У меня следующая ситуация:

Microsoft Report Viewer 2010 используется для отображения отчетов (RDLC-файлов) в локальном режиме в веб-приложении ASP.NET.Данные отчета предоставляются путем назначения источника данных в коде за страницей 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 Сообщение об исключении: Die ASP.NET-Sitzung is abgelaufen oder konnte nicht gefunden> werden.в Microsoft.Reporting.WebForms.ViewerDataOperation..ctor () в Microsoft.Reporting.WebForms.HttpHandler.GetHandler (String operationType) в Microsoft.Reporting.WebForms.HttpHandler.ProcessRequest (контекст HttpContext) в> System.Web.Exp..System.Web.HttpApplication.IExecutionS> tep.Execute () в System.Web.HttpApplication.ExecuteStep (шаг IExecutionStep, Boolean &> closedSynchronously)

IIS настроен на перезагрузку каждое утро в 5 часов утра. Мыиспользуйте настройку InProc в web.config, поэтому очевидно, что сеанс потерян.Если я правильно понимаю поведение ASP.NET, необработанное исключение должно привести к завершению рабочего процесса.Должен быть новый рабочий процесс, когда приходит следующий запрос.

Если настройка времени ожидания сеанса мала, это вызывает то же исключение.Это кажется странным, потому что из того, что я прочитал, средство просмотра отчетов должно пропинговать сервер, чтобы поддержать сеанс.

Я пытался перехватить исключение, но оно выдается где-то внутри элемента управления ReportViewer, прежде чем я доберусь додоступ к нему при загрузке страницы.Приведенный выше код все еще выполняется, если я уберу IsPostBack, но это не имеет никакого эффекта.

Я попытался использовать сервер состояний вместо сохранения сеанса в процессе, чтобы он не потерял свой сеанс, но это приводит к другим ошибкам в средстве просмотра отчетов.Казалось, что он не может сохранить свои данные сеанса на сервере состояний.

Среда - Windows Server 2003 .NET 4.0 Report Viewer 2010

Где можно обработать ошибку,без прерывания рабочего процесса или получения отчета для использования сервера состояний?

Ответы [ 2 ]

1 голос
/ 11 августа 2010

Теперь я решил это, используя пользовательскую страницу, основанную на классе базовой страницы. Теперь я проверяю, является ли сеанс новым, затем перенаправляю на ту же страницу, перезагружая отчет с нуля.

Я также использовал сценарий, чтобы поддержать сеанс, поскольку средство просмотра отчетов не делает это само по себе. Но так как я удовлетворен проверкой сеанса, я отключил ее.

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 вызывает обработчик http (файл .ashx), который касается сеанса каждый раз, когда он вызывается (на самом деле не уверен, если это необходимо). Вот для справки:

 public class KeepSessionAlive : IHttpHandler, IRequiresSessionState
{

    public void ProcessRequest(HttpContext context)
    {
        context.Session["KeepSessionAlive"] = "KeepAlive!";
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}
0 голосов
/ 03 августа 2010

Вы пытались ограничить число рабочих процессов до 1?

У меня возникла та же проблема, и для меня она была исправлена: A) setting a specfic time of day for recycle (которая у вас уже есть) и B) limit worker processes to max of 1 in app pool settings.

...