我在 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"));
所以,我有两个问题:
谢谢
在执行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
});