Asp.Net Core 轻松学-被低估的过滤器 (3)

操作过滤器包含 6 个基础方法,分别是执行前(before)执行后(after),写入结果前(before)写入后(after)
为什么会这样呢,因为操作过滤器实现的接口中包含了结果过滤器的接口
根据官方的提示,如果你需要重写 ActionFilterAttribute 的方法以处理自定义的业务逻辑,那么 OnActionExecutionAsync 这个异步方法不应该和 执行前(before)执行后(after)同时共存
同样,写入结果前(before)写入后(after)和 OnResultExecutionAsync 也是一样

6.2 操作过滤器包含了 写入结果前(before)写入后(after)的方法,这使得我们可以不用去定义结果过滤器就可以实现对写入结果的管理

当然,最好的做法是定义结果过滤器,这有助于业务分类,且逻辑清晰明了,但是如果你希望可以使用异步操作,很遗憾,结果过滤器不支持该方法

6.3 下面来看结果过滤的定义

public class CustomerResultFilter : Attribute, IResultFilter { public void OnResultExecuted(ResultExecutedContext context) { Console.WriteLine("OnResultExecuted"); } public void OnResultExecuting(ResultExecutingContext context) { Console.WriteLine("OnResultExecuting"); } }

代码非常简单,就是实现接口 IResultFilter
IResultFilter 的工作原理和操作过滤器的写入结果前(before)写入后(after)的方法执行一致,可以看到,他们两个方法和参数名称都是一致的,因为他们都是实现同一个接口 IResultFilter

6.4 利用结果过滤器实现对输出结果的干预

下面就简单在结果过滤器内部去对已经组织好的数据进行干预,HomeController.Get 方法本应该输出 一个数组,我们在Header 中增加一项输出:Author=From Ron.liang

public class CustomerResultFilter : Attribute, IResultFilter { public void OnResultExecuted(ResultExecutedContext context) { // ToDo } public void OnResultExecuting(ResultExecutingContext context) { // 干预结果 context.HttpContext.Response.Headers.Add("Author", "From Ron.liang"); } }

6.5 输出结果

Asp.Net Core 轻松学-被低估的过滤器

7.在过滤器中使用依赖注入

在上面介绍的各种各样的过滤器中,有时候我们可能需要读取程序运行环境的信息,根据不同的环境做出不同的响应内容
比如,上面的结果过滤器写入作者信息,可能我们只希望在开发环境输出,而在产品环境忽略

7.1 使用 GetService,以支持依赖注入

public void OnResultExecuting(ResultExecutingContext context) { var env = (IHostingEnvironment)context.HttpContext.RequestServices.GetService(typeof(IHostingEnvironment)); Console.ForegroundColor = ConsoleColor.Blue; Console.WriteLine("OnResultExecuting,{0}", env.EnvironmentName); Console.ForegroundColor = ConsoleColor.Gray; // 干预结果 if (env.IsDevelopment()) context.HttpContext.Response.Headers.Add("Author", "From Ron.liang"); }

上面的从 context.HttpContext.RequestServices.GetService(typeof(IHostingEnvironment)) 获取了环境变量,并判断在开发环境下为响应头添加内容

7.2 在过滤器中使用中间件

Asp.Net Core 提供了一个功能,使得我们在过滤器中可以使用中间件,实际上,这两者的使用方式非常类似
如果你希望这么做,可以定义一个包含 Configure(IApplicationBuilder applicationBuilder) 方法的类,在控制器或者操作中使用它

7.3 定义注册管理管道类

public class RegisterManagerPipeline { public void Configure(IApplicationBuilder applicationBuilder) { CookieAuthenticationOptions options = new CookieAuthenticationOptions(); applicationBuilder.UseCors(config => { config.AllowAnyOrigin(); }); } }

RegisterManagerPipeline 定义了一个 Configure 方法,在该方法内部执行一个跨域设置,表示允许任何来源访问该站点;然后,我们在 UserController 中应用该管道

[Authorize] [Route("api/[controller]")] [MiddlewareFilter(typeof(RegisterManagerPipeline))] public class UserController : Controller { // GET: api/<controller> [AllowAnonymous] [HttpGet] public ActionResult<string> Get() { return "default"; } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjxpp.html