问题

如何在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. 关于python中的pickle函数

    8-7参考阅读 - 读文件.写文件.异常处理.文件保存游戏.pickle数据转成文本的过程又被称为"序列化",即将对象状态转换为可保持或传输的格式的过程.对应的,从序列化的格式中解 ...

  2. 从 JavaScript 到 TypeScript 系列

    随着应用的庞大,项目中 JavaScript 的代码也会越来越臃肿,这时候许多 JavaScript 的语言弊端就会愈发明显,而 TypeScript 的出现,就是着力于解决 JavaScript 语 ...

  3. 面试题:使用LinkedList来模拟一个堆栈或者队列数据结构

    请使用LinkedList来模拟一个堆栈或者队列数据结构. 堆栈:先进后出 First In Last Out  (FILO) 队列:先进先出 First In First Out  (FIFO) 我 ...

  4. js的解析顺序 作用域 严格模式

    一.javascript的解析顺序 我们大家所理解的代码的执行顺序都是从上到下的,但是实际上确不是这样的.我们看一下下面的代码. 1 alert(a); 2 var a = 1; 如果执行顺序是从上到 ...

  5. C++基础知识2

    2 变量和基本类型 2.1 基本内置类型 C++定义了一系列包括算术类型(arithmetic type)和空类型(void)在内的基本数据类型.其中算术类型包含字符,整型数,布尔值和浮点数.空类型不 ...

  6. Linux系统EXT文件系统

    分区格式化(Linux创建文件系统):(假设需要格式化的分区为/dev/sdb1) 1. ext2文件系统和ext3文件系统的区别: ext2不支持日志文件系统,不会产生日志文件,ext3则会产生日志 ...

  7. 我搞zabbix的那两天

    摘要:在生产环境上对服务器进行网络参数(比如CPU.内存等)的监控是很必要的,比如当服务器网络参数如内存不够用.磁盘空间快要占满时及时通知运维人员进行处理,保证服务器系统的安全.而zabbix就是这么 ...

  8. 1_ROS学习

    1_搭建树莓派环境 树莓派是一个嵌入式计算机,专门用来做嵌入式开发的.我们组上用的树莓派是raspberry pi 3 mode B,5V供电,最大电流不超过2A: 我们需要在树莓派上安装上操作系统. ...

  9. .1-Vue源码起步

    搞事!搞事! 截止2017.5.16,终于把vue的源码全部抄完,总共有9624行,花时大概一个月时间,中间迭代了一个版本(2.2-2.3),部分代码可能不一致,不过没关系! 上一个链接https:/ ...

  10. java7大排序算法

    1.冒泡排序 package lizicong; import java.util.Scanner; public class BubbleSort { /* * 属于交换排序:稳定 * 排序原理:相 ...