中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發布時間:2020-07-29 03:36:03 來源:網絡 閱讀:778 作者:水煮code 欄目:編程語言

問題

  想要 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

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

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

工作原理

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

清單 1-17. IBodyModelValidator 接口

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 接口的定義

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

 

 

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

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

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

 

代碼

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

RequiredAttributeMaxLengthAttribute

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

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

public class Album
{
    public int Id { get; set; }
    [Required(ErrorMessage = "Artist is required")]
    [MaxLength(30)]
    public string Artist { get; set; }
    [Required(ErrorMessage = "Title is required")]
    [MaxLength(40)]
    public string Title { get; set; }
    [Range(0, 10, ErrorMessage = "Rating in the range of 0-10 is required.")]
    public int Rating { get; set; }
}
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 的驗證

public class Album : IValidatableObject
{
    public int Id { get; set; }
 
    [Required(ErrorMessage = "Artist is required")]
    [MaxLength(30)]
    public string Artist { get; set; }
 
    [Required(ErrorMessage = "Title is required")]
    [MaxLength(40)]
    public string Title { get; set; }
 
    public int? Rating { get; set; }
    public bool? Starred { get; set; }
 
    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.");
        }
    }
}

 

 

  正如我們看到的,我們可以很容的在Validate 方法中使用自己的邏輯來合并聲明方式的驗證。這是一個特例,如果我們的請求中沒有包含這兩個屬性中的任何一個,我們驗證期望結果就是失敗,同時返回結果給調用端,如清單 1-21 所示。

清單 1-21 非法請求,同時通過 IValidateableObject 執行 Validation 返回相應結果給調用端。

POST /api/album HTTP 1.1

Content-Type: application/json

{"artist":"Rancid", "title":"And Out Come The Wolves"}

Status Code: 400 Bad Request

Content-Length: 130

Content-Type: application/json; charset=utf-8

Date: Tue, 13 May 2014 19:06:31 GMT

{

"Message": "The request is invalid.",

"ModelState": {

"album": ["You must set either the Rating in the 0-9 range or Starred flag."]

}

}

 

  我們可以更進一步的驗證,接下來將介紹 FluentValidation 來為 Web API 做模型驗證。手下,我們要從NuGet 上安裝 FluentValidationInstall-package FluentValidation

就像開始那樣,不把驗證邏輯嵌套到實體中,我們應用 FluentValidation 驗證器,調用它里面的 Validate 的方法。這樣,所有的驗證可以放到實體外部。因此,我們不僅可以從模型中移除之前的驗證邏輯,還可以清掉 DataAnnotation 屬性。修改之前模型驗證的例子,使用 FluentValidation,如清單 1-22 所示。

 

清單 1-22 FluentValidation


 

  在功能方面,上面的例子等同于清單1-20 所示的代碼。FluentValidation 驗證規則是可以配置。上面代碼的前一部分展示了配置相應 FluentValidation 的驗證規則和相應響應的結果,而,后一部分代碼是 IValidateableObject 接口的實現,確保了指定的驗證可以被執行。


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

来宾市| 牟定县| 浦县| 宁波市| 阳谷县| 松滋市| 都江堰市| 乐昌市| 大冶市| 客服| 醴陵市| 秦皇岛市| 镇安县| 大庆市| 宜君县| 建宁县| 嘉峪关市| 永定县| 万年县| 洪雅县| 馆陶县| 兴化市| 九江市| 杭锦旗| 石台县| 汝南县| 闽清县| 安泽县| 盐池县| 浦县| 南靖县| 城步| 凤凰县| 永泰县| 马关县| 大安市| 隆化县| 张家界市| 邢台市| 松滋市| 右玉县|