.net core 过滤器

本文深入探讨了ASP.NET Core MVC中筛选器的概念与应用,包括授权、资源、操作、异常和结果筛选器的执行流程及实现方式,提供了丰富的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

筛选器类型

每种筛选器类型都在筛选器管道中的不同阶段执行。
授权筛选器:最先运行,用于确定是否已针对当前请求为当前用户授权。 如果请求未获授权,它们可以让管道短路。
资源筛选器:是授权后最先处理请求的筛选器。 出于性能方面的考虑,可以使用它们来实现缓存或以其他方式让筛选器管道短路。 它们在模型绑定之前运行,所以可以影响模型绑定。
操作筛选器:可以在调用单个操作方法之前和之后立即运行代码。 它们可用于处理传入某个操作的参数以及从该操作返回的结果。
异常筛选器:用于在向响应正文写入任何内容之前,对未经处理的异常应用全局策略。
结果筛选器:可以在执行单个操作结果之前和之后立即运行代码。 仅当操作方法成功执行时,它们才会运行。 对于必须围绕视图或格式化程序的执行的逻辑,它们很有用。

筛选器添加

services.AddMvc (options => {
    options.Filters.Add (typeof (MemberIdFilter));
})

授权筛选器

实现IAsyncAuthorizationFilter接口

public class ApiAuthorizationAttribute : Attribute, IAsyncAuthorizationFilter {
    public async Task OnAuthorizationAsync (AuthorizationFilterContext context) {
        ....
        if (!authorizationResult.Succeeded) {
            // 禁止访问
            context.Result = new ForbidResult ();
        }
    }
}

资源筛选器

实现 IResourceFilter 或 IAsyncResourceFilter 接口,
如果需要使某个请求正在执行的大部分工作短路,资源筛选器会很有用。 例如,如果响应在缓存中,则缓存筛选器可以绕开管道的其余阶段。

操作筛选器

实现 IActionFilter 或 IAsyncActionFilter 接口。
下面是一个操作筛选器示例:

public class MemberIdFilter : IAsyncActionFilter {
    private IHttpContextAccessor _httpContextAccessor { get; set; }

    public MemberIdFilter (IHttpContextAccessor httpContextAccessor) {
        _httpContextAccessor = httpContextAccessor;
	}

    public async Task OnActionExecutionAsync (
        ActionExecutingContext context,
        ActionExecutionDelegate next) {
        // 已认证
        if (_httpContextAccessor.HttpContext.User != null) {
            .......
        }

        await next ();
    }
}

异常筛选器

异常筛选器可实现 IExceptionFilter 或 IAsyncExceptionFilter 接口。
下面的异常筛选器示例使用自定义开发人员错误视图,显示在开发应用时发生的异常的相关详细信息:

public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
    private readonly IHostingEnvironment _hostingEnvironment;
    private readonly IModelMetadataProvider _modelMetadataProvider;

    public CustomExceptionFilterAttribute(
        IHostingEnvironment hostingEnvironment,
        IModelMetadataProvider modelMetadataProvider)
    {
        _hostingEnvironment = hostingEnvironment;
        _modelMetadataProvider = modelMetadataProvider;
    }
    public override void OnException(ExceptionContext context)
    {
        if (!_hostingEnvironment.IsDevelopment())
        {
            // do nothing
            return;
        }
        var result = new ViewResult {ViewName = "CustomError"};
        result.ViewData = new ViewDataDictionary(_modelMetadataProvider,context.ModelState);
        result.ViewData.Add("Exception", context.Exception);
        // TODO: Pass additional detailed data via ViewData
        context.Result = result;
    }
}

若要处理异常,请将 ExceptionContext.ExceptionHandled 属性设置为 true,或编写响应。 这将停止传播异常。

结果筛选器

实现 IResultFilter 或 IAsyncResultFilter 接口。
下面是一个添加 HTTP 标头的结果筛选器示例。

public class AddHeaderFilterWithDi : IResultFilter {
    private ILogger _logger;
    
    public AddHeaderFilterWithDi (ILoggerFactory loggerFactory) {
        _logger = loggerFactory.CreateLogger<AddHeaderFilterWithDi> ();
    }

