简体   繁体   中英

Redirecting to another page on Session_end event

I would like to auto-redirect to login page when session time outs.

In web.config file, i have the following code

<configuration>
    <system.web>
       <sessionState mode="InProc"  timeout="1"/>
    </system.web>
</configuration>

In Global.asax file-

protected void Session_End(object sender, EventArgs e)
{
    Response.Redirect("LoginPage.aspx");
}

But after time-out, i am receiving the following error:

HttpException was unhandled by user code.

Response is not available in this context.

Any clue to solve this issue?

Session_End is called when the session ends - normally 20 minutes after the last request (for example if browser is inactive or closed).
Since there is no request there is also no response.

I would recommend to do redirection in Application_AcquireRequestState if there is no active session. Remember to avoid loops by checking current url.

Edit: I'm no fan of .Nets built in authentication, Example goes in Global.asax :

    protected void Application_AcquireRequestState(object sender, EventArgs e)
    {
        try
        {
            string lcReqPath = Request.Path.ToLower();

            // Session is not stable in AcquireRequestState - Use Current.Session instead.
            System.Web.SessionState.HttpSessionState curSession = HttpContext.Current.Session;

            // If we do not have a OK Logon (remember Session["LogonOK"] = null; on logout, and set to true on logon.)
            //  and we are not already on loginpage, redirect.

            // note: on missing pages curSession is null, Test this without 'curSession == null || ' and catch exception.
            if (lcReqPath != "/loginpage.aspx" &&
                (curSession == null || curSession["LogonOK"] == null))
            {
                // Redirect nicely
                Context.Server.ClearError();
                Context.Response.AddHeader("Location", "/LoginPage.aspx");
                Context.Response.TrySkipIisCustomErrors = true;
                Context.Response.StatusCode = (int) System.Net.HttpStatusCode.Redirect;
                // End now end the current request so we dont leak.
                Context.Response.Output.Close();
                Context.Response.End();
                return;
            }
        }
        catch (Exception)
        {

            // todo: handle exceptions nicely!
        }
    }

If you are using something like FormsAuthentication for maintaining the security of your application, then this part (that part that you are trying to do) will be done for you. If FormsAuthentication discovers that a user's session has expired it will redirect him or her back to you login page.

Second, don't rely too much on Session_End because it will never trigger if you change session provider from InProc to SQLServer or other out of process provider.

You can use session property IsNewSession to detect whether it is session timeout or not.

The ASP.NET HttpSessionState class has IsNewSession() method that returns true if a new session was created for this request. The key to detecting a session timeout is to also look for the ASP.NET_SessionId cookie in the request.

Definitely I too agree that we should put the below code in some so called a custom BasePage, which is used by all pages, to implement this effectively.

override protected void OnInit(EventArgs e)
  {
       base.OnInit(e);   

if (Context.Session != null)
   {
if (Session.IsNewSession)
    {

     string CookieHeader = Request.Headers["Cookie"];
     if((CookieHeader!=null) && (CookieHeader.IndexOf("ASP.NET_SessionId") >= 0))
     {
      // redirect to any page you need to
      Response.Redirect("sessionTimeout.aspx");
     } 
   }
 }
}

check this link for more explanations if you want to put the above code in a base page class .

You should use Application_AcquireRequestState You'll find that Application_AuthenticateRequest no longer has a session context (or never had one). In my research into this I cam across this post which solved it for me. Thanks go to Waqas Raja.

asp.net: where to put code to redirect users without a session to the homepage?

I think you are getting "Response is not available in this context" because the user is not making a request to the server, and therefor you cannot provide it with a response. Try Server.Transfer instead.

The easiest way what I feel is to use Meta information and get the trick working. Consider we have a page WebPage.aspx add the below code in the the WebPage.aspx.cs file.

private void Page_Load(object sender, System.EventArgs e){      
    Response.AddHeader("Refresh",Convert.ToString((Session.Timeout * 60) + 5));      
    if(Session[“IsUserValid”].ToString()==””)              
    Server.Transfer(“Relogin.aspx”);
}

In the above code, The WebPage.aspx is refreshed after 5 seconds once the Session is expired. And in the page load the session is validated, as the session is no more valid. The page is redirected to the Re-Login page. Every post-back to the server will refresh the session and the same will be updated in the Meta information of the WebPage.aspx .

you can simply do the following in web.config

<configuration>
<system.web>
<sessionState mode="InProc"  timeout="1" loginurl="destinationurl"/>
</system.web>
</configuration>

Since, we can't redirect from Session_End as no response/redirect is present there.By using this you will be redirected to destinationurl when session will timeout.Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM