您好,登錄后才能下訂單哦!
前面的篇幅對于IValueProvider的使用做個基礎的示例講解,但是沒并沒有對 IValueProvider類型的實現做詳細的介紹,然而MVC框架中給我們提供了幾種默認的實現類型,在本篇中將會對NameValueCollectionValueProvider類型做一個示例講解,了解一下MVC框架給我們提供的值提供程序是怎么處理Model值的。
IModelBinder、自定義Model綁定器簡單實現
Model綁定器在MVC框架中的位置
MVC中的默認Model綁定器生成過程
IModelBinderProvider的簡單應用
IValueProvider在MVC框架中生成的位置以及過程
IValueProvider的應用場景
IValueProvider的實現之NameValueCollectionValueProvider
前面的一篇中我們對IValueProvider的使用作了示例演示,那是一個從控制器方法到視圖的一個綁定的過程,大家有沒有想過在視圖里的數據是怎么在綁定回控制器部分的。視圖中的數據類型的不同對應的使用綁定的類型也不同,本篇就為大家示例一個自定義類型的綁定。
代碼1-1
public class Customer { [HiddenInput(DisplayValue=true)] public string CustomerID { get; set; } [Display(Name="姓名")] public string Name { get; set; } [DataType(DataType.Date)] [Display(Name="注冊日期")] public DateTime RegistrationDate{ get; set; } [UIHint("Address")] public Address Address { get; set; } } public class Address { [Display(Name="地址名稱")] [MyCustomMetadataAware] public string AddressName { get; set; } }
對的代碼1-1中的類型已經出現過很多次了,但是出于對沒看過前面篇幅的朋友負責的態度也要加上阿,這是下面示例要用到的示例ViewModel。
首先我們需要數據展示:
代碼1-2:
public class ValueProviderCaseController : Controller { public ViewResult Show(Customer customer) { return View(customer); } }
代碼1-2中定義了個Show()方法,參數類型為代碼1-1所示類型。
看下Show()方法對應的視圖,當然了這樣創建的是強類型視圖,代碼1-3.
代碼1-3
@model ConsoleApplication2.Customer @{ ViewBag.Title = "Show"; } <h3> Show</h3> @using (Html.BeginForm("Update", "ValueProviderCase")) { <p>@Html.EditorForModel()</p> <p>@Html.EditorFor(m => Model.Address)</p> <br /> <input type="submit" value="提交" /> }
在代碼1-3中,我們也看到了,使用了BeginForm()視圖輔助器,并且令表單指向ValueProviderCase 控制器的Update()方法,這個后面會說到,暫且帶過。現在這個時候我們還運行不了項目,我們需要為代碼1-2中的Show()配置一個Model綁定器,代碼1-4.
代碼1-4
public class MyCustomModelBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { if (controllerContext.HttpContext.Request.RequestType == "GET") { return new Customer() { CustomerID = "010", Name = "測試人員", RegistrationDate = DateTime.Now, Address = new Address() { AddressName = "天空之城" } }; } return null; } }
從代碼1-4中,我們可以看到對Model綁定器做了控制,使它在請求類型為Get的時候返回代碼1-1所示類型的ViewModel實例。因為后面的示例我們也還會用到這個Model綁定器,所以加了控制。對于Model綁定器的注冊這里就不說了,運行結果如圖1.
圖1
如果這個時候我們單擊提交按鈕會把數據會變成什么樣子呢?數據到了當前系統上下文中。
NameValueCollection
為什么要講到NameValueCollection類型呢,因為NameValueCollectionValueProvider類型中的操作就是針對的NameValueCollection類型的,這里我們來看圖1中點擊提交后的的數據展示如圖2
圖2
說好了數據呢?大家別急,圖2中的是NameValueCollection類型的AllKeys屬性中的值,而NameValueCollection類型的實例是通過controllerContext.HttpContext.Request.Form這樣獲取而來,也就是上面說到的點擊“提交”后所形成的數據類型。而我們的NameValueCollectionValueProvider類型則是對NameValueCollection類型的處理,具體的內部處理細節就不在這詳細描述了。
下面我們需要做提交后的操作,就是顯示到更新界面,那我們得按照上面代碼1-3中的定義的那樣,需要個Update()方法,示例代碼1-5.
代碼1-5
public class ValueProviderCaseController : Controller { public ViewResult Show(Customer customer) { return View(customer); } [HttpPost] public ActionResult Update(Customer customer) { return View(customer); } }
這個時候我們是看不到綁定器內部的實現的,所以我們來模擬一下,修改上面代碼1-4中的內容,如示例代碼1-6.
代碼1-6
public class MyCustomModelBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { if (controllerContext.HttpContext.Request.RequestType == "GET") { return new Customer() { CustomerID = "010", Name = "測試人員", RegistrationDate = DateTime.Now, Address = new Address() { AddressName = "天空之城" } }; } else if (controllerContext.HttpContext.Request.RequestType == "POST") { Customer customer = new Customer(); customer.Address = new Address(); NameValueCollection nameValueCollection = controllerContext.HttpContext.Request.Form; NameValueCollectionValueProvider nameValueCollectionValueProvider = new NameValueCollectionValueProvider( nameValueCollection, System.Globalization.CultureInfo.InstalledUICulture); customer.CustomerID = GetValue(nameValueCollectionValueProvider, "CustomerID"); customer.Name = GetValue(nameValueCollectionValueProvider, "Name"); customer.RegistrationDate = DateTime.Parse(GetValue(nameValueCollectionValueProvider, "RegistrationDate")); customer.Address.AddressName = GetValue(nameValueCollectionValueProvider, "Address.AddressName"); return customer; } return null; } private string GetValue(IValueProvider valueProvider, string preFix) { return valueProvider.ContainsPrefix(preFix) ? valueProvider.GetValue(preFix).AttemptedValue : null; } }
這里忘了說了,可以把NameValueCollection類型想象成一個鍵值隊類型的集合,并且NameValueCollection類型的實例已經包含著所有數據了,可以使用它內部的GetValue方法(并非代碼1-6中的GetValue方法)來獲取所對應的值,在NameValueCollectionValueProvider類型內部也是使用的這個方法來獲取的值。
在代碼1-6中我們對Model綁定器修改了太多了,首先是控制器了在請求類型為POST的時候(也就是為了在請求Update()方法時所用)使用這個Model綁定器,隨之我們實例化了一個代碼1-1中所示的ViewModel實例,后面會對它進行賦值,隨后我們通過上下文獲取到表單中的數據(NameValueCollection類型的實例)作為NameValueCollectionValueProvider類型構造函數的參數,我們還在Model綁定器中定義了個私有的GetValue()方法,這個的用途就是根據執行的前綴(NameValueCollection類型中的鍵值,也就是視圖元素中的Name屬性)從NameValueCollectionValueProvider類型的實例中獲取對應的數據。
現在看一下Update()方法所對應的視圖代碼,示例代碼1-7
@model ConsoleApplication2.Customer @{ ViewBag.Title = "Update"; } <h3> Update</h3> <p>@Html.EditorForModel()</p> <p>@Html.EditorFor(m => Model.Address)</p>
這個時候我們可以運行項目,首先看到Show頁面后,修改其中的值,然后提交過后會看到修改的值已經更新到了Update的界面中。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。