ASP.NET Core 中文文檔 第四章 MVC(2.1)模型綁定


原文:Model Binding
作者:Rachel Appel
翻譯:婁宇(Lyrics)
校對:許登洋(Seay)何鎮汐

模型綁定介紹

ASP.NET Core MVC 中的模型綁定從 HTTP 請求參數中將數據映射到 Action 方法里。這些參數可以是 string、interger、float 這樣的簡單類型,也可以是復雜類型。這是 MVC 一個非常棒的功能,因為無論傳入數據的大小或復雜性如何,映射傳入數據到對應項是一個經常重復的情況。 MVC 通過抽象綁定解決了這個問題,所以開發者們不必繼續在每一個應用中反復編寫同樣的代碼。自己編寫文本到類型轉換的代碼是冗長並且容易出錯的。

模型綁定如何工作

當 MVC 收到一個 HTTP 請求,它將其路由到一個 Controller 特定的一個 Action 方法。它基於路由數據來決定運行哪個 Action 方法,然后將值從 HTTP 請求綁定到 Action 方法的參數中。例如,考慮下面的 URL:

http://contoso.com/movies/edit/2

因為路由模板看起來像這樣,{controller=Home}/{action=Index}/{id?} movies/edit/2 路由到Movies Controller ,和它的 Edit Action 方法。同時接受到一個可選參數 id 。 Action 方法代碼應該看起來像這樣:

public IActionResult Edit(int? id)

提示
URL 中的字符串不區分大小寫。

MVC 嘗試通過參數名將請求數據綁定到 Action 的參數上。 MVC 將使用參數名以及它的公開可設置的屬性名稱查詢所有的值。在上面的例子中,只有一個參數命名為 id ,MVC 將路由值中名稱相同的值綁定過去。除了路由值之外, MVC 會以一種固定的順序從 HTTP 請求中的其他部分綁定數據。下面是模型綁定的數據源列表的綁定順序:

  • Form values :這是通過 HTTP POST 請求發送的表單數據(包括 jQuery POST 請求)。
  • Route values :由 routing 提供的路由數據集。
  • Query strings :URI 的查詢字符串的一部分。

提示
表單值,路由數據,以及查詢字符串都以鍵值對的形式存儲。

因為模型綁定要找一個命名為 id 的鍵,但是在表單值里沒有命名為 id 的鍵,所以接下來將在路由數據中找尋這個鍵。在我們的例子中,它是匹配的。綁定發生時,該值轉換為 integer 類型的 2。相同的請求使用 Edit(string id) 將轉換成 string 類型的值 “2” 。

到目前為止的例子使用的都是簡單類型。在 MVC 中簡單類型是任何 .NET 原始類型或者帶字符串的類型的轉換器。如果 Action 方法的參數是一個類,比如說 Movie 類型,這個類包含簡單類型和復雜類型的屬性,MVC 的模型綁定仍然可以很好的處理它。它使用反射和遞歸遍歷復雜類型尋找匹配的屬性。模型綁定尋找 parameter_name.parameter_name 的模式去綁定值到屬性上。如果沒有從表單中找到匹配的值,將嘗試只通過 property_name 進行綁定。對於那些 集合(Collection) 類型,模型綁定會去匹配 parameter_name[index] 或者只是 [index] 。模型綁定對待 字典(Dictionary) 類型也是一樣,尋找 parameter_name[key] 或只是 [key] ,前提是 Key 是簡單類型。 Key 支持匹配 HTML 和 Tag Helpers 為相同的模型類型生成的字段名。當創建或者編輯的綁定數據未通過驗證的時候,回傳值使得用戶輸入的表單字段仍然保留,方便了用戶(不必重新輸入全部數據)。

為了綁定發生,這個類必須有一個公開的默認構造函數,並且被綁定的成員必須是公開的,並且可寫的屬性。當模型綁定發生的時候只會通過默認的構造函數去實例化類型,然后設置屬性的值。

