一、模型验证的作用
在ASP.NET Web API中,我们可以使用 System.ComponentModel.DataAnnotations 命名空间中的属性为模型上的属性设置验证规则。
一个模型验证栗子
using System.ComponentModel.DataAnnotations; namespace MyApi.Models { public class Product { public int Id { get; set; } [Required] public string Name { get; set; } public decimal Price { get; set; } [Range(0, 999)] public double Weight { get; set; } } }
和ASP.NET MVC中中的模型验证十分相似,上边的验证规则是:Name属性不能为空,Weight必须在0与999之间。关于验证属性的用法可以参考.NET MVC的验证属性。
客户端(没有必须的Name):
<form action="api/Product" method="post"> Id:<input type="text" name="Id" value="4" /><br /> Price:<input type="text" name="Price" value="1.99" /><br /> Weight:<input type="text" name="Weight" value="2.99" /><br /> <input type="submit" value="Submit" /> </form>
控制器代码:
public class ProductsController : ApiController { public HttpResponseMessage Post(Product product) { if (ModelState.IsValid) { // Do something with the product (not shown). return new HttpResponseMessage(HttpStatusCode.OK); } else { return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState); } } }
当我们提交表格时,google中返回的内容如下
两个小问题:
“Under-Posting”:客户端提交的模型缺少字段,如果是[required]修饰的字段,ModelState不通过验证,如果是数字类型的,用0补充。
“Over-Posting”:客户端也可以发送更多的数据,JSON格式化器只是忽略此值(XML格式化程序也是如此)。
二 、WebApi中的处理验证错误
第一步 添加过滤器
验证失败时,Web API不会自动向客户端返回错误,这就需要控制器来做出适当的响应。我们可以创建action filter用于在Action执行之前检查模型状态。和MVC中的用法一样,代码显示了一个示例:
public class ValidateModelAttribute : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { if (!actionContext.ModelState.IsValid) { //返回第一个异常的错误消息 actionContext.Response = actionContext.Request.CreateResponse( HttpStatusCode.InternalServerError, new { code = 0, msg = actionContext.ModelState.Values.First().Errors.First().ErrorMessage }); } } }
如果模型验证失败,则此过滤器返回包含验证错误的HTTP响应,这样就不再执行Action了。
第二步 使用过滤器
如果我们想在全局使用这种方案,我们可以设置一个全局的过滤器,在配置阶段把上边的过滤器添加到 HttpConfiguration.Filters 集合中。
public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Filters.Add(new ValidateModelAttribute()); } }
如果不想使用全局过滤器,我们也可以把filter设置为各个Controller或Action的属性:
public class ProductsController : ApiController { [ValidateModel] public HttpResponseMessage Post(Product product) { // ... } }
这里主要总结了WebApi中的模型验证,了解更多可查看官网。