溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

ASP.NET MVC Model綁定(六)

發(fā)布時(shí)間:2020-06-23 12:56:22 來源:網(wǎng)絡(luò) 閱讀:763 作者:jinyuan0829 欄目:編程語言

ASP.NET MVC Model綁定(六)

前言

前面的篇幅對(duì)于IValueProvider的使用做個(gè)基礎(chǔ)的示例講解,但是沒并沒有對(duì) IValueProvider類型的實(shí)現(xiàn)做詳細(xì)的介紹,然而MVC框架中給我們提供了幾種默認(rèn)的實(shí)現(xiàn)類型,在本篇中將會(huì)對(duì)NameValueCollectionValueProvider類型做一個(gè)示例講解,了解一下MVC框架給我們提供的值提供程序是怎么處理Model值的。

 

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

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

ASP.NET MVC Model綁定(六)

如果這個(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

ASP.NET MVC Model綁定(六)

說好了數(shù)據(jù)呢?大家別急,圖2中的是NameValueCollection類型的AllKeys屬性中的值,而NameValueCollection類型的實(shí)例是通過controllerContext.HttpContext.Request.Form這樣獲取而來,也就是上面說到的點(diǎn)擊&ldquo;提交&rdquo;后所形成的數(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的界面中。

向AI問一下細(xì)節(jié)

免責(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)容。

AI