更改 ASP.Net Core Web Api 中 ActionFilter 中的响应

问题描述 投票:0回答:1

我在 ASP.Net Core Web Api 项目中使用普通数据注释验证和自定义验证。框架本身向 ModelState 添加验证错误,根据业务逻辑,我还使用

ModelState.AddModelError()
添加自定义验证。我想做的是,在将响应发送给客户端之前,我想检查是否
ModelState.IsValid
,如果无效,我想清除响应并以我想要的格式发送错误 JSON。

我可以在控制器本身中轻松完成此操作,但如果我在每个控制器操作中检查

ModelState
,则会有很多重复代码。所以我想在 ActionFilter 中完成它。

这是我想使用的方法:

public override void OnActionExecuted(ActionExecutedContext context)
{
    if (!context.ModelState.IsValid)
    {
        // Change the response
    }
}

我做了第一部分所需的一切,这样我就可以调试代码,直到它达到这个方法。我还可以访问

ModelState
,因此我只需要修改响应并发送 JSON 响应。当我想到这一点时,这听起来很简单,但即使在尝试了 10 多个不同的代码来更改响应之后,我仍然无法做到这一点。

我认为像这样的简单代码可以工作,但事实并非如此(这当然不是 JSON,我用简单的文本尝试过,这也不起作用):

context.HttpContext.Response.Body.Write(Encoding.UTF8.GetBytes("test"));

所以,我有两个问题:

  1. 这是个好主意吗?有更好的方法来做我想做的事吗?
  2. 如果这是个好主意,我如何修改 ActionFilter 中的响应?

谢谢

c# asp.net-core asp.net-core-webapi
1个回答
0
投票

在执行action之前需要进行模型验证,否则无论验证失败与否,它都会执行action中的代码。

如果您必须在执行操作后执行:

public class ModelStateValidationFilter : IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)

    {
        if (!context.ModelState.IsValid)
        {
            // Get all model state errors
            var errors = context.ModelState
                .Where(e => e.Value.Errors.Count > 0)
                .SelectMany(e => e.Value.Errors)
                .Select(e => e.ErrorMessage)
                .ToList();

            // Create a custom error response
            var errorResponse = new
            {
                Message = "Validation failed",
                Errors = errors
            };

            // Replace the response with the custom error response
            context.Result = new BadRequestObjectResult(errorResponse);
        }
            
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        
    }
}

如果您的项目是 Web Api 并且控制器使用

[ApiController]
属性声明,请务必设置
SuppressModelStateInvalidFilter
true 以禁用
Program.cs
文件中的自动模型验证(无论您在执行操作之前还是之后进行模型验证) ,你总是需要将此属性设置为 true。否则它不会执行操作过滤器,并且默认模型验证会因错误请求而失败,因为模型验证中间件发生在操作过滤器之前):

builder.Services.AddControllers(options =>
{

    options.Filters.Add(typeof(ModelStateValidationFilter)); // Add the filter globally
}).ConfigureApiBehaviorOptions(options =>
{
    options.SuppressModelStateInvalidFilter = true; // Disable automatic model validation
}); 
© www.soinside.com 2019 - 2024. All rights reserved.