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