欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ASP.NET MVC Model绑定(六)

程序员文章站 2022-07-01 18:17:56
asp.net mvc model绑定(六) 前言 前面的篇幅对于ivalueprovider的使用做个基础的示例讲解,但是没并没有对 ivalueprovider类型的实现做详细的介绍,然而mvc...

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

    show
@using (html.beginform("update", "valueprovidercase"))
{
    

@html.editorformodel()

@html.editorfor(m => model.address)


}

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

ASP.NET MVC Model绑定(六)

如果这个时候我们单击提交按钮会把数据会变成什么样子呢?数据到了当前上下文中。

namevaluecollection

为什么要讲到namevaluecollection类型呢,因为namevaluecollectionvalueprovider类型中的操作就是针对的namevaluecollection类型的,这里我们来看图1中点击提交后的的数据展示如图2

图2

ASP.NET MVC Model绑定(六)

说好了数据呢?大家别急,图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";
}

    update

@html.editorformodel()

@html.editorfor(m => model.address)

这个时候我们可以运行项目,首先看到show页面后,修改其中的值,然后提交过后会看到修改的值已经更新到了update的界面中。


作者:金源

出处:https://blog.csdn.net/jinyuan0829

本文版权归作者和csdn共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面