前面的篇幅對於IValueProvider的使用作個基礎的示例講解,可是沒並無對 IValueProvider類型的實現作詳細的介紹,然而MVC框架中給咱們提供了幾種默認的實現類型,在本篇中將會對NameValueCollectionValueProvider類型作一個示例講解,瞭解一下MVC框架給咱們提供的值提供程序是怎麼處理Model值的。框架
前面的一篇中咱們對IValueProvider的使用做了示例演示,那是一個從控制器方法到視圖的一個綁定的過程,你們有沒有想過在視圖裏的數據是怎麼在綁定回控制器部分的。視圖中的數據類型的不一樣對應的使用綁定的類型也不一樣,本篇就爲你們示例一個自定義類型的綁定。ide
代碼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。測試
首先咱們須要數據展現:spa
代碼1-2:code
public class ValueProviderCaseController : Controller { public ViewResult Show(Customer customer) { return View(customer); } }
代碼1-2中定義了個Show()方法,參數類型爲代碼1-1所示類型。orm
看下Show()方法對應的視圖,固然了這樣建立的是強類型視圖,代碼1-3.blog
代碼1-3get
@model ConsoleApplication2.Customer @{ ViewBag.Title = "Show"; } <h2> Show</h2> @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.input
代碼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"; } <h2> Update</h2> <p>@Html.EditorForModel()</p> <p>@Html.EditorFor(m => Model.Address)</p>
這個時候咱們能夠運行項目,首先看到Show頁面後,修改其中的值,而後提交事後會看到修改的值已經更新到了Update的界面中。
做者:金源
出處:http://www.cnblogs.com/jin-yuan/
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面