问题

如何在ASP.NET Core的MVC请求管道之前和之后运行代码。

在一个空的项目中,更新 Startup 类以添加MVC的服务和中间件。

  1. publicvoid ConfigureServices

  2. (IServiceCollection services)

  3. {

  4. services.AddMvc();

  5. }

  6. publicvoid Configure(

  7. IApplicationBuilder app,

  8. IHostingEnvironment env)

  9. {

  10. app.UseMvc(routes =>

  11. {

  12. routes.MapRoute(

  13. name: "default",

  14. template: "{controller=Home}/{action=Index}/{id?}");

  15. });

  16. }

添加类来实现过滤器。

  1. publicclass ParseParameterActionFilter : Attribute, IActionFilter

  2. {

  3. publicvoid OnActionExecuting(ActionExecutingContext context)

  4. {

  5. object param;

  6. if (context.ActionArguments.TryGetValue("param", out param))

  7. context.ActionArguments["param"] = param.ToString().ToUpper();

  8. else

  9. context.ActionArguments.Add("param", "I come from action filter");

  10. }

  11. publicvoid OnActionExecuted(ActionExecutedContext context)

  12. {

  13. }

  14. }

在Home控制器中添加一个使用Action过滤器的操作方法,

  1. [ParseParameterActionFilter]

  2. public IActionResult ParseParameter(string param)

  3. {

  4. return Content($"Hello ParseParameter. Parameter: {param}");

  5. }

浏览到 / Home / ParseParameter; 你会看到的 -

讨论

筛选器在选择执行操作方法后运行。MVC为授权和缓存等内容提供了内置的过滤器。自定义过滤器对于封装要在动作方法之前或之后运行的可重用代码非常有用。

过滤器可能导致结果短路,即停止运行中的代码,并将结果返回给客户端。他们也可以通过服务容器注入 服务,这使得他们非常灵活。

过滤器接口

创建自定义过滤器需要实现您所需的过滤器类型的接口。大多数过滤器类型有两种类型的接口 - 同步和异步。

  1. publicclass HelloActionFilter : IActionFilter

  2. {

  3. publicvoid OnActionExecuting(ActionExecutingContext context)

  4. {

  5. // runs before action method

  6. }

  7. publicvoid OnActionExecuted(ActionExecutedContext context)

  8. {

  9. // runs after action method

  10. }

  11. }

  12. publicclass HelloAsyncActionFilter : IAsyncActionFilter

  13. {

  14. public async Task OnActionExecutionAsync(

  15. ActionExecutingContext context,

  16. ActionExecutionDelegate next)

  17. {

  18. // runs before action method

  19. await next();

  20. // runs after action method

  21. }

  22. }

您可以通过在上下文参数(对于异步过滤器,不要调用下一个 委托)中设置Result (类型 IActionResult)属性 来短路过滤器管道 。

  1. publicclass SkipActionFilter : Attribute, IActionFilter

  2. {

  3. publicvoid OnActionExecuting(ActionExecutingContext context)

  4. {

  5. context.Result = new ContentResult

  6. {

  7. Content = "I'll skip the action execution"

  8. };

  9. }

  10. publicvoid OnActionExecuted(ActionExecutedContext context)

  11. { }

  12. }

  13. [SkipActionFilter]

  14. public IActionResult SkipAction()

  15. {

  16. return Content("Hello SkipAction");

  17. }

对于结果过滤器,可以通过 在上下文参数上设置取消属性并发送响应来进行短路 。

  1. public void OnResultExecuting(ResultExecutingContext context)

  2. {

  3. context.Cancel = true ;

  4. context.HttpContext.Response.WriteAsync(“我将跳过结果执行” );

  5. }

  6. [SkipResultFilter]

  7. public IActionResult SkipResult()

  8. {

  9. 返回 内容(“Hello SkipResult” );

  10. }

过滤器属性

MVC提供了可以继承的抽象基类来创建自定义过滤器。这些抽象类继承自 Attribute 类,因此可以用来装饰控制器和操作方法。

  • ActionFilterAttribute

  • ResultFilterAttribute

  • ExceptionFilterAttribute

  • ServiceFilterAttribute

  • TypeFilterAttribute

过滤器类型

在过滤器管道的不同阶段有各种类型的过滤器。下面,官方文件中的一个数字说明了顺序:

授权

这是运行的第一个过滤器,并将对未经授权的用户的请求短路。他们只有一个方法(不同于其他大多数具有执行 和 执行 方法的过滤器 )。通常情况下,您不会编写自己的授权过滤器,内置过滤器调用到框架的授权机制中。

