在mvc中,过滤器是无此不在,可能没有显示的去调用,所以很多人还不是很理解,本节就通过几个例子来说明一下mvc中过滤器的使用。
一、过滤器概况
为什么说过滤器在mvc中无此不在呢?默认添加一个的控制器,会发现其继承的是Controller类,在Controller上面按F12转到定义:
public abstract class Controller : ControllerBase, IActionFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter
其中上面的几个接口,带有Filter后缀名的,也就是我们本节要说明的过滤器了,共四个:ActionFilter(方法过滤 器),ResultFilter(结果过滤器,感觉不是很好听,就这样叫吧),AuthorizationFilter(授权过滤 器),ExceptionFilter(异常处理过滤器)。现在应该知道无处不在的原因了吧,难道说你不是用Controller。好了废话不多扯了,开 始进入我们的正题。
二、过滤器说明
2.1 IActionFilter有两个方法:
// 摘要:
// 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);
一个是在调用前使用,一个是在调用后使用的。
2.2同样IResultFilter也有两个方法:
// 摘要:
// 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);
2.3 IAuthorizationFilter:
void OnAuthorization(AuthorizationContext filterContext);
这个是在所有过滤器调用之前调用的方法。
2.4 IExceptionFilter
void OnException(ExceptionContext filterContext);
这个是在异常发生时调用。
感觉讲的还是不够清楚,使用书中的一个表格来说明:(虽然是e文,感觉不是很难看懂)

好了,简单的也说明了一些上面的方法,可能还是不清楚怎么去使用这些过滤器。接下来我将会先比较一下他们的相同点,然后去举几个例子来说明其用途。
三、过滤器的使用
3.1共同点
现在我们回头来看上面几个接口的方法,主要是看其形参——一个共同的特点是其包括一个基类为ControllerContext的形参。这个参数有 很多有用的属性,如HttpContextBase,ControllerBase,RouteData等这些属性都直接关系着我们http请求以及请求 的去向。
3.2实例
接下来就来看几个实例,感受一下过滤器的厉害:如果例子中有不足的地方,或者有更好的使用,请大牛指点。
例子1.让含有admin的controller必须要登陆,否则转到登陆界面。
然后让admin文件夹里面的controller去实现继承我们定义的AdminActionFilter.
例子2.统计异常(该实例基于HandleErrorAttribute)
public class CustomExceptionFilter : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
//如果异常未处理
if (!filterContext.ExceptionHandled)
{
Exception innerException = filterContext.Exception;
//如果错误码为500
if ((new HttpException(null, innerException).GetHttpCode() == 500) && this.ExceptionType.IsInstanceOfType(innerException))
{
//获取出现异常的controller名和action名,用于记录
string controllerName = (string)filterContext.RouteData.Values["controller"];
string actionName = (string)filterContext.RouteData.Values["action"];
//定义一个HandErrorInfo,用于Error页使用
HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
//ViewResult是ActionResult,经常出现在controller中action方法return后面,但是出现形式是View()
ViewResult result = new ViewResult
{
ViewName = this.View,
MasterName = this.Master,
//定义ViewData,使用的是泛型
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;
}
}
base.OnException(filterContext);
}
}
然后前台的error.cshtml应该更改为
View Code 之后web.config里面 由于我们的view中的error页面可能会出现异常,所以为了防止这样的问题发生, <system.web/>节点里面可以配置一下,<customErrors mode="On" defaultRedirect="ErrorPage.htm">
使用global文件注册过滤器。
如果没有使用global注册的话,只能一个个去实现,所以我们最好使用哦global去实现注册。
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{ //filters.Add(new HandleErrorAttribute());
filters.Add(new CustomExceptionFilter());
}
下面我把异常处理的源码上传上去,仅供参考。
源码
转载原文:http://www.cnblogs.com/lzhp/archive/2013/05/14/3076478.html

浙公网安备 33010602011771号