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

2022/6/17 1:20:12

本文主要是介绍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)
    {
    }
}


这篇关于Ultimate ASP.NET CORE 6.0 Web API --- 读书笔记(15)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程