.NET 自定义过滤器 - ActionFilterAttribute

24 篇文章 0 订阅
13 篇文章 0 订阅

这个代码片段定义了一个自定义的 ASP.NET Core 过滤器(GuardModelStateAttribute),用于在控制器动作执行之前验证模型状态(ModelState)。如果模型状态无效,则构造一个 ProblemDetails 对象来描述错误,并返回一个 BadRequest 响应。

代码片段:

/// <summary>
/// 验证 ModelState 是否有效
/// </summary>
public class GuardModelStateAttribute : ActionFilterAttribute
{
    // <summary>
    /// 在执行操作之前进行验证。
    /// 如果模型状态无效,则返回 BadRequest 响应。
    /// </summary>
    /// <param name="context">Action 执行上下文</param>
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        // 验证 ModelState 是否有效
        if (!context.ModelState.IsValid)
        {
            // 构造 ProblemDetails 对象来构建错误响应
            var problemDetails = new ProblemDetails
            {
                Title = "Bad Request",                          // 错误标题
                Detail = "参数验证失败,请检查输入参数",           // 错误详情
                Status = (int)HttpStatusCode.BadRequest,        // HTTP 状态码
                Instance = context.HttpContext.Request.Path,    // 请求路径
            };

            // 遍历 ModelState 字典,将错误信息添加到 Extensions 字典中
            foreach (var key in context.ModelState.Keys)
            {
                // 获取每个键对应的错误信息
                var errors = context.ModelState[key]?.Errors;
                // 如果没有错误信息,则跳过
                if (errors is not { Count: > 0 }) continue;

                // 遍历每个错误,并将其添加到 ProblemDetails 的 Extensions 字典中
                foreach (var error in errors)
                {
                    problemDetails.Extensions.Add(key, error.ErrorMessage);
                }
            }

            // 设置响应结果
            context.Result = new BadRequestObjectResult(problemDetails);
        }
    }
}

代码解读

  1. 类定义

    public class GuardModelStateAttribute : ActionFilterAttribute
    
    • GuardModelStateAttribute 继承自 ActionFilterAttribute,这是一个内置的过滤器接口,用于在执行控制器动作前后执行一些逻辑。
  2. 覆盖 OnActionExecuting 方法

    public override void OnActionExecuting(ActionExecutingContext context)
    
    • OnActionExecuting 方法是在控制器动作执行之前调用的。覆盖这个方法可以让我们在动作执行前做一些预处理工作。
  3. 验证模型状态

    if (!context.ModelState.IsValid)
    
    • ModelState.IsValid 是一个布尔属性,表示模型状态是否有效。如果为 false,表示模型状态无效,即请求中的数据未通过验证。
  4. 构造 ProblemDetails 对象

    var problemDetails = new ProblemDetails
    {
        Title = "Bad Request",
        Detail = "参数验证失败,请检查输入参数",
        Status = (int)HttpStatusCode.BadRequest,
        Instance = context.HttpContext.Request.Path,
    };
    
    • ProblemDetails 是一个标准的对象,用于描述 HTTP 错误响应。这里设置了错误标题、详细信息、HTTP 状态码(400 Bad Request)以及请求的路径。
  5. 收集并附加错误信息

    foreach (var key in context.ModelState.Keys)
    {
        var errors = context.ModelState[key]?.Errors;
        if (errors is not { Count: > 0 }) continue;
    
        foreach (var error in errors)
        {
            problemDetails.Extensions.Add(key, error.ErrorMessage);
        }
    }
    
    • 遍历 ModelState 中的所有键值对,获取每个字段的验证错误信息,并将这些错误信息添加到 ProblemDetailsExtensions 字典中。
  6. 设置响应结果

    context.Result = new BadRequestObjectResult(problemDetails);
    
    • 设置 ActionExecutingContextResult 属性,返回一个包含 ProblemDetailsBadRequestObjectResult,这将导致控制器不再继续执行,并返回一个带有错误信息的 HTTP 响应。

作用

这个自定义过滤器的作用是:

  • 验证模型状态:在控制器动作执行之前验证请求中的数据是否满足验证规则。
  • 返回错误响应:如果数据验证失败,则构造一个包含详细错误信息的 ProblemDetails 对象,并返回一个 BadRequest 响应。
  • 简化错误处理:通过在过滤器中集中处理模型状态验证,可以减少在每个控制器动作中重复编写类似的错误处理逻辑。

使用方法

// Add services to the container.
#region 向容器中添加服务

// 关闭默认模型验证过滤器
builder.Services.Configure<ApiBehaviorOptions>(options => options.SuppressModelStateInvalidFilter = true);

builder.Services.AddControllers(options =>
{
    // 添加过滤器
    options.Filters.Add<GuardModelStateAttribute>();
})
.AddNewtonsoftJson(options =>
{
    options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; //格式化时间
});

#endregion

要在控制器中使用这个过滤器,可以在控制器或动作方法上添加 [GuardModelState] 属性:

[ApiController]
[Route("[controller]")]
[GuardModelState] // 在控制器级别应用过滤器
public class MyController : ControllerBase
{
    [HttpGet("{id}")]
    public ActionResult Get(int id)
    {
        // 控制器逻辑
        return Ok();
    }

    [HttpPost]
    [GuardModelState] // 在动作方法级别应用过滤器
    public ActionResult Post([FromBody] MyModel model)
    {
        // 控制器逻辑
        return Ok();
    }
}

总结

GuardModelStateAttribute 是一个自定义的 ASP.NET Core 过滤器,用于在控制器动作执行前验证模型状态,并在模型状态无效时返回一个带有详细错误信息的 BadRequest 响应。通过使用这个过滤器,可以简化错误处理逻辑,并提高代码的可维护性和可读性。

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值