微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Ultimate ASP.NET CORE 6.0 Web API --- 读书笔记15

15 Action Filters

本文内容来自书籍: Marinko Spasojevic - Ultimate ASP.NET Core Web API - From Zero To Six-figure Backend Developer (2nd edition)

  • Authorization filters,放在最前面,决定了请求是否有权限访问
  • Resource filters,就在授权过滤器的后面,在缓存性能很有用
  • Action filters,在action的前后执行
  • Exception filters,在填充响应体之前,处理异常
  • Result filters,它们在操作方法结果执行之前和之后运行

这个章节只介绍Action filter

要创建Action filter,有几种不同实现

  • IActionFilter
  • IAsyncActionFilter
  • ActionFilterattribute

如果是同步方式实现,需要实现OnActionExecutingOnActionExecuted

public class ActionFilterExample : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // our code before action executes
    }
    public void OnActionExecuted(ActionExecutedContext context)
    {
        // our code after action executes
    }
}

如果是异步方式实现,需要实现OnActionExecutionAsync

public class AsyncActionFilterExample : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(ActionExecutingContext context,
    ActionExecutionDelegate next)
    {
        // execute any code before the action executes
        var result = await next();
        // execute any code after the action executes
    }
}

15.2 The Scope of Action Filters

过滤器有几种范围

  • Global
// Program.cs
builder.Services.AddControllers(config =>
{
    config.Filters.Add(new GlobalFilterExample());
});
  • Action
  • Controller
// Program.cs
builder.Services.AddScoped<ActionFilterExample>();
builder.Services.AddScoped<ControllerFilterExample>();

// Controller
[ServiceFilter(typeof(ControllerFilterExample))]
[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
    [HttpGet]
    [ServiceFilter(typeof(ActionFilterExample))]
    public IEnumerable<string> Get()
    {
        return new string[] { "example", "data" };
    }
}

15.3 Order of Invocation

这是认的执行顺序,也可以通过添加order属性,来改变执行顺序

[ServiceFilter(typeof(ControllerFilterExample), Order = 2)]
[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
    [HttpGet]
    [ServiceFilter(typeof(ActionFilterExample), Order = 1)]
    public IEnumerable<string> Get()
    {
        return new string[] { "example", "data" };
    }
}

15.5 Validation with Action Filters

前面的章节介绍过,我们的业务逻辑代码中,没有try-catch块,都提取到全局异常处理的中间件了,但是现在可以使用Action filter来更进一步处理

现在从POSTPUT的逻辑代码中,可以看到相似的验证逻辑

if (company is null)
    return BadRequest("CompanyForUpdateDto object is null");
if (!ModelState.IsValid)
    return UnprocessableEntity(ModelState);

然后我们可以将验证逻辑提取出来,重复使用

public class ValidationFilterattribute : IActionFilter
{
    public ValidationFilterattribute()
    {
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        var action = context.RouteData.Values["action"];
        var controller = context.RouteData.Values["controller"];
        var param = context.ActionArguments
            .SingleOrDefault(x => x.Value.ToString().Contains("Dto")).Value;
        if (param is null)
        {
            context.Result = new BadRequestObjectResult($"Object is null. Controller:{controller}, action: {action}");
            return;
        }

        if (!context.ModelState.IsValid)
            context.Result = new UnprocessableEntityObjectResult(context.ModelState);
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