ASP NET MVC Filters 4种默认过滤器的使用【附示例】_第1页
ASP NET MVC Filters 4种默认过滤器的使用【附示例】_第2页
ASP NET MVC Filters 4种默认过滤器的使用【附示例】_第3页
ASP NET MVC Filters 4种默认过滤器的使用【附示例】_第4页
ASP NET MVC Filters 4种默认过滤器的使用【附示例】_第5页
已阅读5页,还剩118页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、过滤器(Filters)的出现使得我们可以在ASP.NET MVC程序里更好的控制浏览器请求过来的URL,不是每个请求都会响应内容,只响应特定内容给那些有特定权限的用户,过滤器理论上有以下功能:1. 判断登录与否或用户权限 2. 决策输出缓存 3. 防盗链 4. 防蜘蛛 5. 本地化与国际化设置 6. 实现动态Action(做权限管理系统的好东西) 先来看一个简单的例子:新建一个AuthFiltersController,里面有两个Actionpublic ActionResult Index() return View();Authorizepublic ActionResult Welco

2、me() return View();很显然,第一个名为Index的Action是没有过滤的,任何身份的请求都可以通过,只要在浏览器的URL栏里键入:localhost:*/AuthFilters/Index 就能得到对应的视图响应;而第二个名为Welcome的Action上面标注了Authorize,表示这是一个只处理那些通过身份验证的URL请求,如果没有通过身份验证就请求这个Action会被带到登录页面。看看配置文件: 根据配置文件的定义,登录页面就是AccountController下名为LogOn的Action,那么就新建一个AccountController,并新建两个Action:

3、public ActionResult LogOn() return View();HttpPostpublic ActionResult LogOn(LogOnViewModel model) if (model.UserName.Trim() = model.Password.Trim() /伪代码,只要输入的用户名和密码一样就过 if (model.RememberMe) FormsAuthentication.SetAuthCookie(model.UserName, true); /2880分钟有效期的cookie else FormsAuthentication.SetAuthCo

4、okie(model.UserName, false); /会话cookie return RedirectToAction(Welcome, AuthFilters); Else return View(model);第一个是处理Get请求用于响应视图页面的,第二个是处理用户点击提交回发的登录表单。LogOnViewModel是用户登录实体类,看具体定义:/ / 用户登录类/ public class LogOnViewModel / / 用户名 / public string UserName get; set; / / 密码 / public string

5、Password get; set; / / 记住我 / public bool RememberMe get; set; ok,按F6编译下项目,再按Ctrl + F5运行下项目,在URL里输入:localhost:*/AuthFilters/Index 很轻松的得到了Index这个Action的响应再定位到:localhost:*/AuthFilters/Welcome可见,虽然定位到了Welcome这个Action,但是却并不像Index一样直接返回对应的视图,而是被带到了登录页面。就是因为Welcome这个Action上被标注了Authorize,拒绝了所以未验证用户的访问。既然拒绝了

6、未验证的用户,那就登录下通过验证,看看上面LogOn里写的伪代码就知道,输入相同的用户名和密码就能登录成功,用户名和密码都输入“wangjie”试试:已经通过验证并得到Welcome这个Action的响应了。相比之前就是多生成了一个名为“.ASPXAUTH”的Cookie, 这是个默认名,配置文件里可以修改。同时,如果登录的时候勾选了“记住我”那么此Cookie的过期时间就是配置文件里定义的2880分钟。ok,现在提高下难度,只设置名为“a”、“bb”、“ccc”的用户可以访问欢迎页面:Authorize(Users = a,bb,ccc)public ActionR

7、esult Welcome() ViewBag.Message = 已登录; return View();再用“wangjie”登录下发现跳不到欢迎页面了,因为指定了a、bb、ccc这三个用户才可以登录。先不管为何在Action上标注Users = a,bb,ccc就可以控制可以访问的用户,但从操作性上来说这样控制Action的访问权限还是很方便的。但是如果项目大,用户对应的角色和权限变化比较大,每次变化都来重新标注Action显然不合适。MVC框架提供的过滤器(Filters)就派上了用场:上图是Asp.Net MVC框架提供的几种默认Filter:授权筛选器、操作筛选器、结果筛选器、异常筛

8、选器,下面来一一讲解,先看演示Demo结构图:一、授权筛选器授权筛选器用于实现IAuthorizationFilter接口和做出关于是否执行操作方法(如执行身份验证或验证请求的属性)的安全决策。 AuthorizeAttribute类和RequireHttpsAttribute类是授权筛选器的示例。授权筛选器在任何其他筛选器之前运行。新建一个继承AuthorizeAttribute类的UserAuthorize类,F12定位到AuthorizeAttribute类,看看内部申明:public AuthorizeAttribute();public string Roles get; set;

9、public override object TypeId get; public string Users get; set; protected virtual bool AuthorizeCore(HttpContextBase httpContext);protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext);public virtual void OnAuthorization(AuthorizationContext filterContext);protected vi

10、rtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext);上面演示的指定用户才可以访问就是利用了Users属性,并由基类帮助我们验证,只放指定的Users用户通过。要实现自定义的验证只需重写下OnAuthorization和AuthorizeCore方法。为了演示效果,新建一个SampleData类用来初始化数据:/ / 测试数据(实际项目中,这些数据应该从数据库拿)/ public class SampleData public static List users; public static L

11、ist roles; public static List roleWithControllerAndAction; static SampleData() / 初始化用户 users = new List() new User() Id=1, UserName=wangjie, RoleId=1, new User() Id=2, UserName =senior1, RoleId=2, new User() Id=3, UserName =senior2, RoleId=2, new User() Id=5, UserName=junior1, RoleId=3, new User() I

12、d=6, UserName=junior2, RoleId=3, new User() Id=6, UserName=junior3, RoleId=3 ; / 初始化角色 roles = new List() new Role() Id=1, RoleName=管理员, Description=管理员角色, new Role() Id=2, RoleName=高级会员, Description=高级会员角色, new Role() Id=3, RoleName=初级会员, Description=初级会员角色 ; / 初始化角色控制器和Action对应类 roleWithController

13、AndAction = new List() new RoleWithControllerAction() Id=1, ControllerName=AuthFilters, ActionName=AdminUser, RoleIds=1, new RoleWithControllerAction() Id=2, ControllerName=AuthFilters, ActionName=SeniorUser, Ids=1,2, new RoleWithControllerAction() Id=3, ControllerName=AuthFilters, ActionName=Junior

14、User, Ids=1,2,3, new RoleWithControllerAction() Id=4, ControllerName=ActionFilters, ActionName=Index, RoleIds=2,3 ; 简单明了,用户拥有角色,不同角色可以访问的Action也不同。这比较符合权限项目里的控制。再看看UserAuthorize类的具体定义:/ / 自定义用户授权/ public class UserAuthorize : AuthorizeAttribute / / 授权失败时呈现的视图 / public string AuthorizationFailView ge

15、t; set; / / 请求授权时执行 / public override void OnAuthorization(AuthorizationContext filterContext) /获得url请求里的controller和action: string controllerName = filterContext.RouteData.Valuescontroller.ToString().ToLower(); string actionName = filterContext.RouteData.Valuesaction.ToString().ToLower(); /string co

16、ntrollerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName; /string actionName = filterContext.ActionDescriptor.ActionName; /根据请求过来的controller和action去查询可以被哪些角色操作: Models.RoleWithControllerAction roleWithControllerAction = base.SampleData.roleWithControllerAndAction.Find(r = r.

17、ControllerName.ToLower() = controllerName & tionName.ToLower() = actionName); if (roleWithControllerAction != null) this.Roles = roleWithControllerAction.RoleIds; /有权限操作当前控制器和Action的角色id base.OnAuthorization(filterContext); /进入AuthorizeCore / / 自定义授权检查(返回False则授权失败) / protected override bool Authori

