[Asp.net MVC]HandleErrorAttribute異常過濾器


摘要

在asp.net mvc中除了使用try...catch/finally來處理異常外,它提供了一種通過在Controller或者Action上添加特性的方式來處理異常。

HandleErrorAttribute

首先看一下該特性的定義

using System;

namespace System.Web.Mvc
{
    // 摘要: 
    //     表示一個特性,該特性用於處理由操作方法引發的異常。
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class HandleErrorAttribute : FilterAttribute, IExceptionFilter
    {
        // 摘要: 
        //     初始化 System.Web.Mvc.HandleErrorAttribute 類的新實例。
        public HandleErrorAttribute();

        // 摘要: 
        //     獲取或設置異常的類型。
        //
        // 返回結果: 
        //     異常的類型。
        public Type ExceptionType { get; set; }
        //
        // 摘要: 
        //     獲取或設置用於顯示異常信息的母版視圖。
        //
        // 返回結果: 
        //     母版視圖。
        public string Master { get; set; }
        //
        // 摘要: 
        //     獲取此特性的唯一標識符。
        //
        // 返回結果: 
        //     此特性的唯一標識符。
        public override object TypeId { get; }
        //
        // 摘要: 
        //     獲取或設置用於顯示異常信息的頁視圖。
        //
        // 返回結果: 
        //     頁視圖。
        public string View { get; set; }

        // 摘要: 
        //     在發生異常時調用。
        //
        // 參數: 
        //   filterContext:
        //     操作篩選器上下文。
        //
        // 異常: 
        //   System.ArgumentNullException:
        //     filterContext 參數為 null。
        public virtual void OnException(ExceptionContext filterContext);
    }
}

ExceptionType:屬性,相當於try catch(Exception)中的catch捕獲的異常類型,默認所有異常類型。

View:異常展示視圖,這個視圖需要在目錄Views/Shared/下。例如:

Order:該屬性是父類FilterAttribute的一個屬性,用來獲取或者設置執行操作篩選器的順序,默認-1,-1最先執行。

一個例子

在Index中直接拋出一個異常,我們現在需要做的就是通過HandlerError特性捕獲到這個異常,並且在視圖MyError上顯示詳細信息。

步驟1:添加特性

    public class UserController : Controller
    {
        // GET: User
        [HandleError(ExceptionType = typeof(Exception), View = "MyError")]
        public ActionResult Index()
        {
            throw new Exception("Sorry,threre is an error in your web server.");
        }

    }

步驟2:定義錯誤視圖,並通過@Model獲取異常對象並顯示錯誤信息。

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title></title>
</head>
<body>
    <div>
        @Model.Exception.GetType().Name<br />
        @Model.Exception.Message<br />
        @Model.ControllerName<br />
        @Model.ActionName<br />
        @Model.Exception.StackTrace<br />
    </div>
</body>
</html>

步驟3:注冊過濾器。

在App_Start目錄添加類FilterConfig

    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }
    }

在Global.asax中注冊

    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            GlobalConfiguration.Configure(WebApiConfig.Register);

        }
    }

步驟4:開啟自定義錯誤配置

  <system.web>
    ...
    <customErrors mode="On"></customErrors>
  </system.web>

測試

以上是采用ErrorHanlder的默認實現的方式,當然我們也可以自定義異常處理過濾器,方法很簡單繼承HandleErrorAttribute類,並且重寫OnException方法即可。

    /// <summary>
    /// 自定義異常過濾器
    /// </summary>
    public class CustomerErrorAttribute : HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
            //如果沒有處理該異常
            if (!filterContext.ExceptionHandled)
            {
                if (filterContext.Exception.Message.Contains("Sorry,threre is an error in your web server."))
                {
                    filterContext.ExceptionHandled = true;
                    filterContext.HttpContext.Response.Write("這是一個自定義異常處理過濾器");
                }
            }
        }
    }
    public class UserController : Controller
    {
        // GET: User
        [CustomerError(ExceptionType = typeof(Exception), View = "MyError")]
        public ActionResult Index()
        {
            throw new Exception("Sorry,threre is an error in your web server.");
        }

    }
    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
            filters.Add(new CustomerErrorAttribute());
        }
    }

測試

好了,自定義的異常處理過濾器已經起作用了。

需要注意在自定義處理異常過濾器的時候需要重寫OnException方法,該方法有一個ExceptionContext類型的參數。

    // 摘要: 
    //     提供使用 System.Web.Mvc.HandleErrorAttribute 類的上下文。
    public class ExceptionContext : ControllerContext
    {
        // 摘要: 
        //     初始化 System.Web.Mvc.ExceptionContext 類的新實例。
        public ExceptionContext();
        //
        // 摘要: 
        //     使用指定的控制器上下文針對指定的異常初始化 System.Web.Mvc.ExceptionContext 類的新實例。
        //
        // 參數: 
        //   controllerContext:
        //     控制器上下文。
        //
        //   exception:
        //     異常。
        //
        // 異常: 
        //   System.ArgumentNullException:
        //     exception 參數為 null。
        public ExceptionContext(ControllerContext controllerContext, Exception exception);

        // 摘要: 
        //     獲取或設置異常對象。
        //
        // 返回結果: 
        //     異常對象。
        public virtual Exception Exception { get; set; }
        //
        // 摘要: 
        //     獲取或設置一個值,該值指示是否已處理異常。
        //
        // 返回結果: 
        //     如果已處理異常,則為 true;否則為 false。
        public bool ExceptionHandled { get; set; }
        //
        // 摘要: 
        //     獲取或設置操作結果。
        //
        // 返回結果: 
        //     操作結果。
        public ActionResult Result { get; set; }
    }

需要注意的是,在自定義的異常過濾器中,如果對異常已經處理了,需要將ExceptionHandled設置為true,這樣其它的過濾器可以根據該值判斷當前異常是否已經處理過了。

通過異常處理過濾器的特性,你可以更方便的來處理action或者Controller中的異常,比try--catch用起來更方便,用這種方式,也可以簡化異常處理的代碼,少一些大塊兒大塊兒的異常處理代碼。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM