1、自定义过滤器
- MVC支持的过滤器类型有四种,分别是:Authorization(授权),Action(行为),Result(结果)和Exception(异常)
- MVC框架为这些种类的Filter接口实现了默认的特性类。
- 如上表,ActionFilterAttribute 类实现了 IActionFilter 和 IResultFilter
两个接口,这个类是一个抽象类,可以根据具体需求选择性的重写对应的虚方法。
1.1ActionFilterAttribute
- AuthorizeAttribute类实现了IAuthorizationFilter接口,用于进入行为之前或之后的处理或返回结果的之前或之后的处理。
- 自定义Filter需要继承ActionFilterAttribute抽象类,重写其中需要的虚方法,观察ActionFilterAttribute类的方法签名。自定义过滤器可以选择适当的方法来重写完成特定的功能。
- 在Action执行之前调用。
public virtual void OnActionExecuting(ActionExecutingContext filterContext)
- 在Action执行之后调用。
public virtual void OnActionExecuted(ActionExecutedContext filterContext)
- 在执行Result之前调用。
public virtual void OnResultExecuting(ResultExecutingContext filterContext)
- 在执行Result后调用。
public virtual void OnResultExecuted(ResultExecutedContext filterContext)
在项目中创建一个Filters目录,与Controllers、Models目录同一层级。
1、在Filters目录中添加一个类,名称MyActionFilterAttribute。 引用命名空间System.Web.Mvc。
2、让MyActionFilterAttribute类继承自ActionFilterAttribute。
3、覆盖ActionFilterAttribute类中的虚方法OnActionExecuting。
覆盖ActionFilterAttribute类中的虚方法OnResultExecuting。
覆盖ActionFilterAttribute类中的虚方法OnResultExecuted。
过滤器创建好了,下一步就是来使用过滤器,创建控制器Home,并在Index Action上使用控制器。
1.2AuthorizeAttribute
AuthorizeAttribute类实现了IAuthorizationFilter接口,此类型(过滤器)用于限制进入控制器或控制器的某个行为方法。
自定义Filter需要继承IAuthorizationFilter抽象类,重写其中需要的方法。自定义过滤器可以选择适当的方法来重写完成特定的功能。
获取当前验证状态,是否通过了授权访问,如果AuthorizeCore返回false时表示授权失败就会由HandleUnauthorizedRequest方法处理。
protected override bool AuthorizeCore(HttpContextBase httpContext)
在每个Action运行之前执行,进行授权验证,可以在此方法中编写授权验证的前置业务逻辑。
public override void OnAuthorization(AuthorizationContext filterContext)
未授权的请求就会调用此方法,进行相应处理,通常情况这里会跳转到,登录页面或显示无权访问页面
> protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
1.2.1示例
- 通过使用授权过滤器对指定Action或控制器访问授权进行验证。
- 在项目中创建一个Filters目录,与Controllers、Models目录同一层级。
- 在Filters目录中添加一个类,名称MyAuthorizeFilterAttribute,引用命名空间System.Web.Mvc,让MyAuthorizeFilterAttribute类继承自AuthorizeAttribute。
- 覆盖AuthorizeAttribute类中的虚方法AuthorizeCore。验证授权状态。
- 创建Login Action 编写登录视图。
Login.cshtml
<body>
<div>
@using (Html.BeginForm())
{
<p>用户名:@Html.TextBox("name")</p>
<p>密 码: @Html.TextBox("pwd")</p>
<input id="Submit1" type="submit" value="登录" />
<p><b>@ViewBag.Result</b></p>
}
</div
</body>
- 直接访问/Home/Index页面会自动跳转到/Home/Login登录页面,然后在登录界面中填入正确用户名密码。页面可以正常访问/Home/Index。
HomeController.cs
[HttpGet]
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(string name,string pwd)
{
if(name=="jack"&&pwd=="123456")
{
Session["User"] = name;
return RedirectToAction("Index");
}
else
{
ViewBag.Result = "用户名或密码错误";
return View();
}
}
1.3HandleErrorAttribute
1.3.1示例
- 在项目中创建一个Filters目录,与Controllers、Models目录同一层级。
- 在Filters目录中添加一个类,名称MyExceptionFilterAttribute,引用命名空间System.Web.Mvc,让MyExceptionFilterAttribute类继承自HandleErrorAttribute。
- 覆盖AuthorizeAttribute类中的虚方法OnException,当异常出现时捕获出现的异常。
-
在App_Start目录中创建FilterConfig.cs类,编写全局过滤器注册代码,当传入全局过滤器数组时,把当前过滤器添加到全局过滤器数组中。
-
注意: 需要引用命名空间System.Web.Mvc。
创建FilterConfig类时,命名空间会默认加上当前目录名称App_Start,这里需要删除,不然下一步中无法找到对应类。
- 在Global.asax全局文件中,网站项目启动时注册一下全局过滤器,整个项目任何异常发生时都可以调用异常过滤器记录到日志中。
- 到此为止站点中的异常过滤器创建好了,接下来测试异常捕获效果。创建TestEx控制器。并创建两个触发异常的Action,以及对应视图页面。
- 在前面异常捕获的代码中设置了,异常捕获后跳转到友好页面,现在创建Error控制器显示友好信息,在正常项目开发过程中不会将错误信息暴露给用户。
- 测试一下异常捕获的效果,对比一下在Global.asax中注册全局过滤器的代码开启跟关闭,访问/TestEx/Ex1 Action的区别。
- //FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
//注释关闭全局过滤器注册
- 制作异常日志查看页面,显示在异常捕获过程中保存的异常日志信息。在Error控制器中显示错误信息列表。
- 访问浏览/TestEx/Ex1后页面不关闭浏览器,继续浏览 /TestEx/Ex2后会显示所有异常捕获信息。