资源

它们在模型绑定之前运行,可以用来改变它的行为。而且,它们在结果生成后运行,可用于缓存等。

行动

它们在动作方法之前和之后运行,因此对操作动作参数或其结果非常有用。提供给这些过滤器的上下文让您可以操作动作参数,控制器和结果。

例外

它们可以在写入响应之前用于未处理的异常。异常处理中间件适用于大多数场景,但是如果您想根据调用的操作以不同方式处理错误,则可以使用此过滤器。

结果

如果结果成功,它们在执行操作方法的结果之前和之后运行。他们可以用来操纵结果的格式。

过滤范围

可以在不同级别的范围添加过滤器:Action,Controller和Global。属性用于动作和控制器级作用域。对于全局范围的过滤器,您需要添加它们以 在启动时配置服务时 过滤MvcOptions的集合 ,

  1. services.AddMvc(options =>

  2. {

  3. // by instance

  4. options.Filters.Add(new AddDeveloperResultFilter("Tahir Naushad"));

  5. // by type

  6. options.Filters.Add(typeof(GreetDeveloperResultFilter));

  7. });

过滤器按顺序执行

  1. 的 执行 方法是首先呼吁全球>控制器>动作过滤器。

  2. 然后 为Action> Controller> Global过滤器调用已执行的方法。

过滤依赖注入

为了使用需要在运行时注入依赖关系的过滤器,您需要通过Type添加它们。您可以将它们全局添加(如上所述),但是,如果要将它们应用于操作或控制器(作为属性),则有两个选项:

ServiceFilterAttribute

此属性使用服务容器检索过滤器。要使用它,

创建一个使用依赖注入的过滤器 ,

  1. publicclass GreetingServiceFilter : IActionFilter

  2. {

  3. private readonly IGreetingService greetingService;

  4. public GreetingServiceFilter(IGreetingService greetingService)

  5. {

  6. this.greetingService = greetingService;

  7. }

  8. publicvoid OnActionExecuting(ActionExecutingContext context)

  9. {

  10. context.ActionArguments["param"] =

  11. this.greetingService.Greet("James Bond");

  12. }

  13. publicvoid OnActionExecuted(ActionExecutedContext context)

  14. { }

  15. }

将过滤器添加到服务容器

  1. services.AddScoped<GreetingServiceFilter>();

使用ServiceFilterAttribute应用它

  1. [ServiceFilter(typeof(GreetingServiceFilter))]

  2. public IActionResult GreetService(string param)

TypeFilterAttribute

该属性不需要在服务容器中注册过滤器,并使用ObjectFactory 委托启动类型 。使用它

创建一个使用依赖注入的过滤器

  1. publicclass GreetingTypeFilter : IActionFilter

  2. {

  3. private readonly IGreetingService greetingService;

  4. public GreetingTypeFilter(IGreetingService greetingService)

  5. {

  6. this.greetingService = greetingService;

  7. }

  8. publicvoid OnActionExecuting(ActionExecutingContext context)

  9. {

  10. context.ActionArguments["param"] = this.greetingService.Greet("Dr. No");

  11. }

  12. publicvoid OnActionExecuted(ActionExecutedContext context)

  13. { }

  14. }

应用它使用 TypeFilterAttribute。

  1. [TypeFilter(typeof(GreetingTypeFilter))]

  2. public IActionResult GreetType1(string param)

你也可以从TypeFilterAttribute继承 ,然后在没有TypeFilter的情况下 使用,

  1. publicclass GreetingTypeFilterWrapper : TypeFilterAttribute

  2. {

  3. public GreetingTypeFilterWrapper() : base(typeof(GreetingTypeFilter))

  4. { }

  5. }

  6. [GreetingTypeFilterWrapper]

  7. public IActionResult GreetType2(string param)

更多精彩文章请关注我们的微信公众号FocusDotCore

