MVC Filter的使用方法

相信对权限过滤大家伙都不陌生

用户要访问一个页面时

先对其权限进行判断并进行相应的处理动作

在webform中

最直接也是最原始的办法就是

在page_load事件中所有代码之前

先执行一个权限判断的方法

至于其专业的权限机制这里不做讨论

想要了解的同学可以自行google之

或者点击进入:

webform专业的权限验证机制

那么mvc中是如何实现权限验证的?

据我们所知

mvc中是根据路由配置来请求控制器类中的一个方法

并没有webform中的page_load方法

难道我们要在每个action方法中都调用一个权限判断的方法吗?

很明显不可能= =

懒惰的程序员们怎么可能允许这种情况发生

其实在mvc框架中

程序员提供了一种过滤器机制

通过过滤器

我们可以随心所欲的控制访问权限

那么接下来

教育科学频道--走近科学带你进入过滤器的内心世界~~

首先,我们可以自己添加一个过滤器

添加一个类,名为MyFilter1Attribute

并继承自ActionFilterAttribute类(注意,这里的ActionFilterAttribute的命名空间是System.Web.Mvc不要引用错了~)

现在这个MyFilter1Attribute就是一个过滤器类了

因为继承自ActionFilterAttribute类

所以我们自己添加的MyFilter1Attribute就拥有了某些过滤方法

我们对ActionFilterAttributeF12转到定义看一看里面有什么东西

可以看到,这个ActionFilterAttribute是一个特性类(这就是人家为什么以Attribute结尾啦~)

并且实现了两个很重要的接口IActionFilter,IResultFilter

我们在转到定义看一下这两个接口中有什么

可以看到

这两个接口中各自定义了两个方法,而ActionFilterAttribute既然实现了它们,那么ActionFilterAttribute自然也会拥有这四个方法

那么这四个方法是什么呢?

马上揭晓~

前面我们说到过,ActionFilterAttribute其实是一个特性类

什么是特性类?

就比如之前进实体验证的时候,为实体的字段贴上的标签

那个标签就是一个特性类

也就是说

特性类可以通过贴标签的形式来使用

而我们自己添加的MyFilter1Attribute也是一个特性类

这有什么用吗?

等下你就知道了~

现在先在MyFilter1Attribute中重写OnActionExecuting方法

其实我们可以从这个方法的名字上大概推出这个方法是做什么的了

没错,该方法会在action方法执行之前调用

反之IActionFilter中的另一个方法--OnActionExecuted就是在action方法执行完毕之后调用

口说无凭

下面上证据:

public class MyFilter1Attribute:ActionFilterAttribute
    {
        //该方法会在action方法执行之前调用
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            filterContext.HttpContext.Response.Write("我是OnActionExecuting,我在action方法调用钱执行<br/>");
            base.OnActionExecuting(filterContext);
        }

        //该方法会在action方法执行之后调用
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            filterContext.HttpContext.Response.Write("我是OnActionExecuted,我在action方法调用后执行<br/>");
            base.OnActionExecuted(filterContext);
        }

    }

在Home控制器中添加一个action方法

[MyFilter1]
        public void FilterTest()
        {
             Response.Write("我是action方法,在这里执行了~~</br>");
        }

这时候看到了吗?

要在一个action方法中使用一个过滤器

只要在该方法上贴一个过滤器的标签就ok~ 
生成运行,结果如下:

强有力的证明~

但是呢,有时候我们会有这样的一需求:

过滤器中当遇到了贴了某某标签的action方法就跳过不进行验证

这怎么办呢?

可以通过filterContext的ActionDescriptor属性类完成这易操作

ActionDescriptor顾名思义,action方法的描述着

在ActionDescriptor中我们可以拿到相应的action方法信息,甚至还可以拿到一个控制器描述着ControllerDescriptor

代码如下:

//该方法会在action方法执行之前调用
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            filterContext.HttpContext.Response.Write("我是OnActionExecuting,我在action方法调用前执行<br/>");
            //判断该action方法时候有贴上MyFilter1Attribute标签
            if (filterContext.ActionDescriptor.IsDefined(typeof (MyFilter1Attribute),false))
            {
                //如果有,为该action方法直接返回ContentResult,则该action方法在这里就有了返回值,相当于在这里就结束了,不会在去执行之后的方法,如:OnActionExecuted等
                filterContext.Result = new ContentResult();
            }
            base.OnActionExecuting(filterContext);
        }

结果如图:

可以看到,action方法中和OnActionExecuted中的Response.Write都没有被执行,也就是说,该action方法被跳过了

之前我们使用的是IActionFilter接口中的方法

接下来介绍IResultFilter接口方法

//在action方法返回结果之后执行
        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            filterContext.HttpContext.Response.Write("我是OnActionExecuted,我action方法返回结果之前执行<br/>");
            base.OnResultExecuting(filterContext);
        }

        //在action方法返回结果之前前执行
        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            filterContext.HttpContext.Response.Write("我是OnResultExecuted,我在action方法返回结果之后执行<br/>");
            base.OnResultExecuted(filterContext);
        }

IResultFilter中同样也有两个方法

我们将FilterTest改为下面代码:

[MyFilter1]
        public ActionResult FilterTest()
        {
            Response.Write("我是action方法的Response.Write,在这里执行了~~</br>");
            return View();
        }

并添加视图如下:

<body>
    <div>
        我是FilterTest的视图,在这里执行action方法~~
    </div>
</body>

生成并运行,结果图:

可以看到,IResultFilter接口中的方法和IActionFilter方法的区别就是执行位置不一样

但是呢,mvc框架中还有一个过滤器

他就是权限过滤器AuthorizeAttribute

该过滤器在所有action方法过滤器之前执行,也就是说,提供了一个可以超前验证的方法

我们在添加一个新的过滤器类,并继承自AuthorizeAttribute

重写其OnAuthorization方法如下:

这里需要注意,把基类的OnAuthorization方法去掉,因为我们并不需要,而且留着可能会出现一些错误异常

public class MyFilter2Attribute:AuthorizeAttribute
    {
        //在所有action方法过滤器之前执行
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            filterContext.HttpContext.Response.Write("我是OnAuthorization,在所有action方法过滤器之前执行<br/>");
            //base.OnAuthorization(filterContext);
        }
    }
[MyFilter1]
        [MyFilter2]
        public ActionResult FilterTest()
        {
            Response.Write("我是action方法的Response.Write,在这里执行了~~</br>");
            return View();
        }

为FilterTest方法在贴上MyFilter2标签

运行:

有图有证据~

如此一来

我们就可以根据需要选择合适的方法进行权限验证

但是这时候又有问题了

什么问题呢?

这个特性是贴在action方法上面的

如果我控制器中所有的action方法都要进行验证怎么办?

难道每个action方法都贴一遍吗?

如果我程序中的所有控制器中的所有action方法都需要验证呢?

放心~

懒惰的程序员们是不会去做这种傻事的~

如果一个控制器中的所有方法都需要验证

那么我们可以再控制器类上统一贴上标签,如下:

这样一来该控制器中的所有action方法都会进行验证

那么如果每个控制器类都要验证呢?

这个时候我们就需要打开App_Start文件夹了

看到一个FilterConfig类了吗

双击打开FilterConfig.cs

我们可以再这里进行添加全局的过滤器,比如:

最后我们在介绍一个异常处理的过滤器

添加一个过滤器类,并继承自HandleErrorAttribute

 public class MyFilter3Attribute:HandleErrorAttribute
    {
        //在程序中任何地方出现异常都会执行
        public override void OnException(ExceptionContext filterContext)
        {
            //获取异常对象
            Exception ex = filterContext.Exception;
            //记录错误日志
            //导向友好错误界面
            filterContext.Result = new RedirectResult("/Home/Index");
            //重要!!告诉系统异常已处理!!如果没有这个步骤,系统还是会按照正常的异常处理流程走
            filterContext.ExceptionHandled = true;
            //base.OnException(filterContext);
        }
    }

注意,这里基类的OnException也是不需要的

那么异常处理的过滤器要放在哪里呢?

肯定是全局的呀~

filters.Add(new MyFilter3Attribute());

ok,搞定~

运行看看~

时间: 2024-08-01 21:29:31

MVC Filter的使用方法的相关文章

