问题

如何在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. jdbc-日期格式的转换及代码示例

     时间类型相互转换 把数据库的三种时间类型赋给java.util.Date,基本不用转换,因为这是把子类对象给父类的引用,不需要转换. java.sql.Date date = - java.ut ...

  2. 选择排序的3种语言实现方法(C java python)

    1.选择排序的思路是:遍历数组,第一遍找出所有成员的最小值,放到数组下标为0的位置,第二遍从剩余内容中,再次找出最小值,放到数组下标为1的位置,以此类推,遍历完成所有的数组内容,最后结果就是:数组是按 ...

  3. 在不用Promise的情况下如何控制异步请求?

    如何更好的控制异步请求?相信大家一定首选Promise对象.确实,使用Promise控制异步请求确实非常方便,直接使用then()方法就可以实现当一个异步请求完成后再处理另一个请求或操作.同时,这样的 ...

  4. 【学习】js学习笔记:对象的遍历和封装特性

    1.对象的属性访问: 对象.属性 对象[属性],但中括号中必须是字符串 2.属性的遍历: for in方法举例: var ren={}; ren.name="名字"; ren.ea ...

  5. 运维&网络知识(一)

    1. DNS 域名系统(Domain Name System),因特网上作为域名和IP地址映射的一个分布式数据库.

  6. BeginInvoke()使用

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.I ...

  7. win10 uwp 进度条 WaveProgressControl

    昨天看到了有个大神做出好看的进度条样式,于是我就去抄袭他的代码,但是发现看不懂,于是本文主要翻译就是大神说这个控件如何做. 本文翻译 https://stackoverflow.com/a/46057 ...

  8. Ubuntu配置OpenStack 一:主机环境配置以及问题总结

    本文包含openstack配置的实验环境的基本步骤.在下面的步骤中将逐步讲解如何操作. 1.准备三台虚拟机 主机名字分别命名为controller.network.computer[desktop版或 ...

  9. 利用大白菜制作多系统启动U盘(win+ubuntu+PE+...)

    网上提供的方法很多都过时了,不适用,要不就是讲的不清楚 我结合http://www.xuebuyuan.com/848003.html大神的方案,加以研究,整理出了此篇文章 先看下最终成果: 好了,感 ...

  10. UVW源码漫谈(四)

    十一假期后就有点懒散,好长时间都没想起来写东西了.另外最近在打LOL的S赛.接触LOL时间不长,虽然平时玩的比较少,水平也相当菜,但是像这种大型的赛事有时间还是不会错过的.主要能够感受到选手们对竞技的 ...