过滤器(Filter)把附加逻辑注入到MVC框架的请求处理。实现了交叉关注

交叉关注:用于整个应用程序,又不适合放在某个局部位置的功能。

过滤器是.NET的注解属性(Attribute),它们对请求处理管道添加了额外的步骤。

注解属性是派生于System.Attribute的特殊的.NET类。

可以被附加到类、方法、属性、字段等代码元素上。其目的是把附加信息嵌入到已编译的代码中,以便在运行时读回这些信息。

过滤器的基本类型:

过滤器类型

接口

默认实现

描述

Authorization

IAuthorizationFilter

AuthorizationAttribute

最先运行

Action

IActionFilter

ActionFilterAttribute

在动作方法前后运行

Result

IResultFilter

ActionResultAttribute

在动作结果被执行前后

Exception

IExceptionFilter

HandlerErrorAttribute

仅在过滤器、动作发生异常时

授权过滤器:IAuthorizationFilter

namespace System.Web.Mvc{

    // 摘要:定义授权筛选器所需的方法。

    public interface IAuthorizationFilter{

        // 摘要:在需要授权时调用。

        // 参数:filterContext:筛选器上下文。

        void OnAuthorization(AuthorizationContext filterContext);

    }

}

注意:

直接实现接口其实是一件非常危险的事;因此创建一个自定义AuthorizeAttribute子类,再实现授权代码比较容易。

public class CustomAuthAttribute:AuthorizeAttribute{

        /// <summary>

        /// 是否对请求进行授权访问的方式

        /// </summary>

        /// <param name="httpContext">对请求信息进行访问的方法</param>

        protected override bool AuthorizeCore(HttpContextBase httpContext){

            return base.AuthorizeCore(httpContext);

        }

}

直接实现IAuthorizationFilter接口的主要原因是为了获取对传递给OnAuthorization()的AuthorizationContext的访问,通过它可以获得更广泛的信息(路由细节、当前控制器和动作方法信息)。使用接口的方式不仅有安全风险且让授权注解属性中建立的逻辑与控制器紧密的耦合在一起,破坏关注分离,不便于维护。

内建的授权过滤器:

虽然使用了AuthorizeAttribute类作为自定义过滤器的基础,但其AuthorizeCore()有自己的实现

当直接使用AuthorizeAttribute时,可以使用它的public属性来指定授权策略

AuthorizeAttribute属性

名称

类型

描述

Users

String

一个逗号分隔的用户名列表,指定这些用户可以访问动作方法

Roles

String

一个逗号分隔的角色列表,用户必须至少有一个角色

public class HomeController : Controller{

        [Authorize(Users ="admin,steve,jacqui",Roles ="admin")]

        public ActionResult Index(){

            return View();

        }

}

异常过滤器:

namespace System.Web.Mvc{

// 摘要:定义异常筛选器所需的方法。

public interface IExceptionFilter{

// 摘要:在发生异常时调用。

// 参数:filterContext:

//     筛选器上下文。

void OnException(ExceptionContext filterContext);

}

}

当一个未处理的异常出现时,OnException()被调用。该方法的参数是一个ExceptionContext 对象,此对象派生于ControllerContext,并提供了许多有用的属性。

名称

类型

描述

Controller

ControllerBase

返回请求的控制器对象

HttpContext

HttpContextBase

提供对请求细节的访问及对响应的访问

IsChildAction

Bool

若是自动做则返回true

RequestContext

RequestContext

提供对HttpContext和路由数据的访问

RouteData

RouteData

返回请求的路由数据

                          继承自ControllerContext的属性

名称

类型

描述

ActionDescripter

ActionDescripter

提供动作方法的细节

Result

ActionResult

用于动作方法的结果,通过非空值可取消请求

Exception

Exception

未处理的异常

ExceptionHandled

Bool

如果另一个过滤器已经把这个异常标记为已处理则返回true

实现自定义异常过滤器

public class RangeExceptionAttribute : FilterAttribute, IExceptionFilter{

public void OnException(ExceptionContext filterContext){

}

}

使用内建的异常过滤器:

                HandleErrorAttribute属性

名称

类型

描述

ExceptionType

Type

由过滤器处理的异常类型

View

String

该过滤器渲染的视图模板名

Master

String

