Redirect to specific page after session expires (MVC4)
Asked Answered
N

3

15

C# MVC4 project: I want to redirect to a specific page when the session expires.

After some research, I added the following code to the Global.asax in my project:

protected void Session_End(object sender, EventArgs e)
{
     Response.Redirect("Home/Index");
}

When the session expires, it throws an exception at the line Response.Redirect("Home/Index"); saying The response is not available in this context

What's wrong here?

Necessitous answered 21/8, 2014 at 10:1 Comment(4)
you are using formsauthentication..???Housebreaking
@Exception, I'm not sure but I don't think soNecessitous
#24971455Decadence
Nobody has explained why this is happening. Unlike many of the other events in global.asax, the Session_End event doesn't happen in the context of a current request - it's an even that is sent to the application outside of the normal run time - therefore you cannot issue a redirect request. Typically this event is used to allow the application to clean-up resources from the just ended session. It would be hard to have it happen during a request as one of the first things a request does is activate the session.Faun
H
28

The easiest way in MVC is that In case of Session Expire, in every action you have to check its session and if it is null then redirect to Index page.

For this purpose you can make a custom attribute as shown :-

Here is the Class which overrides ActionFilterAttribute.

public class SessionExpireAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            HttpContext ctx = HttpContext.Current;
            // check  sessions here
            if( HttpContext.Current.Session["username"] == null ) 
            {
               filterContext.Result = new RedirectResult("~/Home/Index");
               return;
            }
            base.OnActionExecuting(filterContext);
        }
    }

Then in action just add this attribute as shown :

[SessionExpire]
public ActionResult Index()
{
     return Index();
}

Or Just add attribute only one time as :

[SessionExpire]
public class HomeController : Controller
{
  public ActionResult Index()
  {
     return Index();
  }
}
Housebreaking answered 21/8, 2014 at 10:42 Comment(13)
If you need to check this everywhere just add it to your list of global filters: GlobalFilters.Filters.Add(new SessionExpireFilterAttribute()); in Global.asax.cs. No need to add to every action.Salzman
@Necessitous there are two ways one that Exception posted and one i have shown you, no other way i think available in mvcDecadence
@EhsanSajjad...yes..but in your code we have to change the base controller in order to just check session ..in my opinion its good to make a custom filter instead and moreover if on some actions we want to skip checking session then it will create problems...Housebreaking
@EhsanSajjad and Exception, this is a good discussion and I believe a better solution is needed for this matter. My doubt is, isn't there a better way already?Necessitous
@chiapa...no above mentioned and ehsansajjad solution are a few available solutions in mvc... this is because of the architecture of mvc actually..Housebreaking
@chaipa you can implement you own way some solution but in asp.net there are two ways one custom action filter attribute and second create a base controller and inherit others from itDecadence
I have issue.OnActionExecuting() method call every times but when session expires it not call.Can you give me solution of that? Thanks in advance.Intricate
@Juhi..no this is not possible..there must be problem somewhere else...OnActionExecuting() method will be called everytime before action execute regardless of session.Housebreaking
How do you do this in MVC 6?Bavardage
i have the same problem as @Kartikeya. it works fine until the session actually expires, then it won't hit the attribute anymore.Tiberias
Thanks a lot, but not worked for me. I render partialview via AJAX and when session is ok, the code hits to this method and the page is loaded. But when expired there is no error on Console and no hit to this custom method. Any idea?Coagulase
@ClintEastwood...sorry for late reply..your case is somewhat different.. this will help you.Housebreaking
Can someone help me. I added GlobalFilters.Filters.Add(new SessionExpireFilterAttribute()); But how to exclude this filter on redirecting user to a specific action?Graces
S
0

This is some something new in MVC.



    Public class SessionAuthorizeAttribute : AuthorizeAttribute
    {
        Protected override void HandleUnauthorizeRequest( 
                                   AuthorizationContext filtercontext )
            { 
                filtercontext.Result = new RedirectResult("~/Login/Index");
            } 
    }


After apply this filter on your controller on those where you want to apply authorization.



    [SessionAuthorize]
    public class HomeController : Controller
    {
        // Something awesome here.
    }


Above SessionAuthorizeAttribute's HandleUnAuthorizeRequest function will only call once authorization is failed Instead of repeatedly check for authorization.

Regards MK

Skirmish answered 7/3, 2018 at 10:1 Comment(4)
Authorisation and Session are two different things, and can expire at different times - you can have your authorisation revoked while still having a valid session, and you can have a session timeout before your authentication token (and therefore authorisation) expires.Faun
Thanks for highlighting, But i am still not clear can you please provide an example.Skirmish
Sure: When a user visits your site, .net can issue a session token, typically valid for 20 minutes and reset every time they request a page. If that user then logs in, you will issue an authorisation token, with an expiry time, this can be longer or shorter than the session timeout. If it's longer, but the user doesn't visit any more pages then the session will timeout after twenty minutes, but the authorisation token is still valid and if the user returned to your site they would still be logged in (but would have a new session).Faun
The filter you are suggesting would only fire if the user was not logged in and trying to access a restricted page. The case the OP is using would be something like a search page or similar where the session has timed out and it's lost all the changes, so you need to start again because they weren't using query stringsFaun
S
0

create this action filter class

    class SessionExpireAttribute : ActionFilterAttribute {
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.HttpContext.Session["logged"] == null)
        {
            filterContext.Result = new RedirectResult("/Account/Login");
        }
        base.OnActionExecuted(filterContext);
    }

then use it in your class or method like bellow

[SessionExpireAttribute]
public class MyController : Controller
{
    ....
}
Sisely answered 24/5, 2019 at 12:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.