天天看點

ASP.NET MVC 過濾器(五)

上篇對了行為過濾器的使用做了講解,如果在控制器行為的執行中遇到了異常怎麼辦呢?沒關系,還好架構給我們提供了異常過濾器,在本篇中将會對異常過濾器的使用做一個大概的講解。

ASP.NET MVC 過濾器(五)

前言

ASP.NET MVC過濾器

  • 過濾器在系統架構中的整體對象模型
  • IAuthorizationFilter授權認證過濾器的執行過程
  • 使用IAuthorizationFilter過濾器
  • IActionFilter行為過濾器的執行過程
  • 自定義實作IActionFilter行為過濾器
  • 異常過濾器的使用

在使用異常過濾器之前,我們要看一下它們的結構:

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

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

我們看一下IExceptionFilter接口類型中的OnException()方法中的有個ExceptionContext類型的參數,ExceptionContext類型是遺産過濾器參數上下文對象,繼承自ControllerContext類型,這種程式設計模式在MVC架構中随處可見了不做多的解釋了。

在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

ASP.NET MVC 過濾器(五)

很明确的報出了異常的所在,這是我們不希望的看見的,接下來我們把異常過濾器給使用上:

代碼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

ASP.NET MVC 過濾器(五)

為什麼會顯示這個頁面,這跟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中定義的自定義類型,再看一下運作結果:

ASP.NET MVC 過濾器(五)

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

作者:金源

出處:http://www.cnblogs.com/jin-yuan/

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面

繼續閱讀