在渲染这个过滤器的视图时使用的布局名称

准备工作:

在web.config文件中启用自定义错误时,HandleErrorAttribute过滤器才会生效,在<system.web>节点中添加一个customErrors属性即可;

<system.web>

  <!--定制错误页aa.html-->

    <customErrors mode="On" defaultRedirect="/Content/aa.html" />

  </system.web>

Mode属性的默认值是RemoteOnly在开发期间,HandleErrorAttribute将不会拦截异常,但当应用程序部署到产品服务器时,并从另一台计算机发出请求时HandleErrorAttribute变生效

[HandleError(ExceptionType =typeof(ArgumentNullException),View ="Null")]

public ActionResult Index(){

return View();

}

在渲染视图时HandleErrorAttribute过滤器会传递一个HandleErrorInfo视图模型对象这是一个封装了异常细节的封装程序

名称

类型

描述

ActionName

String

返回生成异常的Action名称

ControllerName

String

返回生成异常的Controller名称

Exception

Exception

返回此异常

@model HandleErrorInfo

@{ 

    ViewBag.Title = "Sorry";

}

<!DOCTYPE html>

<html>

<head>

    <meta name="viewport" content="width=device-width" />

</head>

<body>

@Model.Exception.StackTrace

</body>

</html>

备注:使用HandleError过滤器时一定要包含Model.Exception.StackTrace否则视图不会显示给用户,引用没必要给用户展示堆栈信息所以可以将该值放入div并隐藏

动作过滤器

用于任何目的的多用途过滤器

 namespace System.Web.Mvc{

     // 摘要:定义操作筛选器中使用的方法。

     public interface IActionFilter{

         // 摘要:在执行操作方法后调用。

         // 参数:filterContext:

         //     筛选器上下文。

         void OnActionExecuted(ActionExecutedContext filterContext);

         // 摘要:在执行操作方法之前调用。

         // 参数:filterContext:

         //     筛选器上下文。

         void OnActionExecuting(ActionExecutingContext filterContext);

     }

 }

              ActionExecutingContext 属性

名称

类型

描述

ActionDescriptor

ActionDescriptor

动作方法的描述

Result

ActionResult

动作方法的结果,设置属性非空值,过滤器可以取消请求

              ActionExecutedContext 属性

名称

类型

描述

ActionDescriptor

ActionDescriptor

动作方法的描述

Canceled

Bool

如果该动作被另一个过滤器取消,则返回true

Exception

Exception

返回由另一个过滤器或动作方法抛出的异常

ExceptionHandled

Bool

如果异常被处理返回true

Result

ActionResult

结果过滤器:

它会对动作方法所产生的结果进行操作

namespace System.Web.Mvc{

    // 摘要:定义结果筛选器所需的方法。

    public interface IResultFilter{

        // 摘要:在操作结果执行后调用。

        // 参数:filterContext:

        //     筛选器上下文。

        void OnResultExecuted(ResultExecutedContext filterContext);

        // 摘要:在操作结果执行之前调用。

        // 参数:filterContext:

        //     筛选器上下文。

        void OnResultExecuting(ResultExecutingContext filterContext);

    }

}

动作方法如何返回动作结果,让用户能够将动作方法的意图与动作方法的执行分离。将结果过滤器运用于一个动作方法时会在动作方法返回结果时、但在执行该动作结果之前调用OnResultExecuting。动作结果执行之后调用OnResultExecuted

内建的动作过滤器和结果过滤器

Mvc框架包含一个内建的类,可以用来创建动作过滤器和结果过滤器,这个类的名称ActionFilterAttribute

namespace System.Web.Mvc{

    // 摘要:表示筛选器特性的基类。

    public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter{

        // 摘要:在执行操作方法后由 ASP.NET MVC 框架调用。

        // 参数:filterContext:

        //     筛选器上下文。

        public virtual void OnActionExecuted(ActionExecutedContext filterContext);

        // 摘要:在执行操作方法之前由 ASP.NET MVC 框架调用。

        // 参数:filterContext:

        //     筛选器上下文。

        public virtual void OnActionExecuting(ActionExecutingContext filterContext);

        // 摘要:在执行操作结果后由 ASP.NET MVC 框架调用。

        // 参数:filterContext:

        //     筛选器上下文。

        public virtual void OnResultExecuted(ResultExecutedContext filterContext);

        // 摘要:在执行操作结果之前由 ASP.NET MVC 框架调用。

        // 参数:filterContext:

        //     筛选器上下文。

        public virtual void OnResultExecuting(ResultExecutingContext filterContext);

    }

}

