您的位置:首页 > 移动开发 > Objective-C

浅谈在asp.net mvc3中使用IValidatableObject接口实现Model数据验证

2011-06-07 16:23 459 查看
ASP.NETMVC3新增了许多新特性,IValidatableObject接口就是新增的诸多特性之一。ASPNETMBC3该书中是这样描述的:IValidatableObject接口允许执行Model水平的验证,并且允许你提供整个模型状态的验证错误信息,或者基于Model的两个属性。当Model绑定的时候,MVC3从IValidatableObject接收错误信息,在视图中使用内建的HTML助手时,将会自动标识或者高亮受影响的字段。

可能有人会问了,Mvc2中可以使用自定义验证来对模型进行验证,为什么mvc3中又新增了IValidatableObject这个借口呢?

不错,我们是可以通过继承ValidationAttribute类并且重写它的IsValid方法来自定义验证,但是这中做法有个局限性,那就是如果我需要验证模型的各个属性之间的逻辑关系,例如:我们有一个商品模型,我们要求这个模型的出库数量不能大于库存数量,那么自定义验证就显得不是那么给力了,这时候我们就需要ValidationAttribute接口了。

首先我们这个商品模型Product.cs需要实现ValidationAttribute接口,然后实现Validate这个方法。

viewsourceprint?

03
public
class
Product:IValidatableObject
04
{
05
///<summary>
06
///产品名称
07
///</summary>
08
[DisplayName(
"产品名称"
)]
09
[AllowHtml]
//允许输入html脚本
10
[Required]
11
public
StringName{
get
;
set
;}
12
///<summary>
13
///库存数量
14
///</summary>
15
[DisplayName(
"库存"
)]
16
[Required]
17
public
int
Inventory{
get
;
set
;}
18
19
///<summary>
20
///销售数量
21
///</summary>
22
[DisplayName(
"售出"
)]
23
[Required]
24
public
int
Shipping{
get
;
set
;}
25
26
27
public
IEnumerable<ValidationResult>Validate(ValidationContextvalidationContext)
28
{
29
30
if
(Shipping>Inventory)
31
{
32
yield
return
new
ValidationResult(
"出库数量不能大于库存数量"
,
new
string
[]{
"Shipping"
});
33
}
34
}
35
36
37
38
}
Index.cshtml

viewsourceprint?

03
@model数据验证.Product
04
05
@{
06
Layout=
null
;
07
}
08
09
<!DOCTYPEhtml>
10
11
<html>
12
<head>
13
<title>Index</title>
14
</head>
15
<body>
16
<scriptsrc=
"http://www.cnblogs.com/Scripts/jquery-1.4.4.min.js"
type=
"text/javascript"
></script>
17
<scriptsrc=
"http://www.cnblogs.com/Scripts/jquery.validate.min.js"
type=
"text/javascript"
></script>
18
<scriptsrc=
"http://www.cnblogs.com/Scripts/jquery.validate.unobtrusive.min.js"
type=
"text/javascript"
></script>
19
20
@
using
(Html.BeginForm()){
21
@Html.ValidationSummary(
true
)
22
<fieldset>
23
<legend>Product</legend>
24
25
<div
class
=
"editor-label"
>
26
@Html.LabelFor(model=>model.Name)
27
</div>
28
<div
class
=
"editor-field"
>
29
@Html.EditorFor(model=>model.Name)
30
@Html.ValidationMessageFor(model=>model.Name)
31
</div>
32
33
<div
class
=
"editor-label"
>
34
@Html.LabelFor(model=>model.Inventory)
35
</div>
36
<div
class
=
"editor-field"
>
37
@Html.EditorFor(model=>model.Inventory)
38
@Html.ValidationMessageFor(model=>model.Inventory)
39
</div>
40
41
<div
class
=
"editor-label"
>
42
@Html.LabelFor(model=>model.Shipping)
43
</div>
44
<div
class
=
"editor-field"
>
45
@Html.EditorFor(model=>model.Shipping)
46
@Html.ValidationMessageFor(model=>model.Shipping)
47
</div>
48
49
<p>
50
<inputtype=
"submit"
value=
"Create"
/>
51
</p>
52
</fieldset>
53
}
54
55
<div>
56
@Html.ActionLink(
"BacktoList"
,
"Index"
)
57
</div>
58
59
</body>
60
</html>
当我们输入出库的数量大于库存的数量时,那么我们会得到错误提示,OK搞定了。

但是还有一个小问题,Validate方法中定义的错误提示,两个属性的名称是我们硬编码的,不利于我们的维护,试想假如有一天我们将Inventory和Shipping的Display属性分别改成别的名称,那么我们原来的错误提示”出库数量不能大于库存数量”就不太恰当了,为了解决这个问题,我们可以使用反射来获取这两个属性的DisplayName值,上代码:

EntityAttribute.cs

viewsourceprint?

03
public
class
EntityAttribute
04
{
05
private
Typetype;
06
public
EntityAttribute(Typetype)
07
{
08
this
.type=type;
09
}
10
public
string
GetDisplayAttributeName(
string
propertyName)
11
{
12
varpropertyInfo=type.GetProperty(propertyName);
13
object
[]attrs=propertyInfo.GetCustomAttributes(
typeof
(DisplayNameAttribute),
true
);
14
return
(attrs[0]
as
DisplayNameAttribute).DisplayName;
15
}
16
}
这个EntityAttribute.cs类可以返回指定模型类的指定属性的DisplayName值。

然后我们在更新我们的Product.cs代码

viewsourceprint?

03
public
class
Product:IValidatableObject
04
{
05
///<summary>
06
///产品名称
07
///</summary>
08
[DisplayName(
"产品名称"
)]
09
[AllowHtml]
//允许输入html脚本
10
[Required]
11
public
StringName{
get
;
set
;}
12
///<summary>
13
///库存数量
14
///</summary>
15
[DisplayName(
"库存"
)]
16
[Required]
17
public
int
Inventory{
get
;
set
;}
18
19
///<summary>
20
///销售数量
21
///</summary>
22
[DisplayName(
"售出"
)]
23
[Required]
24
public
int
Shipping{
get
;
set
;}
25
26
27
28
public
IEnumerable<ValidationResult>Validate(ValidationContextvalidationContext)
29
{
30
Typetype=
typeof
(Product);
31
EntityAttributeentityAttribute=
new
EntityAttribute(type);
32
PropertyInfo[]PropertyInfos=type.GetProperties();
33
string
shippingDisplayName=entityAttribute.GetDisplayAttributeName(
"Shipping"
);
34
string
inventoryDisplayName=entityAttribute.GetDisplayAttributeName(
"Inventory"
);
35
if
(Shipping>Inventory)
36
{
37
yield
return
new
ValidationResult(
string
.Format(
"{0}数量不能大于{1}数量"
,shippingDisplayName,inventoryDisplayName),
new
string
[]{
"Shipping"
});
38
}
39
}
40
41
}
这回终于大功告成了!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