ASP.NET MVC 5 - 验证编辑方法(Edit method)和编辑视图(Edit view)

原文:ASP.NET MVC 5 - 验证编辑方法(Edit method)和编辑视图(Edit view) 在本节中,您将验证电影控制器生成的编辑方法(Edit action methods)和视图.但是首先将修改点代码,使得发布日期属性(ReleaseDate)看上去更好.打开Models \ Movie.cs文件,并添加高亮行如下所示: using System; using System.ComponentModel.DataAnnotations; using System.Data.

Asp.Net MVC -Filter

Filter(筛选器)是基于AOP(面向切面编程)的设计,它的作用是对MVC框架处理客户端请求注入额外的逻辑,以非常简单优美的方式实现横切关注点(Cross-cutting Concerns).横切关注点是指横越应该程序的多个甚至所有模块的功能,经典的横切关注点有日志记录.缓存处理.异常处理和权限验证等.本文将分别介绍MVC框架所支持的不同种类的Filter的创建和使用,以及如何控制它们的执行. 四种基本 Filter 概述 MVC框架支持的Filter可以归为四类,每一类都可以对处理请求的不同

学习之-ASP.NET MVC Filter

MVC Filter 是典型的AOP应用,对MVC框架处理客户端请求注入额外的一些逻辑,如日志记录.缓存处理.异常处理和权限验证,性能检测(横切关注点),而这些逻辑通常与主要业务无关,被独立分开作为公用的部分,降低模块之间的耦合度 . ASP.NET MVC 有四种基本过滤器 过滤器类型 接口 默认实现 描述 Authorization IAuthorizationFilter AuthorizationAttribute 最先运行,在任何其他过滤器或动作方法之前 Action IActionF

[转]ASP.NET MVC 5 - 验证编辑方法(Edit method)和编辑视图(Edit view)

在本节中,您将验证电影控制器生成的编辑方法(Edit action methods)和视图.但是首先将修改点代码,使得发布日期属性(ReleaseDate)看上去更好.打开Models \ Movie.cs文件,并添加高亮行如下所示: using System; using System.ComponentModel.DataAnnotations; using System.Data.Entity; namespace MvcMovie.Models { public class Movie

利用ASP.NET MVC Filter 处理网站异常

1,Filter(筛选器)是基于AOP(面向方面编程)的设计,他的好处什么的就不是本文要说的,如果要了解关于filter的相关知识请参照,大神说的够清楚了:http://www.cnblogs.com/willick/p/3331520.html 这里主要记录一下我自己的利用ASP.NET MVC Filter 处理网站异常过程: 2,首先添加 一个自定义的filter类: using System; using System.Collections.Generic; using System.

关于asp.net MVC 中的TryUpdateModel方法

有比较才会有收货,有需求才会发现更多. 在传统的WebFormk开发工作中,我们常常会存在如下的代码块 //保存 protected void btnSubmit_Click(object sender, EventArgs e) { try { BLL.MoneyBll cun = new BLL.MoneyBll(); Model.Money m1 = new Model.Money(); m1.Commany = int.Parse(this.Commany.Text); m1.Count

MVC实现上传图片的方法

Form提交时,须注意form需要添加属性enctype="multipart/form-data",否则Request.Files.Count=0,无法上传图片. cshtml代码: <form id="form1" name="form1" action="SavaeTopicType.aspx" method="post" enctype="multipart/form-data&qu

MVC验证09-使用MVC的Ajax.BeginForm方法实现异步验证

原文:MVC验证09-使用MVC的Ajax.BeginForm方法实现异步验证 MVC中,关于往后台提交的方法有: 1.Html.BeginForm():同步 2.Ajax.BeginForm():异步 3.js或jQuery提交后台 本文体验Ajax.BeginForm()方法.   View model using System; using System.ComponentModel.DataAnnotations;   namespace XHelent.Models { public

jQuery filter函数使用方法

利用filter函数可以从wrapper set中过滤符合条件的DOM元素. 如果有一个内容如下的html文件,要获取类为external的<a>元素,使用filter可以很easy地搞定. <a href="#" class="external">link</a> <a href="#" class="external">link</a> <a href=&q