使用这个类的唯一好处是不需要重写和实现不打算使用的方法。除此之外,直接实现过滤器接口没有任何好处

自定义实例:

public class ProfileAllAttribute: ActionFilterAttribute{

        private Stopwatch timer;

        public override void OnActionExecuting(ActionExecutingContext filterContext){

            timer = Stopwatch.StartNew();

        }

        public override void OnActionExecuted(ActionExecutedContext filterContext){

            timer.Stop();

            filterContext.HttpContext.Response.Write(

                string.Format("<div>Total elapsed time:{0}</div>", timer.Elapsed.TotalSeconds));

        }

}

public class HomeController : Controller{

        [ProfileAll]

        public ActionResult Index(){ return View();}

}

其它过滤器属性:

public abstract class Controller : ControllerBase, IActionFilter, IAuthenticationFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter, IAsyncController, IController, IAsyncManagerContainer

过滤器的几种实现形式:

①全局过滤器

在FilterConfig中直接注册实现类

 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

         public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute()); filters.Add(new MyCustomAttribute());
}

②实现接口

 protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
var contrllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName; var actionName = filterContext.ActionDescriptor.ActionName; var parameter = filterContext.ActionDescriptor.GetParameters(); filterContext.HttpContext.Response.Write(contrllerName + "_" + actionName); base.OnActionExecuting(filterContext);
} protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
}

③注解

 

 public class MyCustomAttribute : FilterAttribute, IActionFilter
{
public void OnActionExecuted(ActionExecutedContext filterContext)
{ } public void OnActionExecuting(ActionExecutingContext filterContext)
{
//1.如果result不为空,那么就return了。不执行递归。。。
filterContext.Result = new ViewResult()
{
ViewName = "Error"
};
}
}

对过滤器执行排序

过滤器是按类型执行的其顺序:授权-》Action-》result。如果有未处理异常,框架在任一阶段都会执行异常过滤器

 namespace System.Web.Mvc

 {

     // 摘要:表示操作和结果筛选器特性的基类。

     public abstract class FilterAttribute : Attribute, IMvcFilter{

         // 摘要: 获取或设置一个值,该值指示是否可指定筛选器特性的多个实例。

         // 返回结果:如果可指定筛选器特性的多个实例,则为 true;否则为 false。

         public bool AllowMultiple { get; }

         // 摘要: 获取或者设置执行操作筛选器的顺序。

         // 返回结果:执行操作筛选器的顺序。

         public int Order { get; set; }

     }

 }

内建过滤器

过滤器

描述

RequireHttps

强迫Action使用Https协议

OutputCache

缓存一个Action的

ValidateInputand

ValidationAntiForgeryToken

与安全性有关的授权过滤器

AsyncTimeout

NoAsyncTimeout

用户异步控制器

ChildActionOnlyAttribute

一个支持Html.action和Html.RenderAction辅助器方法的过滤器

RequireHttps

RequireHttps过滤器让Action强制使用HTTPS协议。他将用户浏览器重定向到同一个动作,但使用‘https://’协议前缀

在形成不安全请求时,重写HandledNonHttpsRequest(),以创建自定义行为,该过滤器仅用于GET请求,POST则会丢掉数据;该过滤器时授权过滤器

