ASP.NET WEB API 自定义模型校验过滤器
对外公开WEB接口时,对模型校验是常见的安全常识,常见的写法是在controller中判断ModelState.IsValid,以注册用户API为例。
Model:
public class RegisterCustomerModel { [Required(ErrorMessage = "姓名不能为空")] [StringLength(10,ErrorMessage = "姓名长度不能超过10个字")] public string Name { get; set; } [Required(ErrorMessage = "电话不能为空")] [RegularExpression(@"^1[34578]\d{9}$", ErrorMessage = "电话号码格式不正确")] public string Phone { get; set; } [Required(ErrorMessage = "密码不能为空")] [StringLength(48, ErrorMessage = "密码长度不能超过48个字符")] public string Password { get; set; } }
打印校验失败的错误消息代码:
public static class ModelStateExtension { public static string ToErrorMessage(this ModelStateDictionary modelStateDictionary) { var stringBuilder = new StringBuilder(); foreach (var value in modelStateDictionary.Values) { foreach (var error in value.Errors) { stringBuilder.AppendLine(error.ErrorMessage); } } return stringBuilder.ToString(); } }
Controller:
public ResponseProtocol Register(RegisterCustomerModel registerCustomerModel) { if (!ModelState.IsValid) { return new ResponseProtocol((int)ResponseResultEnum.ValidateError, ModelState.ToErrorMessage(), string.Empty); } Customer customer = new Customer { Name = registerCustomerModel.Name, Phone = registerCustomerModel.Phone, WeiXinNo = registerCustomerModel.WeiXinNo, Company = registerCustomerModel.Company, UpdateTime = DateTime.Now }; _customerService.Add(customer); return new ResponseProtocol((int)ResponseResultEnum.Success, "注册成功", string.Empty); }
以上写法是在controller里进行校验,缺点是每个需要进行校验的controller都要写一次,为了消除重复,可以将校验代码写入全局过滤器中,由过滤器进行统一模型校验,修改后的代码:
public class ValidationModelFilter : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { //get方法不进行模型校验 if (actionContext.Request.Method.Method=="GET") { return; } if (!actionContext.ModelState.IsValid) { var error = JsonConvert.SerializeObject(new ResponseProtocol() { Code =(int)ResponseResultEnum.ValidateError, Message = actionContext.ModelState.ToErrorMessage(), Data = string.Empty }); var httpResponseMessage = new HttpResponseMessage { Content = new StringContent(error) }; httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); actionContext.Response = httpResponseMessage; } } }
然后在全局过滤器(WebApiConfig)注册一下: config.Filters.Add(new ValidationModelFilter());