Конкретный ErrorHandlerAttribute срабатывает при каждом исключении? - PullRequest
0 голосов
/ 27 февраля 2012

Вопрос:

Я хочу реализовать класс sessionAccess, который генерирует исключение «SessionExpired» при попытке получить доступ к сеансу с истекшим сроком действия.И я хочу показать специальную страницу для SessionExpired вместо YSOD.

Вот что у меня есть:В Global.asax.cs

MvcApplication : System.Web.HttpApplication
{

        // /96154/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


}

А это мой класс SessionAccess:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;


namespace WebApplications
{


    // /1856114/opredelit-kogda-seans-polzovatelya-istek
    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 

А затем в homecontroller я реализую это представление:

  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();
        }

Затем у меня есть SessionExpired.cshtml, который я вставил в Views\Shared

Теперь, несмотря на отключение пользовательской ошибки, я могу получить сообщение об ошибке SessionExpired.Он отлично работает для SessionExpiredException, но теперь проблема в том, что я получаю это исключение для ЛЮБОГО исключения (нулевая ссылка, исключение приложения и т. Д.)

Кто-нибудь может сказать, почему это так?Я бы предположил, что когда-либо попаду на эту страницу только с SessionExpiredException ...

Почему и с каждым другим исключением ????

По какой-то причине внутренняя работа фильтра кажетсябыть неисправным ...

1 Ответ

1 голос
/ 27 февраля 2012

Реализация по умолчанию OnException проверяет HandleErrorAttribute.ExceptionType Свойство и return s, если совпадения нет.Код из HandleErrorAttribute.OnException:

        if (!ExceptionType.IsInstanceOfType(exception)) {
            return;
        }

Поскольку вы переопределяете OnException, вы должны добавить эту проверку и к вашей реализации.

Вы можете скачать и проверить весь источник asp.net-mvc 3 в деталях, если вам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...