mvc原始碼解讀(14)-mvc四大過濾器之ExceptionFilter
這一章我們主要來講異常過濾器ExceptionFilter
,廢話不多說,mvc3
中預設的異常過濾器特性類是HandleErrorAttribute
,該類的主要主要成員有:
public Type ExceptionType
{
get;set
}
public string View
{
get
{
if (string.IsNullOrEmpty(this._view))
{
return "Error";
}
return this._view;
}
set
{
this._view = value;
}
}
public virtual void OnException(ExceptionContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
if (!filterContext.IsChildAction && (!filterContext.ExceptionHandled && filterContext.HttpContext.IsCustomErrorEnabled))
{
Exception innerException = filterContext.Exception;
if ((new HttpException(null, innerException).GetHttpCode() == 500) && this.ExceptionType.IsInstanceOfType(innerException))
{
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 = this.View,
MasterName = this.Master,
ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
TempData = filterContext.Controller.TempData
};
filterContext.Result = result;
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = 500;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
}
}
其中ExceptionType
表示異常的型別,預設是所有異常的基類Exception
,表示會處理所有的標準異常。View
屬性表示丟擲異常時該顯示什麼樣的檢視給使用者,如果每沒有自定義的View
,系統預設輸出的是字串“Error
”,OnException
方法用於系統出現異常時呼叫的方法,我們看紅色程式碼這兩句:
filterContext.ExceptionHandled = true;
new HttpException(null, innerException).GetHttpCode() == 500
ExceptionHandled
屬性是布林值,表示該丟擲的異常是否被處理了,true
表示已經被處理,false
表示沒有被處理,如果被處理過的異常,一定要將ExceptionHandled
設定為true
,防止父類或者更高階別的異常處理重複的處理改異常。而HttpCode=500表示會優先呼叫MVC
框架自己的處理異常,然後將ExceptionHandled
設定為true
。我們先來看一段demo:
我們自定義一個異常類過濾器MyExceptionFilter
,繼承自HandleErrorAttribute
並重寫了OnException
方法,實現方法如下:
public class MyExceptionFilter : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
if (!filterContext.ExceptionHandled && filterContext.Exception is DivideByZeroException)
{
filterContext.Result = new RedirectResult("/MyException/ErrorView");
filterContext.ExceptionHandled = true;
}
base.OnException(filterContext);
}
}
我們建立一個MVC3
的專案,建立一個MyException
控制器,具體程式碼如下:
[MyExceptionFilter]
public ActionResult Index()
{
int firstNumber = 10;
int secondNumber = 0;
int c = firstNumber / secondNumber;
return View();
}
public ActionResult ErrorView()
{
return View();
}
ErrorView
具體程式碼如下:
@{ Layout = null; }
<!DOCTYPE html>
<html> <head><title>ErrorView</title> </head> <body><div>
<p>這是一個異常頁面哦~~~~~</p>
</div> </body> </html>
執行結果如下:
我們可以看到,在Index
中出現異常的時候,執行了OnException
方法,並將使用者的請求轉到了我們自定義的錯誤頁面,同時標記改異常已經處理過了,如果上文我們說到過,若是每個Controller
都要貼上這個異常標籤,會很麻煩,因此我們可以在全域性檔案檔案註冊一個全域性的異常過濾器,具體如下:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
//filters.Add(new MyTestResultFiter() { FilterMessage="標誌全域性過濾器"});
filters.Add(new MyExceptionFilter());
//全域性的異常過濾器
}
,同時在配置檔案中設定i如下:
<system.web>
<customErrors mode="On"></customErrors>
</system.web>
這是一種情況,我們來看另外一種情況,我們自己在try-catch
中處理該異常,會有什麼結果呢,我們將Index
裡面的方法稍作修改如下:
[MyExceptionFilter]
public ActionResult Index()
{
try
{
int firstNumber = 10;
int secondNumber = 0;
int c = firstNumber / secondNumber;
}
catch (DivideByZeroException ex)
{
HttpContext.Response.Write(ex.Message.ToString());
}
return View();
}
對應的index的View
如下:
@{ Layout = null; }
<!DOCTYPE html>
<html><head><title>Index</title> </head> <body><div>
<p>這個是我自己try-Catch到的異常哦~~~</p></div></body></html>
執行結果如下:
我們可以看到,這一次他並沒有執行OnException
方法,異常直接被Catch
住了。try-Catch
和mvc
內建的異常處理器到底有什麼樣的關係?望可以得到解釋~~
相關文章
- mvc原始碼解讀(11)-mvc四大過濾器之AuthorizationFilterMVC原始碼過濾器Filter
- mvc原始碼解讀(12)-mvc四大過濾器之ActionFilterMVC原始碼過濾器Filter
- mvc原始碼解讀(13)-MVC四大過濾器之ResultFilterMVC原始碼過濾器Filter
- ASP.Net MVC過濾器ASP.NETMVC過濾器
- zanphp原始碼解讀 – MVC說起PHP原始碼MVC
- spring-MVC原始碼解讀(一)SpringMVC原始碼
- Nodejs Nestjs 路程 之 異常過濾器ExceptionfilterNodeJS過濾器ExceptionFilter
- Vue原始碼閱讀--過濾器Vue原始碼過濾器
- 【ASP.NET Core】MVC過濾器:執行流程ASP.NETMVC過濾器
- 【ASP.NET Core】MVC過濾器:常見用法ASP.NETMVC過濾器
- MVC使用異常過濾器處理異常MVC過濾器
- Spring MVC 啟動過程原始碼分析SpringMVC原始碼
- MVC配置原理-原始碼MVC原始碼
- 說一說MVC的Authentication過濾(四)MVC
- .Net MVC中定義全域性過濾器及在Action中排除全域性過濾器MVC過濾器
- 精盡Spring MVC原始碼分析 - HandlerMapping 元件(二)之 HandlerInterceptor 攔截器SpringMVC原始碼APP元件
- 瀑布式DEBUG Spring MVC原始碼SpringMVC原始碼
- 分析MVC5原始碼,並實現一個ASP.MVCMVC原始碼
- 跟我一起學.NetCore之MVC過濾器,這篇看完走路可以仰著頭走NetCoreMVC過濾器
- Servlet過濾器原始碼分析Servlet過濾器原始碼
- asp.net mvc中的使用者登入驗證過濾器ASP.NETMVC過濾器
- 精盡Spring MVC原始碼分析 - HandlerMapping 元件(一)之 AbstractHandlerMappingSpringMVC原始碼APP元件
- 精盡Spring MVC原始碼分析 - HandlerAdapter 元件(一)之 HandlerAdapterSpringMVC原始碼APT元件
- 精盡Spring MVC原始碼分析 - HandlerAdapter 元件(五)之 HttpMessageConverterSpringMVC原始碼APT元件HTTP
- 精盡Spring MVC原始碼分析 - HandlerAdapter 元件(四)之 HandlerMethodReturnValueHandlerSpringMVC原始碼APT元件
- 精盡Spring MVC原始碼分析 - HandlerAdapter 元件(二)之 ServletInvocableHandlerMethodSpringMVC原始碼APT元件Servlet
- 精盡Spring MVC原始碼分析 - HandlerAdapter 元件(三)之 HandlerMethodArgumentResolverSpringMVC原始碼APT元件
- 精盡Spring MVC原始碼分析 - HandlerMapping 元件(三)之 AbstractHandlerMethodMappingSpringMVC原始碼APP元件
- 精盡Spring MVC原始碼分析 - HandlerMapping 元件(四)之 AbstractUrlHandlerMappingSpringMVC原始碼APP元件
- Spring Security系列之核心過濾器原始碼分析(四)Spring過濾器原始碼
- Python之MVCPythonMVC
- DRF之過濾類原始碼分析原始碼
- 編寫Spring MVC控制器的14個技巧SpringMVC
- Spring MVC原始碼(一) ----- 啟動過程與元件初始化SpringMVC原始碼元件
- 精盡Spring MVC原始碼分析 - ViewResolver 元件SpringMVC原始碼View元件
- 精盡Spring MVC原始碼分析 - RequestToViewNameTranslator 元件SpringMVC原始碼View元件
- 精盡Spring MVC原始碼分析 - LocaleResolver 元件SpringMVC原始碼元件
- 精盡Spring MVC原始碼分析 - HandlerExceptionResolver 元件SpringMVC原始碼Exception元件