asp.net: где разместить код для перенаправления пользователей без сеанса на домашнюю страницу? - PullRequest
6 голосов
/ 04 февраля 2011

У меня есть веб-приложение с множеством страниц, и большинству из них требуются некоторые переменные сеанса для работы.

Я хочу добавить защитный код в свое приложение.где лучше всего разместить что-нибудь вроде:

if (Session.Count == 0){
                Response.Redirect("~/default.aspx");
}

РЕДАКТИРОВАТЬ: как проверить, является ли текущая страница defult.aspx?

Ответы [ 5 ]

16 голосов
/ 04 февраля 2011

Довольно сложно, да, к счастью, это решено.

Вам необходимо реализовать Application_PreRequestHandlerExecute in Global.asax

вот код

    /// <summary>
    /// The event occurs just after Initialization of Session, and before Page_Init event
    /// </summary>
    protected void Application_PreRequestHandlerExecute(Object sender, EventArgs e)
    {
        // here it checks if session is reuired, as
        // .aspx requires session, and session should be available there
        // .jpg, or .css doesn't require session so session will be null
        // as .jpg, or .css are also http request in any case
        // even if you implemented URL Rewritter, or custom IHttp Module
        if (Context.Handler is IRequiresSessionState
               || Context.Handler is IReadOnlySessionState)
        {
            // here is your actual code
            // check if session is new one
            // or any of your logic
            if (Session.IsNewSession
                || Session.Count < 1)
            {
                // for instance your login page is default.aspx
                // it should not be redirected if,
                // if the request is for login page (i.e. default.aspx)
                if (!Context.Request.Url.AbsoluteUri.ToLower().Contains("/default.aspx"))
                {
                    // redirect to your login page
                    Context.Response.Redirect("~/default.aspx");
                }
            }
        }
    }

Редактировать 1: Объяснение и заключение

Как один из парней рассказал о жизненном цикле приложений ASP.NET .

Происходит множество событий.

На самом деле события в Global.asax возникают в следующей последовательности

  1. Validate Request // выглядит просто внутренним механизмом
  2. Выполнить сопоставление URL // выглядит просто внутренним механизмом

  3. Вызовите событие BeginRequest.

  4. Вызовите событие AuthenticateRequest.
  5. Вызовите событие PostAuthenticateRequest.
  6. Вызовите событие AuthorizeRequest.
  7. Вызовите событие PostAuthorizeRequest.
  8. Вызовите событие ResolveRequestCache.
  9. Вызовите событие PostResolveRequestCache.
  10. Просто выбирает класс, который реализовал IHttpHandler для приложения // выглядит просто внутренним механизмом
  11. Вызовите событие PostMapRequestHandler.
  12. Вызовите событие AcquireRequestState. непосредственно перед вызовом этого события asp.net загружает состояние как Session
  13. Вызовите событие PostAcquireRequestState.
  14. Вызовите событие PreRequestHandlerExecute.
  15. вызов метода ProcessRequest

Вывод: Все события до AcquireRequestState не имеют объекта Session, поскольку Session не загружается ASP.Net, поэтому любое событие из * "AcquireRequestState ** событие дает объект Session, поэтому эта проблема решается. Однако некоторые проверки необходимы, как я уже упоминал в коде выше

1 голос
/ 04 февраля 2011

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

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

1 голос
/ 04 февраля 2011

Один из методов заключается в том, чтобы иметь базовый класс страницы, который выполняет эту проверку для Page_Init.Другим способом было бы отодвинуть идею @K Иванова, поместив ее в Global.asax.Хотя сеанс недоступен во время Application_BeginRequest, он должен быть доступен в методе Application_AcquireRequestState.Для нестандартных веб-запросов это должно обеспечить доступ к сеансу для выполнения того, что вы хотите.

1 голос
/ 04 февраля 2011

Будьте осторожны с Session.Count == 0, потому что такие вещи, как Session_ID, неявно хранятся в сессии.

Предпочтительно искать что-то вроде (Session["UserName"] == null), где Session["UserName"] - это место, где вы явно храните что-топользователя.

Кроме этого, Global.asax является лучшим местом ( жизненный цикл приложения ASP.NET ).

ТАКЖЕ ,Вы должны ввести проверку, что вы не в настоящее время на ~ / default.aspx, потому что в противном случае у вас будет бесконечный цикл.

1 голос
/ 04 февраля 2011

в Application_BeginRequest из Global.asax

, чтобы суммировать идеи, которые мы имеем:

protected void Application_AcquireRequestState(object sender, EventArgs e)
{
    if ((Session.Count == 0) &&
       !(Request.Url.AbsolutePath.EndsWith("default.aspx",
         StringComparison.InvariantCultureIgnoreCase)))
    {
        Response.Redirect("~/default.aspx");
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...