.net core 过滤器

筛选器类型

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

筛选器添加

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”];

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值