    public void OnResultExecuting (ResultExecutingContext context) {
        var headerName = "OnResultExecuting";
        context.HttpContext.Response.Headers.Add (
            headerName, new string[] { "ResultExecutingSuccessfully" });
        _logger.LogInformation ($"Header added: {headerName}");
	}

    public void OnResultExecuted (ResultExecutedContext context) {
        // Can't add to headers here because response has already begun.
    }
}

关于context参数的数据

1.获取控制器名称代码
MVC Core中需强行转下
var controllerName = ((Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor)filterContext.ActionDescriptor).ControllerName;

2.获取Action名称代码
var actionName = filterContext.ActionDescriptor.ActionName;

3.获取Action参数名称
//获取参数数组
var arrParameter = filterContext.ActionDescriptor.GetParameters();
//根据索引获取对应参数名
var paramName = arrParameter[0].ParameterName;

4.获取参数值
var parameterValue = filterContext.Controller.ValueProvider.GetValue(paramName).RawValue;
如果可以确定参数名称可以直接用ActionParameters通过Key来获取,Key指参数名称
var parameterValue = filterContext.ActionParameters[“KeyName”];

在 ASP.NET Core 中,过滤器和中间件是两种用于处理请求和响应的机制,但它们的作用范围和使用场景有所不同。 ### 过滤器(Filters) 过滤器主要用于 MVC 或 Razor Pages 应用程序中,在特定的动作或控制器执行前后添加逻辑。它们可以用来实现日志记录、授权、异常处理等功能。 #### 过滤器的类型 1. **Authorization Filters**:在模型绑定之前执行,用于检查用户是否有权访问某个资源。 2. **Resource Filters**:在模型绑定之后和操作执行之前执行,适用于需要访问请求或响应的场景。 3. **Action Filters**:在动作方法执行前后执行,可以用来修改输入或输出。 4. **Exception Filters**:捕获整个应用程序中的未处理异常。 5. **Result Filters**:在操作结果执行前后执行,可以用来修改视图或数据。 #### 示例代码 - 创建一个简单的 Action Filter ```csharp public class SampleActionFilter : IActionFilter { public void OnActionExecuting(ActionExecutingContext context) { // 在动作执行前执行的逻辑 Console.WriteLine("Action is about to execute..."); } public void OnActionExecuted(ActionExecutedContext context) { // 在动作执行后执行的逻辑 Console.WriteLine("Action has executed."); } } ``` 要将这个过滤器应用到控制器或动作上,可以使用特性: ```csharp [TypeFilter(typeof(SampleActionFilter))] public IActionResult Index() { return View(); } ``` ### 中间件(Middleware) 中间件是一系列组件,它们按顺序处理请求和响应。每个中间件组件可以选择是否将请求传递给下一个组件,并可以在传递前后执行自定义逻辑。中间件非常适合处理跨切面关注点,如身份验证、错误处理、静态文件服务等。 #### 示例代码 - 创建一个简单的中间件 ```csharp public class SimpleMiddleware { private readonly RequestDelegate _next; public SimpleMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext httpContext) { // 在请求处理前执行的逻辑 Console.WriteLine("Before request processing..."); if (_next != null) { await _next(httpContext); // 调用下一个中间件 } // 在请求处理后执行的逻辑 Console.WriteLine("After request processing..."); } } ``` 要将中间件添加到管道中,需要在 `Startup.cs` 的 `Configure` 方法中注册它: ```csharp public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseMiddleware<SimpleMiddleware>(); app.Run(async (context) => { await context.Response.WriteAsync("Hello World!"); }); } ``` ### 解释 - **过滤器** 是专门为 MVC 和 Razor Pages 设计的,通常用于与具体的动作或控制器相关的逻辑。 - **中间件** 则更加通用,适合处理所有请求的全局逻辑。 #### 区别总结 | 特性 | 过滤器 | 中间件 | |-------------------|----------------------------------|----------------------------------| | 适用范围 | MVC/Razor Pages | 所有请求 | | 注册方式 | 使用特性或全局配置 | 在 `Startup.Configure` 方法中注册 | | 生命周期控制 | 动作级别的生命周期控制 | 请求级别的生命周期控制 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值