在webapi项目中我们经常希望对错误信息进行统一控制,不希望每个controller中都写个modelState.isvalid,以屏蔽部分敏感信息到前端,此时就需要对modelState错误返回值进行改造。此时可以通过全局过滤器进行过滤
代码如下:以下写法是发现一个错误就停止验证后续的字段,直接返回错误信息,
namespace NetCore3WebApiTemplate.Filters { /// <summary> /// 验证数据的格式,按照自定义的值类型返回 /// </summary> [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true)] public class ModelValidationAttribute : ActionFilterAttribute { /// <summary> /// 控制器中的操作执行之前调用此方法 /// </summary> /// <param name="actionContext"></param> public override void OnActionExecuting(ActionExecutingContext actionContext) { var modelState = actionContext.ModelState; if (!modelState.IsValid) { string error = string.Empty; foreach (var key in modelState.Keys) { var state = modelState[key]; if (state.Errors.Any()) { var errorInfo = state.Errors.First(); string ex = (errorInfo.Exception == null ? "" : errorInfo.Exception.ToString()); error = string.IsNullOrEmpty(errorInfo.ErrorMessage) ? ex : errorInfo.ErrorMessage; break; } } HttpResponseResultModel<string> response = new HttpResponseResultModel<string>() { IsSuccess = false, ErrorMessage = error, HttpStatusCode = HttpStatusCode.BadRequest }; var result = new JsonResult(response); result.StatusCode = (int)HttpStatusCode.BadRequest; actionContext.Result = result; } } } }
在startup中,做如下配置:禁用默认ModelState行为
/// <summary> /// This method gets called by the runtime. Use this method to add services to the container. /// </summary> /// <param name="services"></param> public void ConfigureServices(IServiceCollection services) { //禁用默认ModelState行为 services.Configure<ApiBehaviorOptions>(options => { options.SuppressModelStateInvalidFilter = true; }); }
使用方式Controller类型进行特性标记如下 标记ModelValidation即可,
/// <summary> /// 基础数据-公司信息表接口 /// </summary> [ApiExplorerSettings(GroupName = "Basic")] [Route("Company")] [ApiController] [ModelValidation] public class CompanyController : ControllerBase { private readonly CompanyApp companyApp; public CompanyController(CompanyApp companyApp) { this.companyApp = companyApp; } /// <summary> /// 根据主键获取 /// </summary> /// <param name="id">主键id</param> /// <returns></returns> [Route("Get")] [ProducesResponseType(typeof(CompanyView), 200)] [HttpGet] public async Task<ActionResult> GetAsync(long id) { var entity = await companyApp.GetAsync(id).ConfigureAwait(false); return Ok(entity); } }
HttpResponseResultModel 类定义 请参阅以下文章: .Net Core全局过滤器之全局异常记录和全局日志的记录