MVC之 自定义过滤器(ActionFilterAttribute)
一、自定义Filter
自定义Filter需要继承ActionFilterAttribute抽象类,重写其中需要的方法,来看下ActionFilterAttribute类的方法签名。
-
//表示所有操作-筛选器特性的基类。
-
[
-
public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter
-
{
-
protected ActionFilterAttribute();
-
// 在Action执行之后由 MVC 框架调用。
-
public virtual void OnActionExecuted(ActionExecutedContext filterContext);
-
// 在Action执行之前由 MVC 框架调用。
-
public virtual void OnActionExecuting(ActionExecutingContext filterContext);
-
// 在执行Result后由 MVC 框架调用。
-
public virtual void OnResultExecuted(ResultExecutedContext filterContext);
-
// 在执行Result之前由 MVC 框架调用。
-
public virtual void OnResultExecuting(ResultExecutingContext filterContext);
-
}
因此自定义过滤器可以选择适当的方法来重写方可。下面来举个简单的例子:检查登录状态的过滤器,没有登录则跳转到登录页
控制器代码
-
[
-
public ActionResult Index()
-
{
-
return View();
-
}
-
-
public ActionResult Login() //此Action自动往cookie里写入登录信息
-
{
-
HttpCookie hcUserName = new HttpCookie("username","admin");
-
HttpCookie hcPassWord = new HttpCookie("password","123456");
-
System.Web.HttpContext.Current.Response.SetCookie(hcUserName);
-
System.Web.HttpContext.Current.Response.SetCookie(hcPassWord);
-
return View();
-
}
过滤器代码
-
public class CheckLogin : ActionFilterAttribute
-
{
-
//在Action执行之前 乱了点,其实只是判断Cookie用户名密码正不正确而已而已。
-
public override void OnActionExecuting(ActionExecutingContext filterContext)
-
{
-
HttpCookieCollection CookieCollect = System.Web.HttpContext.Current.Request.Cookies;if (CookieCollect["username"] == null || CookieCollect["password"] == null)
-
{
-
filterContext.Result = new RedirectResult("/Home/Login");
-
}
-
else
-
{
-
if (CookieCollect["username"].Value != "admin" && CookieCollect["password"].Value != "123456")
-
{
-
filterContext.Result = new RedirectResult("/Home/Login");
-
}
-
}
-
}
-
}//本示例贪图方便,将要跳转到的Action放在同一个Controller下了,如果将过滤器放到Controller类顶部,则永远也跳不到这个LoginAction。
此过滤器实现的效果是,当用户Cookie中用户名和密码不正确则跳转到登录页,注意过滤器也可以放在整个Controller类的顶部,表示该Controller下的
所有Action都执行该项检查。这样一来,控制器里的代码非常漂亮,再也不用所有的Action里都充斥着判断登录的代码了。
-
public class FilterAttribute : ActionFilterAttribute
-
{
-
public string Message { get; set; }
-
-
public override void OnActionExecuting(ActionExecutingContext filterContext)
-
{
-
base.OnActionExecuting(filterContext);
-
filterContext.HttpContext.Response.Write("Action执行之前" + Message + "<br />");
-
}
-
-
public override void OnActionExecuted(ActionExecutedContext filterContext)
-
{
-
base.OnActionExecuted(filterContext);
-
filterContext.HttpContext.Response.Write("Action执行之后" + Message + "<br />");
-
}
-
-
public override void OnResultExecuting(ResultExecutingContext filterContext)
-
{
-
base.OnResultExecuting(filterContext);
-
filterContext.HttpContext.Response.Write("返回Result之前" + Message + "<br />");
-
}
-
-
public override void OnResultExecuted(ResultExecutedContext filterContext)
-
{
-
base.OnResultExecuted(filterContext);
-
filterContext.HttpContext.Response.Write("返回Result之后" + Message + "<br />");
-
}
-
}
然后在调用过滤器的时候,添加上该参数,Controller代码如下:
-
[
-
public ActionResult Index()
-
{
-
return View();
-
}
输出结果如下:
如果标签打到Controller上的话,TestFilterAttributeFilter将作用到Controller下的所有的Action。
默认情况下Action上打了某个自定义标签后,虽然在Controller上也打上了此标签,但它只有Action上的标签起作用了。
补充:如果Action没有打上该标签,那么Controller上的标签便会被执行。
如果想让Action上的标签执行一次,然后Controller上的标签也执行一次,那么应该如何操作呢?
我们只需在FilterAttribute类的定义上打上标记[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]即可【下面类的最上面红色字体部分】,也就是让其成为可以多次执行的Action。代码如下:
-
[
-
public class FilterAttribute : ActionFilterAttribute
-
{
-
public string Message { get; set; }
-
......
三、全局过滤器
有时我们想有些公共的方法需要每个Action都执行,但是又不想再每一个Controller上都打上Action标签,怎么办?幸好Asp。Net MVC3带来了一个美好的东西,全局Filter。而怎么注册全局Filter呢?答案就在Global.asax中。让我们看以下代码,我是如何将上面我们定义的TestFilterAttribute 注册到全局Filter中。
-
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
-
{
-
filters.Add(new HandleErrorAttribute());
-
//注册全局过滤器
-
filters.Add(new TestFilterAttribute() { Message="全局"});
-
}
无人机技术交流QQ群:951349285,mavlink,missionplanner,qgroundcontrol,PX4,ArduPilot。
JAVA&NET技术,跳槽,软考交流QQ群:456257217,有问题的可以在群里面提问交流。