MVC 拦截器
1、IActionFilter(Action拦截器接口)
Action拦截器分别在“执行Action之前”拦截和“执行Action之后”拦截,2个方法如下:
// Called after the action method executes.
//
// 参数:
// filterContext:
// The filter context.
void OnActionExecuted(ActionExecutedContext filterContext);
//
// 摘要:
// Called before an action method executes.
//
// 参数:
// filterContext:
// The filter context.
void OnActionExecuting(ActionExecutingContext filterContext);
摘要就可以区分出哪个是执行之前拦截和执行之后拦截了,我们只需要实现这个接口就可以在执行Action之前做些处理和执行Action之后做些“善后”处理了。。。。
参数:filterContext 包含了执行整个Action的内容,我们可以取到我们想要的内容,如Action名称啦,一些参数等等。。。
LoggerFilter.cs:
2using System.Collections.Generic;
3using System.Linq;
4using System.Web;
5using System.Web.Mvc;
6using System.Web.Mvc.Ajax;
7
8namespace MVCDemo.Controllers.Filters
9{
10 public class LoggerFilter : FilterAttribute, IActionFilter
11 {
12 void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
13 {
14 filterContext.Controller.ViewData["ExecutingLogger"] = "正要添加公告,已以写入日志!时间:" + DateTime.Now;
15 }
16
17 void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext)
18 {
19 filterContext.Controller.ViewData["ExecutedLogger"] = "公告添加完成,已以写入日志!时间:" + DateTime.Now;
20 }
21 }
22}
可以看到,这个类继承了FilterAttribute并实现了IActionFilter。其中关键是IActionFilter,它有两个方法,OnActionExecuting在被拦截Action前执行,OnActionExecuted在被拦截Action后执行。两个方法都有一个参数,虽然类型不同,但其实都是一个作用:被拦截Action的上下文。
这个地方我得解释一下,你拦截器拦截了Action,在做处理时难免要用到被拦截Action相关的东西,例如在我们的例子中,就需要想被拦截Action所在Controller的ViewData中添加内容,所以,拦截器方法有一个参数表示被拦截Action的上下文是顺理成章的事。
2、IExceptionFilter(异常拦截器接口)
ExceptionFilter.cs:
2using System.Collections.Generic;
3using System.Linq;
4using System.Web;
5using System.Web.Mvc;
6using System.Web.Mvc.Ajax;
7
8namespace MVCDemo.Controllers.Filters
9{
10 public class ExceptionFilter : FilterAttribute,IExceptionFilter
11 {
12 void IExceptionFilter.OnException(ExceptionContext filterContext)
13 {
14 filterContext.Controller.ViewData["ErrorMessage"] = filterContext.Exception.Message;
15 filterContext.Result = new ViewResult()
16 {
17 ViewName = "Error",
18 ViewData = filterContext.Controller.ViewData,
19 };
20 filterContext.ExceptionHandled = true;
21 }
22 }
23}
异常拦截器一样需要继承FilterAttribute,但是不要实现IActionFilter,而是要实现IExceptionFilter接口,这个接口只有一个方法:OnException,顾名思义,当然是发生异常时被调用了。我们看看我让它做了什么:首先将异常信息(ExceptionContext一样也是上下文,而其成员的Exception就是一个Exception类型的实例,就是被抛出的异常)记录到ViewData相应的键值里,然后我们要呈现Error这个视图。
注意!这里已经不是Controller里了,而是另一个类,所以当然不能调用View方法 返回ViewResult实例了。我们只好新建一个ViewResult实例,并将其视图名设为Error,将上下文中的DataView传过去。
最后那行filterContext.ExcepitonHandled = true;很重要,这行的意思是告诉系统,异常已经处理,不要再次处理了。
3、 IResultFilter(Result拦截器接口)
IResultFilter 和 IActionFilter 一样提供2个方法,执行前和执行后,分别是在 返回Result之前执行和返回Result之后执行。接口中的2个方法如下:
// Called after an action result executes.
//
// 参数:
// filterContext:
// The filter context.
void OnResultExecuted(ResultExecutedContext filterContext);
//
// 摘要:
// Called before an action result executes.
//
// 参数:
// filterContext:
// The filter context.
void OnResultExecuting(ResultExecutingContext filterContext);
参数:filterContext包含拦截到的Result等信息。。。
示例代码如:
public void OnResultExecuted(ResultExecutedContext filterContext)
{
filterContext.RequestContext.HttpContext.Response.Write("Result已经执行了!");
}
public void OnResultExecuting(ResultExecutingContext filterContext)
{
filterContext.RequestContext.HttpContext.Response.Write("Result执行之前!");
}
#endregion
这2个接口的区别很明显:一个拦截 Action、一个拦截Result(这不是废话嘛,哈哈),又因为Result是Action返回的,
所以 他们的执行顺序是:
OnActionExecuting-->Action中的代码-->OnActionExecuted-->OnResultExecuting-->OnResultExecuted
4、IAuthorizationFilter(授权拦截器接口)
该拦截器专门用来判断权限,判断时候有权限执行后面的Action,此接口在任何拦截器之前执行。。。。。
提供一个方法:
// Called when authorization is required.
//
// 参数:
// filterContext:
// The filter context.
void OnAuthorization(AuthorizationContext filterContext);
示例代码如:
public void OnAuthorization(AuthorizationContext filterContext)
{
filterContext.HttpContext.Response.Write("执行authorization! 判断是否有权限。。。。<br />");
}
#endregion