原文鏈接 https://blog.csdn.net/pan_junbiao/article/details/84523935
比如 ActionFilter中ActionExecutingContext filterContext可以拿到請求中的上下文。可以拿到請求action的名字controller的名字。和要請求的action 的上的標簽等。filterContext.Result 可以給響應復制。截斷請求,從而執行當前返回結果。
MVC Filter是典型的AOP(面向切面編程)應用,在ASP.NET MVC中的4個過濾器類型,如下:
過濾器類型 | 接口 | 默認實現 | 描述 |
---|---|---|---|
Action | IActionFilter | ActionFilterAttribute | 在動作方法之前及之后運行 |
Result | IResultFilter | ActionFilterAttribute | 在動作結果被執行之前和之后運行 |
AuthorizationFilter | IAuthorizationFilter | AuthorizeAttribute | 首先運行,在任何其它過濾器或動作方法之前 |
Exception | IExceptionFilter | HandleErrorAttribute | 只在另一個過濾器、動作方法、動作結果彈出異常時運行 |
但是默認實現它們的過濾器只有三種,分別是ActionFilter(方法),Authorize(授權),HandleError(錯誤處理)。
1、Action過濾器
在ASP.NET MVC中創建MvcApp項目,創建文件夾Filter,然后新建類MyActionFilterAttribute(為了遵循默認的約定,名稱以Attribute結尾),繼承自ActionFilterAttribute類。ActionFilterAttribute類有如下4個方法。
-
using System;
-
-
namespace
System.Web.Mvc
-
{
-
[
AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
-
public
abstract
class
ActionFilterAttribute :
FilterAttribute,
IActionFilter,
IResultFilter
-
{
-
-
protected ActionFilterAttribute();
-
-
public virtual void OnActionExecuted(ActionExecutedContext filterContext);
-
-
public virtual void OnActionExecuting(ActionExecutingContext filterContext);
-
-
public virtual void OnResultExecuted(ResultExecutedContext filterContext);
-
-
public virtual void OnResultExecuting(ResultExecutingContext filterContext);
-
}
-
}
實現MyActionFilterAttribute類:
-
using System;
-
using System.Web.Mvc;
-
-
namespace
MvcApp.Filter
-
{
-
public
class
MyActionFilterAttribute :
ActionFilterAttribute
-
{
-
public override void OnActionExecuting(ActionExecutingContext filterContext)
-
{
-
//1、獲取請求的類名和方法名
-
string strController = filterContext.RouteData.Values[
"controller"].ToString();
-
string strAction = filterContext.RouteData.Values[
"action"].ToString();
-
-
//2、用另一種方式獲取請求的類名和方法名
-
string strController2 = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
-
string strAction2 = filterContext.ActionDescriptor.ActionName;
-
-
filterContext.HttpContext.Response.Write(
"控制器:" + strController +
"<br/>");
-
filterContext.HttpContext.Response.Write(
"控制器:" + strController2 +
"<br/>");
-
filterContext.HttpContext.Response.Write(
"Action:" + strAction +
"<br/>");
-
filterContext.HttpContext.Response.Write(
"Action:" + strAction2 +
"<br/>");
-
-
filterContext.HttpContext.Response.Write(
"Action執行前:" + DateTime.Now.ToString(
"yyyy-MM-dd hh:mm:ss fff") +
"<br/>");
-
base.OnActionExecuting(filterContext);
-
}
-
-
public override void OnActionExecuted(ActionExecutedContext filterContext)
-
{
-
filterContext.HttpContext.Response.Write(
"Action執行后:" + DateTime.Now.ToString(
"yyyy-MM-dd hh:mm:ss fff") +
"<br/>");
-
base.OnActionExecuted(filterContext);
-
}
-
}
-
}
對於過濾器,我們可以把它們加在3個地方,一個是控制器上面(控制器下面的所有Action),一個是Action上面(指定標識的Action),另一個就是全局位置(所有控制器中的Action)。這里只演示在Action上面和Home控制器中:
-
[
MyActionFilter]
-
public ActionResult Index()
-
{
-
return View();
-
}
2、Result過濾器
新建MyResultFilterAttribute類,繼承ActionFilterAttribute:
-
using System;
-
using System.Web.Mvc;
-
-
namespace
MvcApp.Filter
-
{
-
public
class
MyResultFilterAttribute :
ActionFilterAttribute
-
{
-
/// <summary>
-
/// 加載“視圖”前執行
-
/// </summary>
-
/// <param name="filterContext"></param>
-
public override void OnResultExecuting(ResultExecutingContext filterContext)
-
{
-
filterContext.HttpContext.Response.Write(
"加載視圖前執行 OnResultExecuting" + DateTime.Now.ToString(
"yyyy-MM-dd hh:mm:ss fff") +
"<br/>");
-
base.OnResultExecuting(filterContext);
-
}
-
-
/// <summary>
-
/// 加載“視圖”后執行
-
/// </summary>
-
/// <param name="filterContext"></param>
-
public override void OnResultExecuted(ResultExecutedContext filterContext)
-
{
-
filterContext.HttpContext.Response.Write(
"加載視圖后執行 OnResultExecuted" + DateTime.Now.ToString(
"yyyy-MM-dd hh:mm:ss fff") +
"<br/>");
-
base.OnResultExecuted(filterContext);
-
}
-
}
-
}
這里把MyResultFilter過濾器加在控制器上面,相當於給Home控制器中的所有的Action方法添加了MyResultFilter過濾器。
-
using MvcApp.Filter;
-
using System.Web.Mvc;
-
-
namespace
MvcApp.Controllers
-
{
-
[
MyResultFilter]
-
public
class
HomeController :
Controller
-
{
-
[
MyActionFilter]
-
public ActionResult Index()
-
{
-
return View();
-
}
-
-
}
-
}
3、AuthorizeAttribute過濾器
創建MyAuthorizeAttribute類,繼承AuthorizeAttribute類:
-
using System.Web.Mvc;
-
-
namespace
MvcApp.Filter
-
{
-
/// <summary>
-
/// 授權過濾器
-
/// </summary>
-
public
class
MyAuthorizeAttribute :
AuthorizeAttribute
-
{
-
public override void OnAuthorization(AuthorizationContext filterContext)
-
{
-
filterContext.HttpContext.Response.Write(
"OnAuthorization<br/>");
-
-
//注釋掉父類方法,因為父類里的OnAuthorization方法會調用ASP.NET的授權驗證機制
-
//base.OnAuthorization(filterContext);
-
}
-
-
}
-
}
在控制器Home中的Index上添加MyAuthorize過濾器:
-
[
MyAuthorize]
-
[
MyActionFilter]
-
public ActionResult Index()
-
{
-
return View();
-
}
通常Authorize過濾器也是在全局過濾器上面的,主要用來做登錄驗證或者權限驗證,在App_Start目錄下的FilterConfig類的RegisterGlobalFilters方法中添加:
-
public
class
FilterConfig
-
{
-
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
-
{
-
//filters.Add(new HandleErrorAttribute());
-
-
//添加全局授權過濾器
-
filters.Add(
new MyAuthorizeAttribute());
-
}
-
}
在全局中注冊過濾器,則所有控制器的所有行為(Action)都會執行這個過濾器。
運行結果,如下圖:
4、Exception過濾器
創建MyHandleErrorAttribute類,繼承HandleErrorAttribute類:
-
using System;
-
using System.Web.Mvc;
-
-
namespace
MvcApp.Filter
-
{
-
/// <summary>
-
/// 異常處理過濾器
-
/// </summary>
-
public
class
MyHandleErrorAttribute :
HandleErrorAttribute
-
{
-
public override void OnException(ExceptionContext filterContext)
-
{
-
//1、獲取異常對象
-
Exception ex = filterContext.Exception;
-
-
//2、記錄異常日志
-
-
//3、重定向友好頁面
-
filterContext.Result =
new RedirectResult(
"~/error.html");
-
-
//4、標記異常已經處理完畢
-
filterContext.ExceptionHandled =
true;
-
-
base.OnException(filterContext);
-
}
-
}
-
}
在Action上面添加MyHandleError過濾器:
-
[
MyHandleError]
-
public ActionResult GetErr()
-
{
-
int a =
0;
-
int b =
1 / a;
-
return View();
-
}
創建異常錯誤友好提示頁面error.html。
-
<body>
-
自定義錯誤頁面
-
</body>
運行會自動跳轉到error.html頁面。
如果頁面沒有跳轉,就需要去Web.config配置文件中的<system.web>節點下面添加如下配置節點,開啟自定義錯誤:
<customErrors mode="On"></customErrors>
通常這樣的異常處理是放在全局過濾器上面的,只要任意Action方法報錯就會執行MyHandleError過濾器中的代碼。
修改App_Start目錄下面的FilterConfig類:
-
public
class
FilterConfig
-
{
-
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
-
{
-
//filters.Add(new HandleErrorAttribute());
-
-
//添加全局授權過濾器
-
filters.Add(
new MyAuthorizeAttribute());
-
-
//添加全局異常處理過濾器
-
filters.Add(
new MyHandleErrorAttribute());
-
}
-
}
Global.asax下的代碼:
-
using System;
-
using System.Collections.Generic;
-
using System.Linq;
-
using System.Web;
-
using System.Web.Mvc;
-
using System.Web.Optimization;
-
using System.Web.Routing;
-
-
namespace
MvcApp
-
{
-
public
class
MvcApplication :
System.
Web.
HttpApplication
-
{
-
protected void Application_Start()
-
{
-
AreaRegistration.RegisterAllAreas();
-
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
-
RouteConfig.RegisterRoutes(RouteTable.Routes);
-
BundleConfig.RegisterBundles(BundleTable.Bundles);
-
}
-
}
-
}