信用网站标准化建设模块都有哪些,wordpress页尾添加信息,深圳网站制作,免费建论坛网站ASP.NET MVC 中的过滤器允许在执行管道中的特定阶段之前或之后运行代码。可以对全局#xff0c;也可以对每个控制器或每个操作配置过滤器。 1.过滤器如何工作 不同的过滤器类型在管道中的不同阶段执行#xff0c;因此具有各自的与其场景。根据需要执行的任务以及需要执行的请… ASP.NET MVC 中的过滤器允许在执行管道中的特定阶段之前或之后运行代码。可以对全局也可以对每个控制器或每个操作配置过滤器。 1.过滤器如何工作 不同的过滤器类型在管道中的不同阶段执行因此具有各自的与其场景。根据需要执行的任务以及需要执行的请求管道中的位置选择要创建的过滤器类型。过滤器在 MVC 操作调用管道中运行有时也称为过滤管道在 MVC 中选择要执行的操作后执行操作上的过滤器如图 不同的过滤器在管道内的不同位置执行。像授权过滤器这样的过滤器只在管道中靠前的位置执行。其他过滤器如操作Action过滤器可以在管道执行的其他部分之前和之后执行如图 1.选择过滤器 授权过滤器用于确定当前请求用户是否被授权。 资源过滤器是在授权之后第一个处理请求的过滤器也是最后一个在请求离开过滤管道时接触请求的过滤器。在性能方面对实现缓存或者对过滤管道进行短路 特别有用。 操作过滤器包装对单个操作方法的调用并且可以处理传递到操作的参数以及从操作返回的操作结果。 异常过滤器用于对 MVC 应用程序中未处理的异常应用全局策略。 结果过滤器包装单个操作结果的执行并且尽在操作执行成功时运行。它们必须是围绕视图执行或格式化程序执行的逻辑的理想选择。 2.实现过滤器 所有过滤器均可通过不同的接口定义支持同步和异步的实现。根据需要执行的任务类型选择同步或异步实现。从框架的角度看它们是可以互换的。 同步过滤器定义了 OnStageExecuting 和 OnStageExecuted 方法也有例外。OnStageExecuting 方法在事件管道阶段之前通过阶段名称来调用而 OnStageExecuted 方法将在阶段名称命名的管道阶段之后调用。 public class SampleActionFilter:IActionFilter{public void OnActionExecuting(ActionExecutingContext context){//操作执行前做的事情}public void OnActionExecuted(ActionExecutedContext context){//操作执行后做的事情}} 异步过滤器定义了一个单一的 OnActionExecutionAsync 方法可以在具体管道阶段的前后运行。 OnActionExecutionAsync 方法提供了一个 ActionExecutionDelegate 委托调用时该委托会执行具体管道阶段的工作然后等待完成。 public class SampleAsyncActionFilter: IAsyncActionFilter{public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next){//操作执行前做的事情await next();//操作执行后做的事情}} 3.过滤器作用域 过滤器有三种不同级别的作用域。你可以在特定的操作上用特性Attribute的方式使用特定的过滤器。也可以在控制器上用特性的方式使用过滤器这样就可以将效果作用在控制器内的所有操作上。或者注册一个全局过滤器它将作用于整个 MVC 应用程序的每一个操作。 如果想要使用全局过滤器可以在配置 MVC 时在 Startup 的 ConfigureServices 方法中添加 services.AddMvc(options {options.Filters.Add(typeof(SampleActionFilter));//通过类型options.Filters.Add(new SampleActionFilter());//注册实例}).SetCompatibilityVersion(CompatibilityVersion.Version_2_1); 过滤器既可以通过类型添加也可以通过实例添加。如果通过实例添加则该实例会被使用于每一个请求。如果通过类型添加则在每次请求后都会创建一个实例其所有构造函数依赖项都将通过 DI 来填充。 把过滤器接口的实现当作特性使用也非常方便。过滤器特性可应用于控制器和操作方法。框架包含了内置的基于特性的过滤器可以继承他们或者另外定制。例如下面的过滤器继承了 ResultFilterAttribute并重写 OnResultExecuting 方法在响应中增加一个信息头 public class AddHeaderAttribute: ResultFilterAttribute{private readonly string _name;private readonly string _value;public AddHeaderAttribute(string name, string value){_name name;_value value;}public override void OnResultExecuting(ResultExecutingContext context){context.HttpContext.Response.Headers.Add(_name,new string[] { _value });base.OnResultExecuting(context);}} 特性允许过滤器接受参数如下可将此特性添加到控制器或操作中并为其指定所需 HTTP 头的名称和值 [AddHeader(Author, Ruby Lu)]public class HomeController : Controller
{
} 以下几种过滤器接口可以自定义为相应特性的实现 ActionFilterAttribute ExceptionFilterAttribute ResultFilterAttribute FormatFilterAttribute ServiceFilterAttribute TypeFilterAttribute 4.取消和短路 通过设置传入过滤器方法的上下文参数中的 Result 属性可以在过滤器管道的任意一点短路管道。比如下面的 ShortCircuitingResourceFilter 将阻止它之后管道内的所有过滤器包括所有操作过滤器 public class ShortCircuitingResourceFilter:Attribute,IResourceFilter{public void OnResourceExecuting(ResourceExecutingContext context){context.Result new ContentResult() {Content 短路};}public void OnResourceExecuted(ResourceExecutedContext context){}} 2.配置过滤器 全局过滤器在 Startup 中配置。基于特性的过滤器如果不需要任何依赖可以简单地继承一个已存在地过滤器相对应地特性类型。如果要创建一个非全局作用域但需要从依赖注入中获得依赖项的过滤器那么在它们上面加上 ServiceFilterAttribute 或 TypeFilterAttribute 特性这样就可用于控制器或操作了。 1.依赖注入 以特性形式实现的直接添加到控制器或操作的过滤器其构造函数不得由依赖注入提供依赖项。其原因在于特性所需的构造函数参数必须由使用处直接提供。这是特性原型机理的限制。 如果过滤器需要从 DI 中获得依赖项那么可以用以下几种方法在类或操作方法使用 ServiceFilterAttribute TypeFilterAttribute IFilterFactory 实现特性 TypeFilter 将为其依赖项从 DI 中使用服务来实例化一个实例。 ServiceFilter 则从 DI 中获取一个过滤器实例。下面演示 ServiceFilter 先在 ConfigureServices 中注册 AddHeaderFilterWithDI 类型services.AddScopedAddHeaderFilterWithDI(); 然后使用 [ServiceFilter(typeof(AddHeaderFilterWithDI))] public IActionResult Index() { } ServiceFilterAttribute 实现了IFilterFactory 接口它公开了一个创建 IFilter 实例的方法。在 ServiceFilterAttribute 中IFilterFactory 接口的 CreateInstance 方法被实现为从服务容器加载指定的类型。 TypeFilterAttribute 非常类似 ServiceFilterAttribute 也实现 IFilterFactory 接口但它的类型不是直接从 DI 容器中解析相反它使用 Microsoft.Extensions.DependencyInjection.ObjectFactory 实例化类型。 由于这种差异使用 TypeFilterAttribute 引用的类型不需要在使用前向容器注册但它们仍由容器来填充其依赖项。此外TypeFilterAttribute 可以可选的接受该类型的构造函数参数。下面是 TypeFilterAttribute 演示 [TypeFilter(typeof(AddHeaderAttribute),Arguments new object[] { Author,Ruby })]public IActionResult Index(){return View();} 如果有一个简单的过滤器不需要任何参数但有构造函数需要通过 DI 填充依赖项那么可以继承 TypeFilterAttribute允许使用自己命名的特性类和方法而不是 [TypeFilterAttribute(typeof(FilterType))]。下面的过滤器显示了如何实现此功能 public class SampleActionFilterAttribute:TypeFilterAttribute{public SampleActionFilterAttribute() : base(typeof(SampleActionFilterImpl)){}private class SampleActionFilterImpl:IActionFilter{public void OnActionExecuting(ActionExecutingContext context){//操作执行前做的事情}public void OnActionExecuted(ActionExecutedContext context){//操作执行后做的事情}}} 该过滤器可通过使用 [SampleActionFilter] 这样的语法应用于类或方法而不必使用 [TypeFilter] 或 [ServiceFilter] 。 IFilterFactory 实现 IFilter 因此在过滤器管道中任何位置的 IFilterFactory 实例都可当作 Filter 实例来使用。当框架准备调用过滤器时将尝试将其转换为 IFilterFactory 。如果转换成功 则调用 CreateInstance 方法来创建将被调用的 IFilter 实例。这是一种非常灵活的设计因为当应用程序启动时不需要明确地设置精确地过滤器。 你可以在自己地特性中实现 IFilterFactory 几口作为另一种创建过滤器的方法 public class AddHeadWithFactoryAttribute:Attribute, IFilterFactory{public bool IsReusable { get; }//实现IFilterFactorypublic IFilterMetadata CreateInstance(IServiceProvider serviceProvider){return new InternalAddHeaderFilter();}}public class InternalAddHeaderFilter : IResultFilter{public void OnResultExecuting(ResultExecutingContext context){context.HttpContext.Response.Headers.Add(Internal, new string[] { Header Add });}public void OnResultExecuted(ResultExecutedContext context){}} 2.排序 过滤器可以应用于操作方法或控制器通过特性或添加到全局过滤器集合中。作用域通常也决定了排序最接近操作的过滤器首先运行。 除了作用域过滤器还可以通过实现 IOrderedFilter 来重写它们的执行顺序。此接口简单的暴露了一个 int Order 属性并且过滤器基于该属性以数字升序执行。所有内置的过滤器包括 TypeFilterAttribute 和 ServiceFilterAttribute 都实现 IOrderedFilter 接口。因此当将过滤器特性应用于类或方法时可以指定过滤器执行顺序。默认情况下所有内置过滤器的 Order 属性都为0因此范围用作分隔符并且是决定性因素除非 Order 设置为 0。 每个从 Controller 基类继承的控制器都包含 OnActionExecuting 和 OnActionExecuted 方法。这些方法为给定操作包装了过滤器它们分别最先运行和最后运行。假设没有为任何过滤器设置 Order 舒总那么单纯基于范围的顺序为 控制器的 OnActionExecuting 全局过滤器的OnActionExecuting 类过滤器的OnActionExecuting 方法过滤器的OnActionExecuting 方法过滤器的OnActionExecuted 类过滤器的OnActionExecuted 全局过滤器的OnActionExecuted 控制器过滤器的OnActionExecuted 要修改默认的基于范围的顺序则应显示设置类级别或者方法级别过滤器的 Order 属性。例如将 Order -1 添加到方法级属性 [MyFilter (Name ...Order -1)] 在这种情况下小于零的值将确保此过滤器在全局和类级过滤器之前运行 控制器的 OnActionExecuting 方法过滤器的OnActionExecuting 全局过滤器的OnActionExecuting 类过滤器的OnActionExecuting 类过滤器的OnActionExecuted 全局过滤器的OnActionExecuted 控制器过滤器的OnActionExecuted 方法过滤器的OnActionExecuted Controller 类的方法总是在所有过滤器之前和之后运行。这些方法不作为IFilter实例实现。也不参与IFilter排序算法。 3.对比中间件 一般来说过滤器用于处理业务与应用程序的横切关注点用法和功能很像中间件但过滤器允许你将作用范围缩小并将其插入到应用程序中有意义的位置例如视图之前或模型绑定之后。过滤器是 MVC 的一部分可以访问其上下文和构造函数。例如中间件很难检测到请求的模型验证是否产生错误并且做出相应的响应。 转载于:https://www.cnblogs.com/afei-24/p/11334100.html