Question:
I want to implement a sessionAccess class, which throws a “SessionExpired”-Exception when an attempt to access an expired session is made.
And I want to show a special page for SessionExpired, instead of the YSOD.
This is what I have:
In Global.asax.cs
MvcApplication : System.Web.HttpApplication
{
// http://stackoverflow.com/questions/183316/asp-net-mvc-handleerror
public class SessionExpiredErrorHandlerAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext exceptionContext)
{
//Logger.Error(exceptionContext.Exception.Message,exceptionContext.Exception);
//exceptionContext.ExceptionHandled = true;
// http://blog.dantup.com/2009/04/aspnet-mvc-handleerror-attribute-custom.html
UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
string messagePageUrl = url.Action("SessionExpired", "Home").ToString();
System.Web.HttpContext.Current.Response.Redirect(messagePageUrl, true);
base.OnException(exceptionContext);
} // End Sub OnException
} // End Class MyErrorHandlerAttribute
// http://freshbrewedcode.com/jonathancreamer/2011/11/29/global-handleerrorattribute-in-asp-net-mvc3/
// <customErrors mode="On" />
// <customErrors mode="RemoteOnlyy" />
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new SessionExpiredErrorHandlerAttribute
{
ExceptionType = typeof(WebApplications.SessionAccess.SessionExpiredException),
View = "@btw WHY is anything I write here ignored ???, and why TF can one only set the view, and not the controller as well @",
Order = 2
});
} // End Sub RegisterGlobalFilters
}
And this is my SessionAccess class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace WebApplications
{
// http://stackoverflow.com/questions/2950064/detect-when-a-users-session-has-exipred
public class SessionAccess
{
// LoginFailedException
public class SessionExpiredException : System.Exception
{
// The default constructor needs to be defined
// explicitly now since it would be gone otherwise.
public SessionExpiredException()
{
}
public SessionExpiredException(string strKey)
: base("Session \"" + strKey + "\" expired, or was never set.")
{
}
}
static System.Web.SessionState.HttpSessionState Session
{
get
{
if (System.Web.HttpContext.Current == null)
throw new ApplicationException("No Http Context, No Session to Get!");
return System.Web.HttpContext.Current.Session;
}
}
public static T Get<T>(string key)
{
System.Nullable<bool> SessionExists = (System.Nullable<bool>) Session["__sys_" + key + "_hasBeenSet"];
if (SessionExists == null)
throw new SessionExpiredException(key);
if (Session[key] == null)
return default(T);
else
return (T)Session[key];
}
public static void Set<T>(string key, T value)
{
Session["__sys_" + key + "_hasBeenSet"] = true;
Session[key] = value;
}
} // End Class SessionAccess
} // End Namespace WebApplications
And then, in the homecontroller, I implement this view:
public ActionResult TestPage(string id)
{
/*
WebApplications.SessionAccess.Set<string>("foo", "test");
string str = WebApplications.SessionAccess.Get<string>("foo");
Console.WriteLine(str);
Session.Clear();
Session.Abandon();
str = WebApplications.SessionAccess.Get<string>("foo");
Console.WriteLine(str);
*/
throw new Exception("bogus");
return View();
}
Then I have a SessionExpired.cshtml, which I put into Views\Shared
Now, despite custom-error off, I can get the SessionExpired error message.
It works fine for SessionExpiredException, but the problem now is, that I get this exception for ANY exception (null reference, applicationexception, etc…)
Can anybody tell my why this is ?
I would have assumed I only ever get to this page on a SessionExpiredException…
Why on every other exception as well ????
For some reason, the inner workings of filter seems to be malfunctioning…
Default implementation of
OnExceptionchecks HandleErrorAttribute.ExceptionType Property andreturns if there’s no match. Code fromHandleErrorAttribute.OnException:As you override
OnException, you should add this check to your implementation too.You can download and inspect whole source of asp.net-mvc 3 in details if you need to.