asp.net core 统一模型验证拦截实现
在使用webapi对外提供服务的时候,我们希望提供一个统一的返回值例如 {"code":1,"message":"ok","data":""}。为了解耦会对未处理的异常和模型验证进行统一处理。本文介绍了asp.net core 3.1版本中实现统一模型验证的实现方法。
在asp.net core中的过滤器和framework中的过滤器使用上并没有太大差异。新建过滤器ModelVerificationFilter.cs
public class ModelVerificationFilter : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
}
public void OnActionExecuting(ActionExecutingContext context)
{
if (context.ModelState.IsValid)
{
return;
}
var errorMessage = context.ModelState
?.FirstOrDefault(m => m.Value.ValidationState == ModelValidationState.Invalid).Value
?.Errors
?.FirstOrDefault()
?.ErrorMessage;
context.HttpContext.Response.StatusCode = (int) HttpStatusCode.BadRequest;
context.Result = new ObjectResult(new ResponseVm(errorMessage, 400));
}
}
这里在发现模型验证失败的时候,返回第一个模型验证错误信息,并把http的状态码设置为BadRequest。代码中ResponseVm类是前面提到的统一返回值类型。
public class ResponseVm
{
public ResponseVm(string message, int code)
{
Message = message;
Code = code;
}
public ResponseVm()
{
Message = "ok";
Code = 0;
}
/// <summary>
/// 错误信息
/// </summary>
public string Message { get; set; }
/// <summary>
/// 错误码
/// </summary>
public int Code { get; set; }
public static ResponseVm Success(string msg = "ok")
{
return new ResponseVm(msg, 0);
}
public static ResponseVm Failed(string msg = "error", int code = -1)
{
return new ResponseVm(msg, code);
}
}
设置好过滤器之后发现并没有输出我们要求的结果,而是产生了一个系统默认的模型验证错误的返回值。其中Source是我们要验证的字段。
{
"errors": {
"Source": [
"来源 必须在 1 至 2 之间"
]
...
},
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|61e0ca29-42ac2f842289c956."
}
参考官方文档Web API应用-概述-自动 HTTP 400响应一节。
使用 2.1 的兼容性版本时,HTTP 400 响应的默认响应类型为 SerializableError。 下述请求正文是序列化类型的示例:
使用 2.2 或更高版本的兼容性版本时,HTTP 400 响应的默认响应类型为 ValidationProblemDetails。
若要禁用自动 400 行为,请将 SuppressModelStateInvalidFilter 属性设置为 true。 将以下突出显示的代码添加到 Startup.ConfigureServices:services.AddControllers() .ConfigureApiBehaviorOptions(options => { ... options.SuppressModelStateInvalidFilter = true; ... });
按文档修改后,统一模型验证拦截成功。两种方法配置
services.Configure<ApiBehaviorOptions>(o =>
{
o.SuppressModelStateInvalidFilter = true;
});
services.AddControllers()
.ConfigureApiBehaviorOptions(opt => opt.SuppressModelStateInvalidFilter = true)
参考:
正文到此结束
热门推荐
相关文章
该篇文章的评论功能已被站长关闭