使用json 繫結grid_理解ASP.NET Core中的模型繫結
技術標籤:使用json 繫結grid資料繫結發生referenceerror
當MVC通過路由將請求對映到一個Action後,為了執行這個Action,首先需要進行模型繫結。那麼,什麼是模型繫結呢?
一、理解模型繫結
模型繫結是將HTTP請求中的資料對映到MVC中的Action方法的引數的過程,它發生在MVC已經通過路由將請求定位到目標Controller和目標Action之後以及執行Action之前。
當找到了目標Action方法後,為了要執行它,首先需要檢查它的引數併為它們賦值,這些引數的值通常會從當前請求中獲取。
// URL: /search?type=name&order=descpublic IActionResult Search(string type, string order){ // …}
Action方法的引數型別可以是簡單的資料型別,如int、string等,也可以是複雜的資料型別,如自定義類等。當進行模型繫結時,MVC會根據方法中的引數名並從HTTP請求中獲取相應的資料。
預設情況下,MVC認為HTTP請求提供資料的方式有以下三種:
1、表單值:通過HTTP POST請求所提交的一組表單資料;
2、路由值:通過路由中介軟體處理併為路由引數賦值;
3、查詢字串:通過URL中的查詢字串提供;
以上這些資料來源均以key-value的形式提供資料。模型繫結會按照順序從上述三個位置按照指定的key(即Action方法的引數名)來查詢引數的值。以下分別展示了上述三種情況:
1、從表單獲取
// 從表單獲取@using(var form = Html.BeginForm()){
@Html.LabelFor(m => m.FirstName) @Html.TextBoxFor(m => m.FirstName)
@Html.LabelFor(m => m.LastName) @Html.TextBoxFor(m => m.LastName)
}public IActionResult CreateUser(User user){ // …}
2、從路由獲取
請求URL:/home/index/3,約定的路由模板:"{contoller}/{action}/{id?}"
public IActionResult(int id){ // …}
3、從查詢字串獲取:
請求URL:/search?type=info&order=desc
publicIActionResultSearch(stringtype,stringorder){//…}
可以看出,模型繫結功能十分強大,它不僅能夠為簡單的引數型別繫結值,它還能夠為自定義類提供繫結值。上例中的繫結表單值就是將多個簡單資料型別的值對映到一個自定義類,在進行這種繫結時,模型繫結會根據自定義類的屬性名稱來進行繫結,將資料來源中的相應的引數賦值給自定義類中的同名屬性。
也因此,當自定義類作為Action方法的引數時,它必須具有一個預設的建構函式(即public型別且不帶引數),並且其中需要模型繫結賦值的屬性也應該是public型別且帶有get和set段,即支援屬性值讀取和寫入。
public class User{ public string FirstName { get; set; } public string LastName { get; set; }}
當繫結失敗時,比如在所有的資料來源中均沒有找到預期的值,模型繫結並不會丟擲異常,相反,它會為Action引數提供相應引數型別的預設值,如字串是null、int為0、自定義類則是一個屬性包含預設值的例項。
提示:為了檢查繫結是否成功,你可以使用ControllerBase類提供的Model屬性的IsValid屬性來檢查繫結是否有問題,ModelState屬性表示一個包含了ModelStateEntry的集合,它裡面包含了綁定出錯的所有情況。
二、自定義繫結方式
剛才我們討論的繫結都是模型繫結所提供的預設方式,MVC提供了一些特性,使用它們能夠改變引數獲取值的方式,它們包括:
1、[FromHeader]:從HTTP訊息頭中為引數獲取值,HTTP訊息頭也包含了一組key-value形式的值;
2、[FromQuery]:從查詢字串中為引數獲取值;
3、[FromRoute]:從路由中為引數獲取值;
4、[FromFrom]:從表單資料中為引數獲取值;
5、[FromBody]:從HTTP請求的正文中為引數獲取值(同一個Action中最多隻能有一個引數使用這種方式獲取);
6、[FromServices]:從依賴注入容器中為引數獲取值(這種方式提供的資料並不是從HTTP請求中獲取);
7、[ModelBinder]:使用自定義模型繫結方式為引數提供值,自定義模型繫結需要實現IModelBinder介面;
通過使用這些特效能夠改變Action方法引數獲取值的方式。此外,還有另外兩個特性用來控制模型繫結的形為:
1、[BindRequired]:必須要求繫結,如果繫結失敗,則會在ModelState中新增一條錯誤資訊;
2、[BindNever]:模型繫結不會處理這個引數;
要使用上述特性時,只要為相應的引數新增即可:
public IActionResult([FromQuery] int parameter1, [FromHeader(Name = "CustomHeader")] string parameter2, [FromService] IDataService parameter3, [FromBody] User parameter4){ // ...}
最後,需要注意的是,當使用[FromBody]方式時,MVC會根據為它配置的資料輸入格式化器(Data Input Formatter)對資料進行處理(也即反序列化)。
預設情況下,ASP.NET Core包含了一個用於處理JSON資料的JsonInputFormatter,它用於將請求正文JSON內容反序列化為一個.NET物件,因此,預設情況下,所提供資料應是JSON格式。而如果希望使用其他格式,如XML,則應為MVC新增相應格式的資料輸入格式化器。
public void ConfigureServices(IServiceCollection services){ services.AddMvc() .AddXmlSerializerFormatters(); }}
上例添加了XML格式的輸入、輸出格式化器,這樣,程式就能夠正確地從正文中獲取XML格式的資料,並繫結到Action的引數上。
總結
本文討論了ASP.NET Core中的模型繫結以及它的使用方式。充分理解模型繫結如何使用,將會幫助我們正確地為Action新增引數以及靈活地為這些引數指定資料值。