基础教程:ASP.NET Core 2.0 MVC筛选器的更多相关文章

  1. ASP.NET Core 2.0 MVC项目实战

    一.前言 毕业后入职现在的公司快有一个月了,公司主要的产品用的是C/S架构,再加上自己现在还在学习维护很老的delphi项目,还是有很多不情愿的.之前实习时主要是做.NET的B/S架构的项目,主要还是 ...

  2. ASP.NET CORE 1.0 MVC API 文档用 SWASHBUCKLE SWAGGER实现

    from:https://damienbod.com/2015/12/13/asp-net-5-mvc-6-api-documentation-using-swagger/ 代码生成工具: https ...

  3. ASP.NET Core 基础教程 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 基础教程 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 是对 ASP.NET 有重大意义的一次重新设计.本章节我们将介绍 A ...

  4. asp.net core 3.0 MVC JSON 全局配置

    asp.net core 3.0 MVC JSON 全局配置 System.Text.Json(default) startup配置代码如下: using System.Text.Encodings. ...

  5. ASP.NET Core 3.0 gRPC 拦截器

    目录 ASP.NET Core 3.0 使用gRPC ASP.NET Core 3.0 gRPC 双向流 ASP.NET Core 3.0 gRPC 拦截器 一. 前言 前面两篇文章给大家介绍了使用g ...

  6. asp.net Core 2.0 MVC为Controller或Action添加定制特性实现登录验证

    前言:最近在倒腾 微软的新平台 asp.net Core 2.0,在这个过程中有些东西还是存在差异.下面是我在学习过程的一点笔记.有不妥之处,望各位大虾指正! 一.先创建一个控制器继承于Control ...

  7. 基础教程:视图中的ASP.NET Core 2.0 MVC依赖注入

    问题 如何在ASP.NET Core MVC Views中注入和使用服务. 解 更新 启动 类来为MVC添加服务和中间件. 添加一项服务 添加一个Controller,返回 ViewResult. 添 ...

  8. ASP.NET Core 5.0 MVC中的 Razor 页面 介绍

    Razor 是一个用于将基于服务器的代码嵌入到网页中的标记语法. Razor语法由 Razor 标记.c # 和 HTML 组成. 通常包含 Razor 的文件的扩展名 cshtml Razor 语法 ...

  9. ASP.Net Core 5.0 MVC 配置文件读取,Startup 类中ConfigureServices 方法、Configure 方法的使用

    配置文件读取 1. 新建FirstController控制器 在appsettings文件内容替换成以下代码 { "Position": { "Title": ...

随机推荐

  1. 学习如何看懂SQL Server执行计划(三)——连接查询篇

    三.连接查询部分 --------------------嵌套循环-------------------- /* UserInfo表数据少.Coupon表数据多嵌套循环可以理解为就是两层For循环,外 ...

  2. gulp使用1-入门指南

    入门指南 1. 全局安装 gulp: $ npm install --global gulp 或使用cnpm 2. 作为项目的开发依赖(devDependencies)安装: $ npm instal ...

  3. Jmeter脚本录制方法(二)——手工编写脚本(jmeter与fiddler结合使用)

    jmeter脚本录制方法可以分三种,前几天写的一篇文章中,已介绍了前两种,今天来说下第三种,手工编写脚本,建议使用这一种方法,虽然写的过程有点繁琐,但调试脚本比前两者方式都要便捷. 首先来看下三种方式 ...

  4. c#字符编码,System.Text.Encoding类,字符编码大全:如Unicode编码、GB18030、UTF-8,UTF-7,GB2312,ASCII,UTF32,Big5

    本页列出来目前window下所有支持的字符编码  ---c#通过 System.Text.Encoding.GetEncodings()获取,里面可以对其进行查询,筛选,对同一个字符,在不同编码进行查 ...

  5. MxNet新前端Gluon模型转换到Symbol

    1. 导入各种包 from mxnet import gluon from mxnet.gluon import nn import matplotlib.pyplot as plt from mxn ...

  6. java 静态代码块 代码块 构造函数 静态成员变量 成员变量的初始化顺序

    没有父类的情况 1,静态代码块-->静态成员变量-->成员变量(实例属性)-->代码块-->构造函数 2, 静态代码块 和 静态成员变量 只会初始化一次 有父类的情况 1,父类 ...

  7. MV45AFZZ 销售订单的增强

    ***INCLUDE MV45AFZZ . *---------------------------------------------------------------------* * FORM ...

  8. 通过VBA,当在EXCEL单元格中输入任意的日期格式时,都能自动转换为指定的标准格式的日期值

    在日常录入EXCEL表格的单元格里 ,我们输入一些一般性的日期内容,如:2017-10-17 或 2017/10/17时,EXCEL会自动识别为日期并按单元格设计格式显示,单元格中存储的值也是日期格式 ...

  9. win10 UWP 剪贴板 Clipboard

    win10 UWP 剪贴板 Clipboard使用Windows.ApplicationModel.DataTransfer.Clipboard 设置文本 DataPackage dataPackag ...

  10. 使用vim编写hexo文档,并用ultisnips/snipmates/snippets插件补全

    作为一个vim使用者,编写markdown文档时若不能用vim这怎么能受的了! 下面是我编写markdown的时候用到的插件 Plugin 'Markdown'Plugin 'Markdown-syn ...