ASP.NET MVC 過濾器(五)

 

ASP.NET MVC 過濾器(五)

前言

上篇對了行爲過濾器的使用作了講解,若是在控制器行爲的執行中遇到了異常怎麼辦呢?不要緊,還好框架給咱們提供了異常過濾器,在本篇中將會對異常過濾器的使用作一個大概的講解。html

 

ASP.NET MVC過濾器

  • 過濾器在系統框架中的總體對象模型web

  • IAuthorizationFilter受權認證過濾器的執行過程編程

  • 使用IAuthorizationFilter過濾器c#

  • IActionFilter行爲過濾器的執行過程服務器

  • 自定義實現IActionFilter行爲過濾器框架

  • 異常過濾器的使用ide

 

異常過濾器的使用

在使用異常過濾器以前,咱們要看一下它們的結構:佈局

      public interface IExceptionFilter
    {
        void OnException(ExceptionContext filterContext);
    }

IExceptionFilter接口類型是異常過濾器必須實現的接口,固然了還有FilterAttribute特性類型這是必需要實現的。在此不對FilterAttribute特性類型作什麼介紹。this

咱們看一下IExceptionFilter接口類型中的OnException()方法中的有個ExceptionContext類型的參數,ExceptionContext類型是遺產過濾器參數上下文對象,繼承自ControllerContext類型,這種編程模式在MVC框架中隨處可見了不作多的解釋了。spa

在MVC框架中給咱們默認的提供了一個異常過濾器類型:

代碼1-1

      public class HandleErrorAttribute : FilterAttribute, IExceptionFilter
    {
        // 摘要:
        //     初始化 System.Web.Mvc.HandleErrorAttribute 類的新實例。
        public HandleErrorAttribute();
        public Type ExceptionType { get; set; }
        public string Master { get; set; }
        public string View { get; set; }
        public virtual void OnException(ExceptionContext filterContext);
    }

ExceptionType屬性對應要處理的異常類型,若是設置某種異常類型值那麼異常過濾器只會針對這個類型的異常來進行作處理,默認值是處理全部異常類型。

Master屬性則是設置在處理異常以後所要顯示視圖所用的佈局。

View屬性是設置在處理異常以後所要顯示的視圖名稱。

來看示例:

示例仍是接着上個篇幅的示例,沒看過前篇的朋友也沒什麼影響很簡單的示例。

代碼1-2

        public ActionResult Index()
        {
            int i = 0;
            int j = 3 / i;
            return View(_DataStandard.GetProducts());   
        }

首先咱們在控制器的Index()方法中定義個錯誤處理,0是不能做爲除數的處理到這必須報異常的。運行的結果如圖1所示。

圖1

很明確的報出了異常的所在,這是咱們不但願的看見的,接下來咱們把異常過濾器給使用上:

代碼1-3

        [HandleError]
        public ActionResult Index()
        {
            int i = 0;
            int j = 3 / i;
            return View(_DataStandard.GetProducts());   
        }

這時你會發現運行的結果和圖1中所示的同樣,這是坑爹呢??!!!!固然不是咱們須要在Web.config文件的中的<system.web>節點下作相對應的配置才能夠,

代碼1-4

<customErrors  mode="On"" />

須要添加代碼1-4中的內容到system.web節點下,這是咱們再來看一下運行的結果圖。

圖2

爲何會顯示這個頁面,這跟HandleErrorAttribute類型中的OnException(ExceptionContext filterContext)方法默認實現有關係,它默認設置就是服務器錯誤信息,那咱們怎麼自定義的指定咱們想顯示的頁面,或者是看到咱們想詳細看到的錯誤信息呢?咱們再來重寫一下OnException()方法吧。

代碼1-5

public class MyCustomHandleErrorAttribute : HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }
            if (filterContext.Exception!=null)
            {
                Exception innerException = filterContext.Exception;
                if (!filterContext.ExceptionHandled)
                {
                    string controllerName = (string)filterContext.RouteData.Values["controller"];
                    string actionName = (string)filterContext.RouteData.Values["action"];
                    HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
                    ViewResult result = new ViewResult
                    {
                        ViewName = "Error",
                        MasterName = this.Master,
                        ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
                        TempData = filterContext.Controller.TempData
                    };
                    filterContext.Result = result;
                    filterContext.ExceptionHandled = true;
                }
            }
        }
    }

在上面的MyCustomHandleErrorAttribute類型實現中,咱們只須要關注ExceptionContext filterContext參數中的Result的設置,在代碼1-5中咱們指定了Error這個視圖,而且還實例化了HandleErrorInfo類型做爲視圖模型傳遞到視圖中,咱們如今要新建一個視圖,在當前控制器的文件夾下View/[controllername]/Error.cshtml新建這個視圖文件,而且選擇爲強類型視圖,類型則爲HandleErrorInfo類型,咱們看一下視圖的定義。

代碼1-6:

@model HandleErrorInfo
@{
    ViewBag.Title = "Error";
}
<h2>
    Error</h2>
<p>
    異常類型:<b>@Model.Exception.GetType().Name</b>
    異常所在控制器:<b>@Model.ControllerName</b>
    異常所在控制器行爲:<b>@Model.ActionName</b>
</p>
<p>
    詳細信息:<b>@Model.Exception.Message</b>
</p>

如今咱們修改一下代碼1-3中的所使用的過濾器,修改成咱們代碼1-5中定義的自定義類型,再看一下運行結果:

到這裏異常過濾器的基礎使用也就講解完畢了。還有一種結果過濾器就不作講解了,基礎結構和行爲過濾器近乎相同使用方式也是,使用一下便知其用法。

相關文章
相關標籤/搜索