本文的环境是Asp.net Mvc Codeplex Preview 5
前文提到我们可以使用 Controller中的UpdateModel来获取 繁杂类型
例如
UpdateModel(x, Request.Form.AllKeys);
但是这里有些问题,当我们使用Request.Form.AllKeys时,提交的数据中有非x属性时,就会发生错误:
The model of type ‘MyModel‘ does not have a property named ‘Name2‘.
但是使用
UpdateModel(x,
new
[] {
“
IDX
“
,
“
Name
“
});
这种形式,我们又会觉得它太过麻烦。
其实Asp.net Mvc为我们提供了一种很简单的传递复杂数据的方式,它类似于Monorail中的DataBinder:
我们完全可以通过以下方式来传递数据。例如
view:
<%
using (Html.Form(
“
home
“
,
“
about
“
, FormMethod.Post)) {
%>
2
<%
=
Html.TextBox(
“
my.ID
“
)
%>
3
<%
=
Html.TextBox(
“
my.Name
“
)
%>
4
<%
=
Html.SubmitButton()
%>
5
<%
}
%>
controller:
“
post
“
)]
public
ActionResult About([ModelBinder(
typeof
(MyModelBinder))]MyModel my) {
ViewData[
“
Title
“
]
=
my.Name
+
my.ID;
return
View();
}
这样我们就可以从my中获取到Post过来的值了,这里的关键在于[ModelBinder(typeof(MyModelBinder))]
而 MyModelBinder的实现方法如下
using
System;
2
using
System.Collections.Generic;
3
using
System.ComponentModel;
4
using
System.Globalization;
5
using
System.Linq;
6
using
System.Web.Mvc;
7
8
///
<summary>
9
///
这个类是根据Controller.UpdateModel方法更改而成
10
///
</summary>
11
public
class
MyModelBinder : IModelBinder{
12
#region
IModelBinder 成员
13
14
public
object
GetValue(ControllerContext controllerContext,
string
modelName, Type modelType,
15
ModelStateDictionary modelState){
16
object
model
=
Activator.CreateInstance(modelType);
//
将做为参数的类实例化了
17
IEnumerable
<
string
>
keys
=
modelType.GetProperties().Select(c
=>
c.Name);
//
得到该对象的属性的名的字符串数组,这里的结果应该为[“ID”,”Name”]
18
string
objectPrefix
=
modelName;
//
这个就是,我的对象名叫my则会检查 name=”my.ID” name=”my.Name”的表单字段
19
20
PropertyDescriptorCollection properties
=
TypeDescriptor.GetProperties(model);
//
对象的属性的集合
21
var dictionary
=
new
Dictionary
<
string
, PropertyDescriptor
>
();
22
foreach
(
string
str
in
keys){
23
//
遍历属性的字符串集合即[“ID”,”Name”]
24
if
(
!
string
.IsNullOrEmpty(str)){
25
PropertyDescriptor descriptor
=
properties.Find(str,
true
);
26
if
(descriptor
==
null
){
27
throw
new
ArgumentException(
28
string
.Format(CultureInfo.CurrentUICulture,
“
无此属性{0},{1}
“
,
new
object
[]{model.GetType().FullName, str}),
29
“
modelName
“
);
30
}
31
string
str3
=
string
.IsNullOrEmpty(objectPrefix)
?
str : (objectPrefix
+
“
.
“
+
str);
//
将对象名与属性名拼接,如my.ID
32
dictionary[str3]
=
descriptor;
33
}
34
}
35
foreach
(var pair
in
dictionary){
36
string
key
=
pair.Key;
37
PropertyDescriptor descriptor2
=
pair.Value;
38
object
obj2
=
ModelBinders.GetBinder(descriptor2.PropertyType).GetValue(controllerContext, key,
39
descriptor2.PropertyType, modelState);
40
if
(obj2
!=
null
){
41
try
{
42
descriptor2.SetValue(model, obj2);
//
设置属性的值
43
continue
;
44
}
45
catch
{
46
//
如果有使用验证Helepr则会显示在Html.ValidationSummary中
47
string
errorMessage
=
string
.Format(CultureInfo.CurrentCulture,
“
验证失败{0}:{1}
“
,
new
[]{obj2, descriptor2.Name});
48
string
attemptedValue
=
Convert.ToString(obj2, CultureInfo.CurrentCulture);
49
modelState.AddModelError(key, attemptedValue, errorMessage);
50
continue
;
51
}
52
}
53
}
54
return
model;
//
最后 返回这个我们设置完属性的对象
55
}
56
57
#endregion
58
}
这样我们就实现了 用Action的参数传递复杂类型。
当然,如果你连[ModelBinder(typeof(MyModelBinder))]都不想写了,想直接来以下写法,
[AcceptVerbs(
“
post
“
)]
2
public
ActionResult About(MyModel my) {
3
ViewData[
“
Title
“
]
=
my.Name
+
my.ID;
4
return
View();
5
}
这个也是可以的不过你要在Application_Start中添加
ModelBinders.Binders.Add(typeof (MyModel), new MyModelBinder());
来表示二者的绑定关系。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/110860.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...