Filter小解释
FiterAttribute是一个特殊的CS属性,是一个抽象类。他的父类是Attribute。而在Mvc中最常用的是ActionFilterAttribute.他是FiterAttribute的子类。同时,ActionFilterAttribute又继承了IActionFilter, IResultFilter两个接口。从这两个接口中,ActionFilterAttribute继承来四个虚方法。我们要使用ActionFiterAttribute则可以重写这几个方法。
如上图,这四个方法分别表示执行前、执行后,结果返回前,结果返回后。大家可以望文生义。
权限验证实现
我们这节中要实现的简单登录检查就是使用这个ActionFiterAttribute,在此,我们重写OnActionExecuting。
首先,我们定义一个ActionFiterAttribute子类,重写该方法。
public class CheckinLoginAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); if (!filterContext.HttpContext.User.Identity.IsAuthenticated) { filterContext.HttpContext.Response.Redirect("~/Home/Login"); return; } } }
此时,使用这个Fiter就可以了。我们在Action的顶部定义该属性。如下
[CheckinLogin] public ActionResult GetSmallClass(string BigClass) { SmallClass_NewS news = new SmallClass_NewS(); news.FromDataTable(EntityDMHelper.GetSmallClass_New(BigClass)); return Json(news,JsonRequestBehavior.AllowGet); }
要注意的是,如果我们想公开某些页面,那么就不要在该Action上定义该属性。
如果我们觉得这样每个Action都要添加怎么办呢?可以在Controller上直接添加属性:
[CheckinLogin] public class ArticleController : Controller { public ActionResult Index(int? id) { BigClass_NewS bigNews = new BigClass_NewS(); bigNews.FromDataTable(EntityDMHelper.GetBigClass_New()); ViewBag.News = bigNews; NewsS news = new NewsS(); News model = new News(); if (id.HasValue) { news.FromDataTable(EntityDMHelper.GetNewsById(id.Value)); if (news.Count > 0) { model = news[0]; } } return View(model); }
这样,还是太麻烦。有人说过懒惰的程序员是个好程序员。那么我们是否还有更加简单的方法呢?Mvc3有了GlobalFilter方法,只需要在Global.asax中更改Application_Start方法就可以了:
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); GlobalFilters.Filters.Add(new CheckinLoginAttribute());//添加属性 RegisterGlobalFilters(GlobalFilters.Filters);//注册 RegisterRoutes(RouteTable.Routes); }
那么这样出现了新的矛盾,我们的登录页面及用户验证页面都被跳转,还会形成递归跳转。怎么办呢?办法总是有的,可以改写OnActionExecuting方法,如下:
public class CheckinLoginAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); string url=filterContext.HttpContext.Request.Url.ToString(); if(url.IndexOf("Home")>0){//将登录controller列为例外 return; } if (!filterContext.HttpContext.User.Identity.IsAuthenticated) { filterContext.HttpContext.Response.Redirect("~/Home/Login"); return; } } }
如此,就将登录页面列为例外。
到此为止,就成功实现了权限检查功能。好了本节到此,由于老是学习新的知识,我们下一节讲解一下如何用vs调试Mvc。