ASP.NET Core MVC 2.1 頂級參數驗證


本文討論ASP.NET Core 2.1中與ASP.NET Core MVC / Web API控制器中的模型綁定相關的功能。雖說這是一個功能,但從我的角度來看,它更像是一個錯誤修復!

請注意,我使用的是 NET Core 2.1 Preview 1,正式版發布后,功能可能存在變動。

ASP.NET Core 2.0 模型驗證

模型驗證是ASP.NET Core MVC 管線的重要組成部分。有很多方法可以注入到驗證層(例如使用FluentValidation),最常見的方法可能是使用來自System.ComponentModel的驗證標記來修飾綁定模型。 例如:

public class UserModel  
{
    [Required, EmailAddress]
    public string Email { get; set; }

    [Required, StringLength(1000)]
    public string Name { get; set; }
}

如果您在控制器的操作方法中使用UserModelMvcMiddleware則會自動創建對象的新實例,綁定模型的屬性並使用如下三個來源對其進行驗證:

  1. 表單 - 當使用POST將表單發送到服務器時,發送到HTTP請求的主體中;
  2. 路由 - 在匹配路由后從URL段或默認值中獲取;
  3. 查詢字符串 - 在URL的末尾傳遞。

請注意,目前,作為JSON發送的數據默認情況下不會被綁定。如果您希望綁定請求體中的JSON數據,則需要使用此處所述[FromBody]標記修飾模型。

在控制器Action方法中,可以簡單地檢查ModelState屬性,確定提供的數據是否有效:

public class CheckoutController : Controller  
{
    public IActionResult SaveUser(UserModel model)
    {
        if(!ModelState.IsValid)
        {
            // Something wasn't valid on the model
            return View(model);
        }

        // The model passed validation, do something with it
    }
}

這是非常標准的MVC內容,但是如果您不想創建整個綁定模型,但仍想驗證傳入數據,該怎么辦?

ASP.NET Core 2.0 頂級參數

DataAnnotation標記默認MVC驗證系統使用的屬性不必應用於類的屬性,它們也可以應用於參數。這可能會導致您認為您可以完全替換UserModel上面的示例中的以下內容:

MVC默認驗證系統使用的DataAnnotation標記不一定應用於類的屬性,它們同樣可以應用於參數。這可能會導致您認為可以完全替換上面示例中的UserModel,如下所示:

public class CheckoutController : Controller  
{
    public IActionResult SaveUser(
        [Required, EmailAddress] string Email 
        [Required, StringLength(1000)] string Name)
    {
        if(!ModelState.IsValid)
        {
            // Something wasn't valid on the model
            return View(model);
        }

        // The model passed validation, do something with it
    }
}

不幸的是,這是行不通的!在綁定屬性時,驗證屬性將被忽略,並且ModelState.IsValid始終是true

ASP.NET Core 2.1中的頂級參數

幸運的是,ASP.NET Core團隊意識到了這個問題,並且已經將修補程序合並為ASP.NET Core 2.1的一部分。因此,上一節中的代碼的行為與您所期望的一樣,參數經過驗證,並相應地進行了ModelState.IsValid更新。

作為這項工作的一部分,您現在還可以使用[BindRequired]標記修飾參數。當綁定非空值類型時,此標記很重要,因為使用[Required]標記對這些屬性並不能提供預期的行為。

這意味着您現在可以執行以下操作,並確保testId參數已從路由參數中正確綁定,並且qty參數已從查詢字符串中綁定。在ASP.NET Core 2.1之前,它甚至不能編譯!

[HttpGet("test/{testId}")]
public IActionResult Get([BindRequired, FromRoute] Guid testId, [BindRequired, FromQuery] int qty)  
{
    if(!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    // Valid and bound
}

對於這個問題可以查閱我之前的博客:《ASP.NET Core MVC中的 [Required]與[BindRequired]》

總結

在ASP.NET Core 2.0及以下版本中,應用於頂級參數的驗證標記將被忽略,並且ModelState不會更新。只考慮復雜模型類型的驗證參數。

在ASP.NET Core 2.1中,驗證標記現在將在頂級參數上得到遵守。更重要的是,您可以將[BindReqired]標記應用於參數。

ASP.NET Core 2.1 增加了很多新特性。這是一些不錯的小改進之一,它使事情變得更容易,更一致 -- 我喜歡這種改變。

翻譯自https://andrewlock.net/coming-in-asp-net-core-2-1-top-level-mvc-parameter-validation/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM