在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全局過濾器之全局異常記錄和全局日志的記錄