Как обработать исключение, истекшее в сеансе просмотра отчетов

У меня такая ситуация:

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 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) в> System.WebFormation.HcallApp .System.Web.HttpApplication.IExecutionS> tep.Execute () в System.Web.HttpApplication.ExecuteStep (шаг IExecutionStep, логическое значение &> завершено синхронно)

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

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

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

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

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

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


person Niels Ziegler    schedule 29.07.2010    source источник


Ответы (2)


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

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

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;
        }
    }
}
person Niels Ziegler    schedule 11.08.2010
comment
Почему вы публикуете закомментированный код? Пожалуйста, приложите некоторые усилия в своей презентации для других. - person leppie; 01.09.2011
comment
@NielsSchultz, я должен зарегистрировать этот обработчик в web.config, чтобы все заработало? - person Johnny_D; 03.04.2013

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

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

person VicarInATutu    schedule 03.08.2010
comment
Мы никогда не меняли количество рабочих процессов, оно по-прежнему равно 1. Теперь я проверил, является ли сеанс новым, а затем перезагрузил страницу. Жду результатов от тестовой системы, чтобы посмотреть, поможет ли. - person Niels Ziegler; 04.08.2010