當一個參數被綁定,模型綁定停止繼續查找這個參數名並開始綁定下一個參數。如果綁定失敗, MVC 不會拋出異常。你可以查詢模型狀態異常通過檢查 ModelState.IsValid 屬性。

提示
Controller 的 ModelState 屬性中的每個 Entry 都是一個包含了 Errors 屬性 的 ModelStateEntry。 你基本不需要去查詢這個集合。使用 ModelState.IsValid 來替代它。

此外,還有一些特殊的數據類型在 MVC 執行模型綁定的時候需要考慮:

  • IFormFileIEnumerable<IFormFile>: 一個或多個通過 HTTP 請求上傳的文件。
  • CancelationToken:用於在異步 Controller 中取消活動。

這些類型可以被綁定到 Action 參數或者一個類的屬性中。

一旦模型綁定完成,就會進行 驗證 。默認的模型綁定適合絕大多數開發場景。它也是可擴展的,所以如果你有獨特的需求,你可以自定義內置的行為。

通過 Attributes 自定義模型綁定行為

MVC 包含幾種讓你可以指定與默認綁定源不同行為的 Attribute 。比如,你可以通過使用 [BindRequired] 或者 [BindNever] Attribute 指定一個屬性是否需要綁定,或者它是否應該不發生。另外你可以替換默認的數據源,指定模型綁定器(Model Binder)的數據源。下面的是模型綁定 Attribute 的列表:

  • [BindRequired]:這個 Attribute 表示如果這個綁定不能發生,將添加一個模型狀態錯誤(Model State Error)。
  • [BindNever]:告訴模型綁定器(Model Binder)這個參數不進行綁定。
  • [FromHeader][FromQuery][FromRoute][FromForm]:通過這些來指定期望的綁定源。
  • [FromServices]:這個 Attribute 使用 dependency injection 通過服務來綁定參數。
  • [FromBody]:使用配置好的格式化器來 從 HTTP 請求 Body 中綁定數據。格式化器的選擇基於 HTTP 請求的 Content-Type
    [ModelBinder]:用來替換默認的模型綁定器(Model Binder),綁定源和名字。

當你需要替換模型綁定的默認行為時,Attribute 是非常有用的工具。

從 Http Request 的 body 中綁定格式化數據

HTTP 請求數據能夠支持各種各樣的格式,包括 JSON 、XML 以及許多其它的格式。當你使用 [FromBody] 特性的時候表示你想要從 HTTP 請求的 Body 中綁定參數, MVC 使用一個格式化器的配置集來處理與 HTTP 請求的 Content-Type 對應的請求數據。默認情況下 MVC 包含一個 JsonInputFormatter 類用來處理 JSON 數據,但是你可以添加額外的格式化器來處理 XML 或者其它自定義格式。

提示
JsonInputFormatter 是默認的格式化器,它是基於 Json.NET

ASP.NET 選擇輸入格式化器基於 Content-Type Header 以及參數的類型,除非這里有一個 Attribute 去指定其它的。如果你更喜歡使用 XML 或者其他格式,你必須在 Startup.cs 文件中進行配置,但是首先你必須使用 NuGet 引用 Microsoft.AspNetCore.Mvc.Formatters.Xml 。你的啟動代碼看起來應該像這樣:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
       .AddXmlSerializerFormatters();
}

Startup.cs 文件中的代碼包含了一個帶有 services 參數的 ConfigureServices 方法,你可以使用它來為你的 ASP.NET 應用構建服務。在示例中,我們添加一個 XML 格式化器作為一個在此應用中 MVC 能夠提供的的服務。 options 參數傳入 AddMvc 方法允許你去添加和管理過濾器(Filter),格式化器(Formatter),以及其它 MVC 的系統選項從應用中啟動。然后應用 各種各樣的 Attribute 到 Controller 類或者 Action 方法上去實現你預期的效果。

返回目錄


免責聲明!

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



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