【aspnetcore】在过滤器(Filter)中使用注入服务(ServiceFilter|TypeFilter)
在MVC中,AOP是很常用的功能,我们经常会使用如 ActionFilter,IAuthorizeFilter 等描述对Controller和Action进行约束和扩展,一般做法如下:
public class TestActionFilterAttribute : Attribute, IActionFilter
{ public void OnActionExecuted(ActionExecutedContext context)
{
if (context.HttpContext.Request.Query.TryGetValue("id", out StringValues value))
{
Console.WriteLine(value.First());
}
else
{
context.HttpContext.Response.Redirect("/Error/404");
}
} public void OnActionExecuting(ActionExecutingContext context)
{ }
}
上面的代码很简单,就是判断请求中是否包含id参数,如果有,则打印id;如果没有,则跳转到错误页面。用法也很简单,在需要约束的Action上添加[TestActionFilter]即可。
[TestActionFilter]
public IActionResult Index()
{
return View();
}
这是Filter最基本的用法,但是,如果我们需要在Filter中使用注入的服务怎么办?比如说修改下 TestActionFilterAttribute:
public class TestActionFilterAttribute : Attribute, IActionFilter
{
private readonly ILogger _logger; public TestActionFilterAttribute(ILoggerFactory logger)
{
_logger = logger.CreateLogger("TestActionFilterAttribute");
} public void OnActionExecuted(ActionExecutedContext context)
{
var path = context.HttpContext.Request.Path;
_logger.LogDebug($"{path} 开始运行了");
} public void OnActionExecuting(ActionExecutingContext context)
{ }
}
我们在Filter的构造函数中注入ILoggerFactory参数,这是系统默认提供的日志工厂服务,用来在控制台打印消息。
回到Controller文件,发现[TestActionFilter]报错:未提供与"TestActionFilterAttribute"的必需形参logger对应的实参。好吧,下面我们尝试构造一个logger对象
public class HomeController : Controller
{
private readonly ILoggerFactory _loggerFactory; public HomeController(ILoggerFactory factory)
{
_loggerFactory = factory;
} [TestActionFilter(_loggerFactory)]
public IActionResult Index()
{
return View();
}
}
修改过后,继续报错:特性构造函数参数"logger"具有类型ILoggerFactory,这不是有效特性参数类型。由此可见,如果在Filter中需要注入服务,常规的方式是无法实现的。
如果一定需要调用注入服务该怎么实现呢?其实框架已经为我们提供了两种途径:TypeFilter和ServiceFilter
public class TestTypeFilter : IActionFilter
{
private readonly ILogger _logger; public TestTypeFilter(ILoggerFactory logger)
{
_logger = logger.CreateLogger("TestTypeFilter");
} public void OnActionExecuted(ActionExecutedContext context)
{
var path = context.HttpContext.Request.Path;
_logger.LogDebug($"{path} 开始运行了");
} public void OnActionExecuting(ActionExecutingContext context)
{ }
}
这里的代码和上面修改过的TestActionFilterAttribute一模一样,修改下Controller文件:
[TypeFilter(typeof(TestTypeFilter))]
public IActionResult Index()
{
return View();
}
运行测试,效果如下:
可以看到,代码运行正常。
下面再看看ServiceFilter的用法,新建文件 TestServiceFilter
public class TestServiceFilter : IActionFilter
{
private readonly ILogger _logger; public TestServiceFilter(ILoggerFactory logger)
{
_logger = logger.CreateLogger("TestServiceFilter");
} public void OnActionExecuted(ActionExecutedContext context)
{
var path = context.HttpContext.Request.Path;
_logger.LogDebug($"{path} 开始运行了");
} public void OnActionExecuting(ActionExecutingContext context)
{ }
}
修改Controller文件:
//[TypeFilter(typeof(TestTypeFilter))]
[ServiceFilter(typeof(TestServiceFilter))]
public IActionResult Index()
{
return View();
}
仅仅这样是不够的,顾名思义,ServiceFilter(服务过滤器),我们需要到startup.cs的ConfiguraionServices中注册TestServiceFilter:
services.AddSingleton<TestServiceFilter>();
运行测试,效果如下:
OK,运行正常!
下面是补充内容,添加一个全局异常过滤器:
新建文件 MvcGlobalExceptionFilter.cs
public class MvcGlobalExceptionFilter : IExceptionFilter
{
private readonly ILogger _logger; public MvcGlobalExceptionFilter(ILoggerFactory logger)
{
_logger = logger.CreateLogger("MvcGlobalExceptionFilter");
} public void OnException(ExceptionContext context)
{
// 全局异常的错误处理
_logger.LogError(context.Exception, "全局异常");
}
}
修改Startup.cs中的ConfigurationServices:
services.AddMvc(options =>
{
// 添加全局异常
options.Filters.Add<MvcGlobalExceptionFilter>();
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
修改Controller文件,手动抛出异常:
[ServiceFilter(typeof(TestServiceFilter))]
public IActionResult Index()
{
throw new Exception("异常测试,这是手动抛出的异常");
return View();
}
运行测试,效果如下:
可以看到,我们定义的过滤器捕获并打印了异常信息。
【aspnetcore】在过滤器(Filter)中使用注入服务(ServiceFilter|TypeFilter)的更多相关文章
- java 过滤器Filter中chain.doFilter()之前和之后代码的执行顺序
过滤器拦截到响应url的请求后会先执行doFilter()方法中chain.doFilter()之前的代码,然后执行下一个过滤器或者servelt.紧接着执行chain.doFilter()之后的代码 ...
- .Net Core中依赖注入服务使用总结
一.依赖注入 引入依赖注入的目的是为了解耦和.说白了就是面向接口编程,通过调用接口的方法,而不直接实例化对象去调用.这样做的好处就是如果添加了另一个种实现类,不需要修改之前代码,只需要修改注入的地方将 ...
- FluentValidation 验证(二):WebApi 中使用 注入服务
比如你要验证用户的时候判断一下这个用户名称在数据库是否已经存在了,这时候FluentValidation 就需要注入查询数据库 只需要注入一下就可以了 public class Login3Reque ...
- IoC容器Autofac(5) - Autofac在Asp.net MVC Filter中的应用
Autofac结合EF在MVC中的使用,上一篇IoC容器Autofac(4) - Autofact + Asp.net MVC + EF Code First(附源码)已经介绍了.但是只是MVC中Co ...
- 如何在自定义Filter中优雅的实现静态资源放行
在javaweb开发中,过滤器Filter比较常用于类似登录的拦截等场景.但是,当过滤器的配置不当时就会把所有的请求都拦截,静态资源也会被拦截掉,导致静态页面加载不出来. 一般的解决方 ...
- .NET 使用自带 DI 批量注入服务(Service)和 后台服务(BackgroundService)
今天教大家如何在asp .net core 和 .net 控制台程序中 批量注入服务和 BackgroundService 后台服务 在默认的 .net 项目中如果我们注入一个服务或者后台服务,常规的 ...
- servlet filter中使用autowired无法注入
问题: 我们为了避免未经授权的人直接通过url访问我们的页面,配置了如下filter <!-- 登录过滤器 --> <filter> <filter-name>se ...
- ASP.NET Core中使用自定义MVC过滤器属性的依赖注入
除了将自己的中间件添加到ASP.NET MVC Core应用程序管道之外,您还可以使用自定义MVC过滤器属性来控制响应,并有选择地将它们应用于整个控制器或控制器操作. ASP.NET Core中常用的 ...
- 避免在ASP.NET Core 3.0中为启动类注入服务
本篇是如何升级到ASP.NET Core 3.0系列文章的第二篇. Part 1 - 将.NET Standard 2.0类库转换为.NET Core 3.0类库 Part 2 - IHostingE ...
随机推荐
- php filter 安全过滤函数
转自:http://www.blags.org/archives/741.html php 利用filter 扩展编写的参数处理静态类,欢迎使用.希望大家看得开心,用得放心. <?php /** ...
- 通过 :hover 伪元素控制其他元素
---代码 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <tit ...
- requireJS 加载css、less文件
-- requireJS 同样可以加载css 文件,有require-css的插件,只需要把插件放入main.js同文件夹,在依赖处 采用 ‘css! test.css’的形式就可以加载css文件 - ...
- 谈谈java中成员变量与成员方法继承的问题
谈谈java中成员变量与成员方法继承的问题 关于成员变量和成员方法的的继承问题,我也可以做一个小测试,来看看结果. 首先我们先创建一个父类:
- kallsyms
kallsyms 在v2.6.0的内核中,为了更好地调试内核,引入新的功能kallsyms.kallsyms把内核用到的所有函数地址和名称连接进内核文件,当内核启动后,同时加载到内存中.
- gulp --- 前端自动化构建工具
目录 1. gulp使用步骤 1.1 安装Node.js 1.2 全局安装gulp 1.3 安装项目依赖包gulp 1.3.1 了解package.json 1.3.2 根据package.json安 ...
- H264解码器源码(Android 1.6 版)
H264解码器源码,移植ffmpeg中的H264解码部分到Android,深度删减优化,在模拟器(320x480)中验证通过. 程序的采用jni架构.界面部分,文件读取,视频显示都是用java做的,底 ...
- Win32环境下代码注入与API钩子的实现
本文详细的介绍了在Visual Studio(以下简称VS)下实现API钩子的编程方法,阅读本文需要基础:有操作系统的基本知识(进程管理,内存管理),会在VS下编写和调试Win32应用程序和动态链接库 ...
- CSS:CSS 单位
ylbtech-CSS:CSS 单位 1.返回顶部 1. 尺寸 单位 描述 % 百分比 in 英寸 cm 厘米 mm 毫米 em 1em 等于当前的字体尺寸. 2em 等于当前字体尺寸的两倍. 例如, ...
- bzoj4827
FFT+数学 先开始觉得枚举c就行了,不过我naive了 事实上c是确定的,通过化简式子可以得出一个二次函数,那么c就可以解出来了. 然后把a翻转,fft一下就行了 难得的良心题 #include&l ...