[水煮 ASP.NET Web API2 方法論](1-6)Model Validation

來源:互聯網
上載者:User

標籤:rtp   情況   api   number   row   x11   validate   mod   表示   

問題

  想要 ASP.NET Web API 執行模型驗證,同時可以和 ASP.NET MVC 共用一些驗證邏輯。

解決方案

  ASP.NET Web API 與 ASP.NET MVC 支援一樣的驗證機制,都是通過System.ComponentModel.DataAnnoataions 的屬性驗證。使用架構提供的相關驗證屬性,已足夠來用來驗證模型。

想要更細粒度的驗證,我們可以選擇在我們的模型中實現 IValudateObject(來自於System.ComponentModel.DataAnnotations)。如果所有的屬性都驗證通過,ASP.NET Web API 將會調用介面的Validate 方法,在這裡我們可以進行更進一步的進行實體驗證。這是和 MVC 裡面的行為一樣,並且,我們甚至可以在 Web API 和 MVC 中使用同一個 DTO。

  還有另一種方法,就是可以使用一個叫做 FluentValidation(NuGet 中可以下載FluentValidation)的第三方程式庫,他可以構建更強大的驗證情境。在這樣的情況下,我們仍然需在我們的模型中實現 IValidateObject 介面,同時需要依賴於FluentValidation 驗證器,而不是內嵌的驗證邏輯。

小提示 ASP.NET Web API 的驗證行為在跨宿主機上是相同的。

工作原理

  為了從 HTTP 請求 Body 中讀取的模型並執行驗證,ASP.NET Web API 依賴於一個 IBodyModelValidator 的服務。介面的大致描述如清單 1-17 所示,然而,他是一個可替代的服務,正常情況下,預設實現(DefaultBodyModelValidator)足夠我們使用,在HttpConfiguration 被設定為自啟動。

清單 1-17. IBodyModelValidator 介面

12345 public interface IBodyModelValidator{    bool Validate(object model, Type type, ModelMetadataProvider metadataProvider,    HttpActionContext actionContext, string keyPrefix);}

 

 

  有一個叫做FormatrtParameterBinding 的服務,在 HTTP 請求 Body 綁定到 Action 參數的處理請求時,DefaultBodyModelValidator 的 Validate 方法會被調用。對於驗證程式,他會遞迴驗證整個對象圖譜,驗證每一個屬性以及嵌套屬性。Web API 通過使用DataAnnotationModelValidatorProviderr 來支援聲明。如果我們的模型使用WCF 方式的 DataMemberAttribute 聲明,那麼,我們需要使用架構的 DataMemberValidatorProvider。

  最後,我們的模型可以實現IValidatableObject 介面,這個介面只暴露了一個簡單的方法如清單1-18所示。如果實現了介面,那就需要我們自己提供額外的驗證邏輯。只要所有的屬性驗證通過,ASP.NET Wwb API 就會調用IValidateableObject介面的 Validate 方法,

 

清單1-18. IValidateableObject 介面的定義

1234 public interface IValidateableObject{    IEnumerable<ValidationResult> Validate(ValidationContext validationContext);}

 

 

  驗證結果是通過 ASP.NET Web API 的  ModelStateDictionary 形式表示,在這裡 ModelState 也是可以用的。這個和 ASP.NET MVC 中的概念是完全一樣的,但是使用的對象是不同的,因為 Web API 使用自己版本的System.Web.Http.Modelbinding。ModelStateDictionary 暴露了IsValid 屬性,這個屬性可以用來檢查 Action 內Model 驗證的狀態。

  聲明的驗證機制也很好的整合到了 ASP.NET Web API Help Page,可以提供對 API 語義上的描述。我們將會在7-11 的時候詳細討論他。

  小提示 在 API 中最好的做法是使用不同的模型作為 Request 和Response 實體。例如,實體 ID 一般僅僅是 Response 模型需要的,如果 Request 中需要的話,是可以從 URI 中拿到的。

 

代碼

  清單 1-19 展示了一個模型有多種驗證的情況:

RequiredAttribute,MaxLengthAttribute 和

RangeAttribute。接下來,我們就可以利用 ModelState 來驗證 Controller 中的驗證狀態,同時響應適當的提示資訊給調用端。

清單 1-19. 簡單的 Web API 模型驗證

123456789101112131415161718192021222324 public class Album{    public int Id { getset; }    [Required(ErrorMessage = "{0} is required")]    [MaxLength(30)]    public string Artist { getset; }    [Required(ErrorMessage = "{0} is required")]    [MaxLength(40)]    public string Title { getset; }    [Range(0, 10, ErrorMessage = "{0} in the range of {1}-{2} is required.")]    public int Rating { getset; }}public class AlbumController : ApiController{    public HttpResponseMessage Post(Album album)    {        if (!ModelState.IsValid)        {            throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest,            ModelState));        }        //omitted for brevity    }}

 

 

  負責處理 ModelState 代碼的一般驗證可以很容易從 Controller 提取到成公用的部分,使其可以被很好的重用,不過這一部分我們將在 5-4 的時候再詳細介紹。

  現在,我們考慮一下這個情境,如果我們要在模型上增加增加兩個額外的屬性 Rating 和 Starred,同時擴充模型驗證,驗證的要求是這兩個屬性至少有一個是必填的。雖然,在兩個屬性之間糾纏的驗證很難使用聲明的方式來表示,但是,不要忘記 IValidateableObject 可以幫我們。我們可以使用介面中的 Validata 的方法去檢查整個模型的狀態,同時返回相應的 ValidationResult。我們要做的修改如清單 1-20 所示的代碼。

 

清單 1-20. 修改 ASP.NET Web API 依賴於 IValidateableObject 的驗證

1234567891011121314151617181920212223 public class Album : IValidatableObject{    public int Id { getset; }      [Required(ErrorMessage = "{0} is required")]    [MaxLength(30)]    public string Artist { getset; }      [Required(ErrorMessage = "{0} is required")]    [MaxLength(40)]    public string Title { getset; }      public int? Rating { getset; }    public bool? Starred { getset; }      public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)    {        if (!(Rating.HasValue && Rating > 0 && Rating < 10) || (Starred.HasValue && Starred.Value))        {            yield return new ValidationResult("You must set either the Rating in the 0-9 range orStarred flag.");        }    }}



[水煮 ASP.NET Web API2 方法論](1-6)Model Validation

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.