在使用.net core下进行模型验证的时候一直提示400错误,感觉跟之前的.net framework下不太一样,一查是有区别
在.net core下如果使用WebApi对于模型验证会自动使用ModelStateInvalidFilter 这个过滤器
返回的格式是:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|d1a00f39-4781223826243061.",
"errors": {
"depid": [
"部门不能为空"
]
}
}
而不是使用ModelState.IsValid来进行验证
如果想跟之前.net framework那样通过自定义的模型验证过滤器, 或在action中ModelState.IsValid进行验证,而且返回不是400错误而是正常请求通过提示来返回
有两种方法
1.Net Core 禁用模型验证过滤器
SuppressModelStateInvalidFilter = true时,会关闭默认模型验证过滤器。[ApiController] 默认自带有400模型验证,且优先级比较高,如果需要自定义模型验证,则需要先关闭默认的模型验证
services.Configure<ApiBehaviorOptions>(options => options.SuppressModelStateInvalidFilter = true);
2.自动替换默认模型验证
services.Configure<ApiBehaviorOptions>(options =>
{
string smsg="";
options.InvalidModelStateResponseFactory = (context) =>
{
foreach (var key in context.ModelState.Keys) {
var errors = context.ModelState[key].Errors;
if (errors.Count() > 0) {
smsg = errors[0].ErrorMessage;
break;
}
}
return new JsonResult(new ResponseMessageDTO() { Success = false, Message = $"参数验证不通过:{smsg}"});
//return new JsonResult(Result.FromError($"参数验证不通过:{error.ToString()}", ResultCode.InvalidParams));
};
});
第一种模式关闭的话,你可以通过你自定义的模型验证过滤器来实现
如使用之前的过滤器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using MyMis.DTO;
using MyUtility.AttributeExtend;
namespace MyMis.MvcExtend.Filter {
public class DataValidationAttribute : Attribute, IActionFilter {
public void OnActionExecuted(ActionExecutedContext context) {
}
public void OnActionExecuting(ActionExecutingContext context) {
bool doValid = false;
//判断Action是否有DoValidAttribute
DoValidAttribute actionAttr = (DoValidAttribute)((Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor)context.ActionDescriptor).MethodInfo.GetCustomAttribute(typeof(DoValidAttribute), false);
if (actionAttr != null) {
var attr = actionAttr as DoValidAttribute;
doValid = actionAttr._doValid;
}
if (doValid) {
if (!context.ModelState.IsValid) {
var errorMsg = this.GetErrMessage(context);
context.Result = new JsonResult(new ResponseMessageDTO() { Success = false, Message = errorMsg });
}
}
}
private string GetErrMessage(ActionExecutingContext context) {
string smsg = "";
foreach (var key in context.ModelState.Keys) {
var errors = context.ModelState[key].Errors;
if (errors.Count() > 0) {
smsg = errors[0].ErrorMessage;
break;
}
}
return smsg;
}
}
}
第二种方式的话直接替换掉.net core默认的模型验证方法了
两种方式都可以看个人喜好了,建议采用第二种