mvc4中的过滤器的更多相关文章

  1. C#面试题(转载) SQL Server 数据库基础笔记分享(下) SQL Server 数据库基础笔记分享(上) Asp.Net MVC4中的全局过滤器 C#语法——泛型的多种应用

    C#面试题(转载) 原文地址:100道C#面试题(.net开发人员必备)  https://blog.csdn.net/u013519551/article/details/51220841 1. . ...

  2. MVC4中基于bootstrap和HTML5的图片上传Jquery自定义控件

    场景:mvc4中上传图片,批量上传,上传前浏览,操作.图片进度条. 解决:自定义jquery控件 没有解决:非图片上传时,会有浏览样式的问题; 解决方案; 1.样式 – bootstrap 的css和 ...

  3. Angularjs在控制器(controller.js)的js代码中使用过滤器($filter)格式化日期/时间实例

    Angularjs内置的过滤器(filter)为我们的数据信息格式化提供了比较强大的功能,比如:格式化时间,日期.格式化数字精度.语言本地化.格式化货币等等.但这些过滤器一般都是在VIEW中使用的,比 ...

  4. Autofac在MVC4中牛刀小试

    Autofac是传说中速度最快的一套.NET高效的依赖注入框架.Autofac的介绍与使用请去参考Autofac全面解析系列(版本:3.5).   这里介绍的已经挺详细的啦. 下面我就先来说说MVC4 ...

  5. .net中自定义过滤器对Response内容进行处理

    原文:http://www.cnblogs.com/zgqys1980/archive/2008/09/02/1281895.html 代码DEMO:http://files.cnblogs.com/ ...

  6. java Servlet中的过滤器Filter

    web.xml中元素执行的顺序listener->filter->struts拦截器->servlet. 1.过滤器的概念 Java中的Filter 并不是一个标准的Servlet ...

  7. ASP.NET MVC4中的bundles特性引发服务器拒绝访问(403错误)

    在ASP.NET MVC4中微软引入了bundles特性,这个特性可以将服务器端的多个Javascript或多个css文件捆绑在一起作为一个单一的URL地址供客户端浏览器调用,从而减少了页面上Http ...

  8. MVC中的过滤器

    authour: chenboyi updatetime: 2015-05-09 09:30:30 friendly link:   目录: 1,思维导图   2,过滤器种类(图示) 3,全局过滤器 ...

  9. MVC4中使用Ninject

    MVC4中使用Ninject 1.NuGet获取Ninject.dll .NET技术交流群 199281001 .欢迎加入. 2.全局注册  Global.asax.cs  RegisterNinje ...

随机推荐

  1. iOS 之 KVC KVO

    KVC:键值编码,是一种间接访问对象实例变量的机制,可以不通过存取方法(getter setter)就可以访问实例变量. KVO: 属性变化的通知机制

  2. endnote X7 加入文献

    endnote可以管理文献,并且在word中方便的添加参考文献. 1.加入文献: 2.导入以后可以创建自己的group,然后把导入的参考文献拖到group里,这样方便在插入参考文献的时候用group名 ...

  3. origin添加error bar

    增加一列,然后set as Y Error,然后全部选中显示就行了.

  4. ViewSwitcher的功能与用法

    ViewSwtcher代表了视图切换组件,它本身继承了FrameLayout,因此可以将多个View层叠在一起,每次只显示一个组件.当程序控制从一个View切换到另一个View时,ViewSwitch ...

  5. 纯代码实现CSS圆角

    我这里说的是纯代码,是指的不使用图片实现圆角,图片实现圆角,这里就不说了. 纯代码实现圆角主要有3种方法: 第一种:CSS3圆角   #chaomao{     border-radius:2px 2 ...

  6. Promise基础

    前言: ES2015将Promise引入语言规范,包括fetch等在内的API也构建在Promise之上.作为让js摆脱“回调地狱”的重要一环和众多框架中的重要基础设施之一,学习如何自己实现一个Pro ...

  7. PayPal为什么从Java迁移到Node.js

    前言 大家都知道PayPal是另一家迁移到Node.js平台的大型公司,Jeff Harrell的这篇博文 Node.js at PayPal  解释了为什么从Java迁移出来的原因: 开发效率提高一 ...

  8. 【原】小写了一个cnode的小程序

    小程序刚出来的第一天,朋友圈被刷屏了,所以趁周末也小玩了一下小程序.其实发觉搭建一个小程序不难,只要给你一个demo,然后自己不断的查看文档,基本就可以入门了,不过对于这种刚出来的东西,还是挺多坑的, ...

  9. HoloLens开发手记 - 构建2D应用 Building 2D apps

    HoloLens可以让我们在真实世界中看到全息图像内容.但是它本质上还是一台Windows 10设备,这意味着HoloLens可以以2D应用形式运行Windows Store里的大部分UWP应用. 目 ...

  10. Codeforces374B

    B. Inna and Nine time limit per test 1 second memory limit per test 256 megabytes input standard inp ...