博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET MVC Model绑定(六)
阅读量:6291 次
发布时间:2019-06-22

本文共 5577 字,大约阅读时间需要 18 分钟。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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:

1
2
3
4
5
6
7
8
    
public 
class 
ValueProviderCaseController : Controller
    
{
        
public 
ViewResult Show(Customer customer)
        
{
            
return 
View(customer);
        
}
 
    
}

代码1-2中定义了个Show()方法,参数类型为代码1-1所示类型。

看下Show()方法对应的视图,当然了这样创建的是强类型视图,代码1-3.

代码1-3

1
2
3
4
5
6
7
8
9
10
11
12
13
@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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
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这样获取而来,也就是上面说到的点击&ldquo;提交&rdquo;后所形成的数据类型。而我们的NameValueCollectionValueProvider类型则是对NameValueCollection类型的处理,具体的内部处理细节就不在这详细描述了。

下面我们需要做提交后的操作,就是显示到更新界面,那我们得按照上面代码1-3中的定义的那样,需要个Update()方法,示例代码1-5.

代码1-5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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

1
2
3
4
5
6
7
8
@model ConsoleApplication2.Customer
@{
    
ViewBag.Title = "Update";
}
<
h2
>
    
Update</
h2
>
<
p
>@Html.EditorForModel()</
p
>
<
p
>@Html.EditorFor(m => Model.Address)</
p
>

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

     本文转自jinyuan0829 51CTO博客,原文链接:http://blog.51cto.com/jinyuan/1434205,如需转载请自行联系原作者

你可能感兴趣的文章
浅谈MySQL 数据库性能优化
查看>>
《UNIX/Linux 系统管理技术手册(第四版)》——1.10 其他的权威文档
查看>>
灵动空间 创享生活
查看>>
《UNIX网络编程 卷1:套接字联网API(第3版)》——8.6 UDP回射客户程序:dg_cli函数...
查看>>
不要将时间浪费到编写完美代码上
查看>>
《算法基础:打开算法之门》一3.4 归并排序
查看>>
高德开放平台开放源代码 鼓励开发者创新
查看>>
《高并发Oracle数据库系统的架构与设计》一2.5 索引维护
查看>>
Firefox 是 Pwn2own 2014 上攻陷次数最多的浏览器
查看>>
阿里感悟(十八)- 应届生Review
查看>>
话说模式匹配(5) for表达式中的模式匹配
查看>>
《锋利的SQL(第2版)》——1.7 常用函数
查看>>
jquery中hover()的用法。简单粗暴
查看>>
线程管理(六)等待线程的终结
查看>>
spring boot集成mongodb最简单版
查看>>
DELL EqualLogic PS存储数据恢复全过程整理
查看>>
《Node.js入门经典》一2.3 安装模块
查看>>
《Java 开发从入门到精通》—— 2.5 技术解惑
查看>>
Linux 性能诊断 perf使用指南
查看>>
实操分享:看看小白我如何第一次搭建阿里云windows服务器(Tomcat+Mysql)
查看>>