• ASP.NET MVC Model绑定(六)


    ASP.NET MVC Model绑定(六)

    前言

    前面的篇幅对于IValueProvider的使用做个基础的演示样例解说,可是没并没有对 IValueProvider类型的实现做具体的介绍。然而MVC框架中给我们提供了几种默认的实现类型,在本篇中将会对NameValueCollectionValueProvider类型做一个演示样例解说,了解一下MVC框架给我们提供的值提供程序是怎么处理Model值的。

     

    Model绑定

    • IModelBinder、自己定义Model绑定器简单实现
    • Model绑定器在MVC框架中的位置
    • MVC中的默认Model绑定器生成过程
    • IModelBinderProvider的简单应用
    • IValueProvider在MVC框架中生成的位置以及过程
    • IValueProvider的应用场景
    • IValueProvider的实现之NameValueCollectionValueProvider

    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";  
    }
    <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.

    代码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

    假设这个时候我们单击提交button会把数据会变成什么样子呢?数据到了当前系统上下文中。

     

    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的界面中。


    作者:金源

  • 相关阅读:
    Vim学习指南
    frambuffer lcd.c
    工控显示界面
    ubuntu nfs 开发板
    java初学1
    使用多态来实现数据库之间的切换
    Space Shooter 太空射击
    CandyCrush 糖果传奇
    进制转换以及原码、反码、补码
    winform小知识
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10706301.html
  • Copyright © 2020-2023  润新知