18、zeCore(HttpContextBase httpContext) if (httpContext.User.Identity.IsAuthenticated) string userName = httpContext.User.Identity.Name; /当前登录用户的用户名 Models.User user = Database.SampleData.users.Find(u = u.UserName = userName); /当前登录用户对象 if (user != null) Models.Role role = Database.SampleData.roles.Find

19、(r = r.Id = user.RoleId); /当前登录用户的角色 foreach (string roleid in Roles.Split(,) if (role.Id.ToString() = roleid) return true; return false; else return false; else return false; /进入HandleUnauthorizedRequest / / 处理授权失败的HTTP请求 / protected override void HandleUnauthorizedRequest(AuthorizationContext filt

20、erContext) filterContext.Result = new ViewResult ViewName = AuthorizationFailView ; 自定义好授权类就可以到控制器上使用了,看看AuthFiltersController类:public class AuthFiltersController : Controller public ActionResult Index() return View(); /Authorize(Users = a,bb,ccc) Authorize public ActionResult Welcome() ViewBag.Mess

21、age = 普通已授权页面; return View(); UserAuthorize(AuthorizationFailView = Error) /管理员页面 public ActionResult AdminUser() ViewBag.Message = 管理员页面; return View(Welcome); UserAuthorize(AuthorizationFailView = Error) /会员页面(管理员、会员都可访问) public ActionResult SeniorUser() ViewBag.Message = 高级会员页面; return View(Welco

22、me); UserAuthorize(AuthorizationFailView = Error) /游客页面(管理员、会员、游客都可访问) public ActionResult JuniorUser() ViewBag.Message = 初级会员页面; return View(Welcome); Welcome这个Action使用了默认的授权验证,只要登陆成功就可以访问。其他几个Action上都标注了自定义的UserAuthorize,并没有标注Users=.,Roles=.,因为这样在Action上写死用户或者角色控制权限显然是不可行的,用户和角色的对应以及不同的角色可以操作的Acti

23、on应该是从数据库里取出来的。为了演示就在SampleData类里初始化了一些用户和角色信息,根据SampleData类的定义,很明显wangjie拥有1号管理员角色,可以访问AuthFilters这个控制器下的所有Action,senior1、senior2拥有2号高级会员的角色,可以访问AuthFilters这个控制器下除了AdminUser之外的Action等等再次登陆下,就发现拥有高级会员角色的用户senior1是不可以访问AdminUser这个Action,会被带到AuthorizationFailView属性指定的Error视图:二、操作筛选器、结果筛选器操作筛选器用于实现IAct

24、ionFilter接口以及包装操作方法执行。IActionFilter接口声明两个方法:OnActionExecuting和OnActionExecuted。OnActionExecuting在操作方法之前运行。OnActionExecuted在操作方法之后运行,可以执行其他处理,如向操作方法提供额外数据、检查返回值或取消执行操作方法。结果筛选器用于实现IResultFilter接口以及包装ActionResult对象的执行。IResultFilter接口声明两个方法OnResultExecuting和OnResultExecuted。OnResultExecuting在执行ActionRes

25、ult对象之前运行。OnResultExecuted在结果之后运行,可以对结果执行其他处理,如修改 HTTP 响应。OutputCacheAttribute 类是结果筛选器的一个示例。操作筛选器和结果筛选器都实现ActionFilterAttribute类,看看类里定义的方法:public virtual void OnActionExecuted(ActionExecutedContext filterContext);public virtual void OnActionExecuting(ActionExecutingContext filterContext);public virt

26、ual void OnResultExecuted(ResultExecutedContext filterContext);public virtual void OnResultExecuting(ResultExecutingContext filterContext);根据方法的名字就知道4个方法执行的顺序了:OnActionExecuting是Action执行前的操作、OnActionExecuted则是Action执行后的操作、OnResultExecuting是解析ActionResult前执行、OnResultExecuted是解析ActionResult后执行即:Action

27、执行前:OnActionExecuting方法先执行Action执行 OnActionExecuted方法执行OnResultExecuting方法执行返回的ActionRsult中的 executeResult方法执行OnResultExecuted执行完全可以重写OnActionExecuting方法实现上面授权筛选器一样的功能,因为OnActionExecuting方法是在Action方法执行前运行的,自定义一个实现ActionFilterAttribute类的ActionFilters类,OnActionExecuting方法这么写:/ / 在执行操作方法之前由 MVC 框架调用/ p

28、ublic override void OnActionExecuting(ActionExecutingContext filterContext) string userName = filterContext.HttpContext.User.Identity.Name; /当前登录用户的用户名 Models.User user = Database.SampleData.users.Find(u = u.UserName = userName); /当前登录用户对象 if (user != null) Models.Role role = Database.SampleData.rol

29、es.Find(r = r.Id = user.RoleId); /当前登录用户的角色 /获得controller: string controllerName = filterContext.RouteData.Valuescontroller.ToString().ToLower(); /string actionName = filterContext.RouteData.Valuesaction.ToString().ToLower(); if (ActionName = null) ActionName = filterContext.RouteData.Valuesaction.T

30、oString(); /查询角色id Models.RoleWithControllerAction roleWithControllerAction = .SampleData.roleWithControllerAndAction.Find(r = r.ControllerName.ToLower() = controllerName & Name.ToLower() = ActionName.ToLower(); if (roleWithControllerAction != null) this.Roles = roleWithControllerAction.RoleIds; /有权

31、限操作当前控制器和Action的角色id if (!string.IsNullOrEmpty(Roles) foreach (string roleid in Roles.Split(,) if (role.Id.ToString() = roleid) return; /return就说明有权限了,后面的代码就不跑了,直接返回视图给浏览器就好 filterContext.Result = new EmptyResult(); /请求失败输出空结果 HttpContext.Current.Response.Write(对不起,你没有权限!); /打出提示文字 /return; else /fi

32、lterContext.Result = new ViewResult ViewName = Error ; filterContext.Result = new EmptyResult(); HttpContext.Current.Response.Write(对不起,请先登录!); /return; /base.OnActionExecuting(filterContext);看看如何在ActionFiltersController控制器里使:public class ActionFiltersController : Controller ActionFilters public Act

33、ionResult Index() return View(); ActionFilters(ActionName = Index) public ActionResult Details() return View(); ActionFilters public ActionResult Test() return View(); 很明显Index和Details这两个Action同用一个权限,看看初始化数据SampleData类的定义:new RoleWithControllerAction() Id=4, ControllerName=ActionFilters, ActionName=

34、Index, RoleIds=2,3只有2和3号角色可以访问,那么1号角色的wangjie用户应该是访问不了的,登录试试:三、异常筛选器异常筛选器用于实现IExceptionFilter接口,并在ASP.NET MVC管道执行期间引发了未处理的异常时执行。异常筛选器可用于执行诸如日志记录或显示错误页之类的任务。HandleErrorAttribute类是异常筛选器的一个示例。有之前授权筛选器、操作和结果筛选器的使用经验,再看异常筛选器就简单许多了,来看看自定义的继承自HandleErrorAttribute类的异常筛选类ExceptionFilters:/ / 异常筛选器/ public cl

35、ass ExceptionFilters : HandleErrorAttribute / / 在发生异常时调用 / public override void OnException(ExceptionContext filterContext) /if (!filterContext.ExceptionHandled & filterContext.Exception is NullReferenceException) if (!filterContext.ExceptionHandled) /获取出现异常的controller名和action名,用于记录 string controlle

36、rName = (string)filterContext.RouteData.Valuescontroller; string actionName = (string)filterContext.RouteData.Valuesaction; /定义一个HandErrorInfo,用于Error视图展示异常信息 HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName); ViewResult result = new ViewResult ViewName

37、 = this.View, ViewData = new ViewDataDictionary(model) /定义ViewData,泛型 ; filterContext.Result = result; filterContext.ExceptionHandled = true; /base.OnException(filterContext); 看看如何在视图中使用:ExceptionFilters(View = Exception)public ActionResult Index() throw new NullReferenceException(测试抛出异常!);View是制定的捕

38、获异常后显示给用户的视图:再看一个Action:ExceptionFilters(View = ExceptionDetails)public ActionResult Details() int i = int.Parse(hello,world!); return View();把string类型的数据强转int,肯定得报FormatException异常,看看ExceptionDetails视图如何定义的:model System.Web.Mvc.HandleErrorInfo Layout = null; 异常 抛错控制器:Model.ControllerName 抛错方法:Model

39、.ActionName 抛错类型:Model.Exception.GetType().Name 异常信息:Model.Exception.Message 堆栈信息: Model.Exception.StackTrace浏览器显示结果:感谢阅读,如果觉得还不错,请不吝给我点个“赞”,谢谢。(英文版 ) easily blame, to prevent the broken window effect. Supervise the leading cadres to play an exemplary role, take the lead in the strict implementation

40、 of the and , lead to safeguard the solemnity and authority of the party discipline, ensure that the party discipline and the laws and regulations for implementation in place. Throughout the discipline in the daily supervision and management, strengthen supervision and inspection, from the thorough

41、investigation of violations of discipline behavior. Strengthen to key areas, key departments and key projects as well as the masses reflect the concentration of the units and departments for supervision. - strengthening supervision, discipline inspection and supervision of cadres to set an example f

42、or compliance with the and is a man must be hexyl, blacksmith needs its own hardware. Discipline inspection organs as the executor of the party discipline, and supervisor of the defenders, for its supervision must be more strictly, discipline inspection and supervision of cadres to firmly establish

43、the awareness of Party Constitution, sense of discipline and rules consciousness, politics loyalty, sense obey. Action speak Ji Ordinance to set an example of the regulations of the rule of law, strengthen supervision and accept the supervision of the firmness and consciousness, do comply with and .

44、 To firmly establish the discipline must first be disciplined, the supervisor will be subject to the supervision of concept, and consciously safeguard and implement party compasses party, take the lead in practicing three strict real strict, so loyal, clean, play. To be good at learning, the Constit

45、ution and the as morality, politics and brought to fruition; to implement , do not want to, dare not, not with disciplinary ruler to supervision; to discipline a ruler, often the control inspection, and consciously in the ideological red line to draw the row Ming Good accumulation is indeed the bott

46、om line, so that the heart has fear, said to have quit, the line has ended. Attached: indifferent to heart, calmly to the table in our life, there are many unpredictable things will happen, some good, some bad things, we cannot control is powerless to stop, but with time, you will find in life somet

47、imes turns out to be not good, some bad things finally turned out to be a good thing, but then we muddy however did not know, this is the life teach us things. 1, life can be complex, can also be simple. Want simple life of precipitation, to have enough time to reflect, to make Become more perfect.

48、Life is the most important thing is not to win, but the struggle; not to have conquered, but to have fought well. 2, the plain is the background of life. Live a plain life, give up on themselves is not a coward, but the wise answers; not disillusioned after the heart, such as ashes, but experience t

49、he storm after the enlightenment; not unrewarding perfunctorily, but calm attitude of life of unrestrained self-confidence. Plain living, there is no noise noisy, no earthly troubles, more did not fill in the discontent of desire, some just a calm, a calm. 3, memory of heart will not good things to erase the, life is a When no movie, pain is a beginnin

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论