Detecting Session Timeouts using a ASP.Net MVC Action Filter
Some time ago, I read an article on how to detect a session timeout in a ASP.Net Web forms application by placing some code in a Base Page. The code worked for me and you could read more about it here. In my last post I mentioned that Microsoft released a beta version of their MVC implementation of ASP.Net and since them, I have been playing around with it. But, as with Web forms, I still needed a way to detect a session timeout and perform an action when a timeout is detected. So, I decided to use the same code implemented in the original article and implement it into my MVC project. I decided to write a custom action filter and apply it to my controller actions where I need to ensure that my session was still active. Here is the code for my action filter.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Reflection;
namespace Web {
public class SessionExpireFilterAttribute : ActionFilterAttribute {
public override void OnActionExecuting( ActionExecutingContext filterContext ) {
HttpContext ctx = HttpContext.Current;
// check if session is supported
if ( ctx.Session != null ) {
// check if a new session id was generated
if ( ctx.Session.IsNewSession ) {
// If it says it is a new session, but an existing cookie exists, then it must
// have timed out
string sessionCookie = ctx.Request.Headers[ "Cookie" ];
if ( ( null != sessionCookie ) && ( sessionCookie.IndexOf ( "ASP.NET_SessionId" ) >= 0 ) ) {
ctx.Response.Redirect ( "~/Home/Login" );
}
}
}
base.OnActionExecuting ( filterContext );
}
}
}
And then, I would apply this filter to my Controller action methods like so:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
namespace Web.Controllers {
public class HomeController : Controller {
[SessionExpireFilter]
public ActionResult Index( ) {
// This method will not execute if our session has expired
// render Home Page
return View();
}
public ActionResult Login() {
// render Login page
return View();
}
}
}
The code is pretty straightforward. I just apply the [SessionExpireFilter] attribute on each method where I want to ensure that our session is still valid. If you have any questions, leave a comment under this post. Until next time…
Happy Coding!
Hey! I like your post “Detecting Session Timeouts using a ASP.Net MVC Action Filter” so well that I like to ask you whether I should translate into German and linking back. Greetings Engel
That’s fine. Sorry, I took so long to respond. You got caught in my SPAM filter.
This code is really helpful – thanks a lot.
Is there a reason why you used HttpContext.Current instead of filterContext.HttpContext? I’m implementing this and would like to make sure all my ducks are in a row, per se.
Thanks again.
I think using the filterContext.HttpContext would be better. At the time I made the posting, I actually looked to see if the filterContext had that property and either I overlooked it or it just wasn’t there in the Beta version. Nice catch. Thanks.
Nice post. I was just looking for that, thanks!
Cool! I was just looking for that too!!
Consider assigning a RedirectToRouteResult to filterContext.Result instead of manipulating the Response directly.
Thanks Tyrone Davis. Really very helpfull.
Problem when rendering the partialview.
I’m calling action from javascript, that action returns partial view and assigining the to some div.
If session expires, the page what we have mentioned in respone.redirect is returing as a partialview .
Please help me to solve this problem
[...] found the following blog post that claims to to solve the problem (this is similar to the first answer), but it doesn’t [...]
Hi!!! i’m having a problem with your method, when it executes it adds “(S(44krko45it3muqqdcsnh0445))” to my qerystring!!! wht’s happening????
thanks, Nicole.
Looks like you may have cookieless sessions turned on in your web.config. Make sure your sessionState element under the system.web section have cookieless=”false” set for that element.
I’m also having the same issue as Mr. from post #10. Since this all originates from an Ajax call, if a session times out the calling page loads the login screen into the existing page.
Is there an easy way to do a total redirect?
Hi,
Can I set the timeout value of session in MVC like I do in APS.net in web.config
This set the session time out to 10 hours in ASP.net but is not working for MVC
Regards,
No, there isn’t a way to do that on the redirect. Instead for an ajax call, you need to pass a value back to it and let the resulting ajax onsuccess handler do a javascript redirect
You could handle:
var isAjax = ctx.Request.IsAjaxRequest();
And then load a partial view login, that then redirects back to the login page?
[...] used the blog post made by Tyrone Davis to get me started. In my scenario, I am assuming [...]
Thanks for the article, I hope you dont mind but I borrowed your code. I also extended it a bit to handle return urls and made it testable with Rhino Mock.
http://cbertolasio.wordpress.com/2010/11/27/using-an-actionfilter-to-redirect-to-login-when-session-expires/
Not a problem Cedrick. Glad I was able to get you started on this. Will check out your blog from time to time.
[...] en la creación de una nueva página base de la cual deben heredar luego todas nuestras páginas. – Detecting Session Timeouts using ASP.Net MVC Action Filter: propone el uso de un action filter para poder luego asignar un atributo del tipo [...]
if ( ctx.Session != null ) {
}
Even after time i get the ctx.Session to null. so my redirect loop does not get execute. What could be the fix?
Not to start a flame war but ASP or Silverlight?
The Breathalyser Game
21st Birthday Ideas
It depends on the project and whether or now you would like to have a “rich” user interface. That is my view anyways. I’m a web developer so I like to keep things as close to HTML and javascript as possible.
Thanks for info
How can I achieve this inside a Base Controller so all of my controller actions gets this behavior and I don’t have to repeat?
Hi
Thx for the article. I have included the SessionExpireFilterAttribute and registered this actionfilter in Global.asax. But the problem is it is working only for [Httppost] methods, but not working for Get methods in mvc3.
Very nice post.
But will it redirect a user to “Home/Login” in this case:
Dialog with lets say five sites. 5th site calls “Session.Abandon();”
Situation: user “walks” through dialog, ends in 5th site, Abandon() is called, but user navigates with the browser(!) back button back to the fourth site. Is the user in this szenario redirected to “Home/Login”?
I dont thik so, because ” if ( ctx.Session.IsNewSession )” isnt true, because we didnt create a new session. Or?
[...] am using code for session timeout (code comes from this link). This code generally works fine, except if user has waited long enough to hit IIS Idletime [...]
I know this post is rather dated by now, but couldn’t this be accomplished simply by using Forms Authentication, and setting the
loginUrlto where you want to be redirected when you timeout? Am I missing something here?Hi, will this code automatically redirect you if your session has expired or when i try to navigate around only then it redirects.
It will redirect when you try to navigate. There is nothing running in the background checking for the session to end and forcing a redirect.
Yes and no. Yes, if you decide to set the timeout of the Forms Authentication ticket to expire the same time as your Session timeout. It post addressed Session expiration instead of Forms Authentication ticket expiration.
Hi, I got the same problem that was mentioned above,
“Problem when rendering the partialview.
I’m calling action from javascript, that action returns partial view and assigining the to some div.
If session expires, the page what we have mentioned in respone.redirect is returing as a partialview .”
How can I used this solution using partial views?