Model Validation in ASP.NET Web API

Model Validation in ASP.NET Web API

原文:http://www.asp.net/web-api/overview/formats-and-model-binding/model-validation-in-aspnet-web-api

本文主要讲述Web API中使用标记来验证数据,以及出路验证错误。

1. 数据注解 Data Annotations

在Web API中,使用System.ComponentModel.DataAnnotations中的属性来添加验证规则。

例如:

using System.ComponentModel.DataAnnotations;

namespace WebApiPractice.Models
{
    public class Product
    {
        public int Id { get; set; }
        [Required]
        public string Name { get; set; }
        public string Category { get; set; }
        public decimal Price { get; set; }
        [Range(0, 999)]
        public double Weight { get; set; }
    }
}

Required属性要求Name不能为空。Range属性要求Weight的值在0~999之间。

在Controller中验证:

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);
    }
}

"Under-Posting": 当客户端发送的值缺少的时候,一般使用Nullable来解决,因为基础类型都有一个默认值,比如int(0),double(0),string("")。


[Required] public decimal? Price { get; set; }

"Over-Posting": 客户端发送了过多的数据。一般采用DTO避免这种情况。

2. 处理验证错误

Web API不会自动将验证错误返回给客户端。需要控制器的action检查模型状态并做适当地返回。

在控制器的action被调用之前,可以创建一个action过滤器来检查模型的状态。

代码如下:

using System.Net;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;

namespace WebApiPractice.Filters
{
    //模型验证
    public class ValidateModelAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (actionContext.ModelState.IsValid == false)
            {
                actionContext.Response = actionContext.Request.CreateErrorResponse(
                    HttpStatusCode.BadRequest, actionContext.ModelState);
            }
        }
    }
}

如果验证失败,过滤器将会返回包含验证错误的HTTP响应。这种情况下,控制器的action不会被调用。

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Date: Tue, 16 Jul 2013 21:02:29 GMT
Content-Length: 331

{
  "Message": "The request is invalid.",
  "ModelState": {
    "product": [
      "Required property 'Name' not found in JSON. Path '', line 1, position 17."
    ],
    "product.Name": [
      "The Name field is required."
    ],
    "product.Weight": [
      "The field Weight must be between 0 and 999."
    ]
  }
}

可以将验证的过滤器应用在所有控制器,或者单个控制器,单个action:

config.Filters.Add(new ValidateModelAttribute());
[ValidateModel]
public HttpResponseMessage Post(Product product)

测试代码:

public void PostProduct()
{
    HttpClient httpClient = new HttpClient();
    Product p = new Product();
    p.Id = 12;
    p.Price = 100;

    var t = httpClient.PostAsJsonAsync("http://localhost:60865/api/products", p);
    t.Wait();

    System.Diagnostics.Debug.WriteLine(t.Result);
    Console.WriteLine(t.Result);
}
posted @ 2016-09-03 20:16  _DN  阅读(173)  评论(0编辑  收藏  举报