您好,登錄后才能下訂單哦!
前面的篇幅對(duì)于IValueProvider的使用做個(gè)基礎(chǔ)的示例講解,但是沒并沒有對(duì) IValueProvider類型的實(shí)現(xiàn)做詳細(xì)的介紹,然而MVC框架中給我們提供了幾種默認(rèn)的實(shí)現(xiàn)類型,在本篇中將會(huì)對(duì)NameValueCollectionValueProvider類型做一個(gè)示例講解,了解一下MVC框架給我們提供的值提供程序是怎么處理Model值的。
IModelBinder、自定義Model綁定器簡(jiǎn)單實(shí)現(xiàn)
Model綁定器在MVC框架中的位置
MVC中的默認(rèn)Model綁定器生成過程
IModelBinderProvider的簡(jiǎn)單應(yīng)用
IValueProvider在MVC框架中生成的位置以及過程
IValueProvider的應(yīng)用場(chǎng)景
IValueProvider的實(shí)現(xiàn)之NameValueCollectionValueProvider
前面的一篇中我們對(duì)IValueProvider的使用作了示例演示,那是一個(gè)從控制器方法到視圖的一個(gè)綁定的過程,大家有沒有想過在視圖里的數(shù)據(jù)是怎么在綁定回控制器部分的。視圖中的數(shù)據(jù)類型的不同對(duì)應(yīng)的使用綁定的類型也不同,本篇就為大家示例一個(gè)自定義類型的綁定。
代碼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="注冊(cè)日期")] public DateTime RegistrationDate{ get; set; } [UIHint("Address")] public Address Address { get; set; } } public class Address { [Display(Name="地址名稱")] [MyCustomMetadataAware] public string AddressName { get; set; } }
對(duì)的代碼1-1中的類型已經(jīng)出現(xiàn)過很多次了,但是出于對(duì)沒看過前面篇幅的朋友負(fù)責(zé)的態(tài)度也要加上阿,這是下面示例要用到的示例ViewModel。
首先我們需要數(shù)據(jù)展示:
代碼1-2:
public class ValueProviderCaseController : Controller { public ViewResult Show(Customer customer) { return View(customer); } }
代碼1-2中定義了個(gè)Show()方法,參數(shù)類型為代碼1-1所示類型。
看下Show()方法對(duì)應(yīng)的視圖,當(dāng)然了這樣創(chuàng)建的是強(qiáng)類型視圖,代碼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()方法,這個(gè)后面會(huì)說到,暫且?guī)н^?,F(xiàn)在這個(gè)時(shí)候我們還運(yùn)行不了項(xiàng)目,我們需要為代碼1-2中的Show()配置一個(gè)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 = "測(cè)試人員", RegistrationDate = DateTime.Now, Address = new Address() { AddressName = "天空之城" } }; } return null; } }
從代碼1-4中,我們可以看到對(duì)Model綁定器做了控制,使它在請(qǐng)求類型為Get的時(shí)候返回代碼1-1所示類型的ViewModel實(shí)例。因?yàn)楹竺娴氖纠覀円策€會(huì)用到這個(gè)Model綁定器,所以加了控制。對(duì)于Model綁定器的注冊(cè)這里就不說了,運(yùn)行結(jié)果如圖1.
圖1
如果這個(gè)時(shí)候我們單擊提交按鈕會(huì)把數(shù)據(jù)會(huì)變成什么樣子呢?數(shù)據(jù)到了當(dāng)前系統(tǒng)上下文中。
NameValueCollection
為什么要講到NameValueCollection類型呢,因?yàn)镹ameValueCollectionValueProvider類型中的操作就是針對(duì)的NameValueCollection類型的,這里我們來看圖1中點(diǎn)擊提交后的的數(shù)據(jù)展示如圖2
圖2
說好了數(shù)據(jù)呢?大家別急,圖2中的是NameValueCollection類型的AllKeys屬性中的值,而NameValueCollection類型的實(shí)例是通過controllerContext.HttpContext.Request.Form這樣獲取而來,也就是上面說到的點(diǎn)擊“提交”后所形成的數(shù)據(jù)類型。而我們的NameValueCollectionValueProvider類型則是對(duì)NameValueCollection類型的處理,具體的內(nèi)部處理細(xì)節(jié)就不在這詳細(xì)描述了。
下面我們需要做提交后的操作,就是顯示到更新界面,那我們得按照上面代碼1-3中的定義的那樣,需要個(gè)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); } }
這個(gè)時(shí)候我們是看不到綁定器內(nèi)部的實(shí)現(xiàn)的,所以我們來模擬一下,修改上面代碼1-4中的內(nèi)容,如示例代碼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 = "測(cè)試人員", 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類型想象成一個(gè)鍵值隊(duì)類型的集合,并且NameValueCollection類型的實(shí)例已經(jīng)包含著所有數(shù)據(jù)了,可以使用它內(nèi)部的GetValue方法(并非代碼1-6中的GetValue方法)來獲取所對(duì)應(yīng)的值,在NameValueCollectionValueProvider類型內(nèi)部也是使用的這個(gè)方法來獲取的值。
在代碼1-6中我們對(duì)Model綁定器修改了太多了,首先是控制器了在請(qǐng)求類型為POST的時(shí)候(也就是為了在請(qǐng)求Update()方法時(shí)所用)使用這個(gè)Model綁定器,隨之我們實(shí)例化了一個(gè)代碼1-1中所示的ViewModel實(shí)例,后面會(huì)對(duì)它進(jìn)行賦值,隨后我們通過上下文獲取到表單中的數(shù)據(jù)(NameValueCollection類型的實(shí)例)作為NameValueCollectionValueProvider類型構(gòu)造函數(shù)的參數(shù),我們還在Model綁定器中定義了個(gè)私有的GetValue()方法,這個(gè)的用途就是根據(jù)執(zhí)行的前綴(NameValueCollection類型中的鍵值,也就是視圖元素中的Name屬性)從NameValueCollectionValueProvider類型的實(shí)例中獲取對(duì)應(yīng)的數(shù)據(jù)。
現(xiàn)在看一下Update()方法所對(duì)應(yīng)的視圖代碼,示例代碼1-7
@model ConsoleApplication2.Customer @{ ViewBag.Title = "Update"; } <h3> Update</h3> <p>@Html.EditorForModel()</p> <p>@Html.EditorFor(m => Model.Address)</p>
這個(gè)時(shí)候我們可以運(yùn)行項(xiàng)目,首先看到Show頁面后,修改其中的值,然后提交過后會(huì)看到修改的值已經(jīng)更新到了Update的界面中。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。