MVC下实现表单验证可以使用多种方法。国外已经出现了一些Mvc下使用的验证框架。本文中提供的方法只是众多方法之一,可以供学习者参考一二。

在Web开发中,表单提交算是一种很常见的从客户端获取数据的办法了。可是,用户的行为永远都是无法意料的。为此,咱们在程序中不得已有必要对用户输入的数据进行严厉效验。在WebForm年代咱们常用的手法是验证控件,可是到了Mvc年代,再运用控件变得困难了,因而咱们有必要找到新的办法来处理这个问题。

在实际运用中,咱们能够考虑多种形式来进行这一验证(注:本文现在只研讨服务器端验证的状况),最直接的办法莫过于对每个表单值手动用C#代码进行验证了,比如:

MVC下ASP.NET的表单验证完成(asp.net mvc 表单验证)  ASP.NET MVC 表单验证 第1张

if(!Int32.TryParse(Request.Form[“age”], out age)){
xxxx…
}
If(age xxx){
xxxx…
}

可是正如上面看到的相同,这种办法单调而繁琐,需求用户对每个字段都要手动效验,或许开发人员的一不小心就会形成体系的缝隙。因而,制造出一个能对这种行为进行主动进行的轮子势在必行,当然,到本文写作的时分停止,国外现已呈现了一些Mvc下运用的验证结构,可是全国轮子不怕多,我在此厚颜再造出个,只期望不被冠上山寨之名。

该结构的缔造源自4MVC团队的Infancy项目,上一年年末开端这个项目的时分,正是MVC结构参加ModelBinder的时分,其时便想到了通过运用ModelBinder来完成一种服务器端主动验证结构,通过屡次修正,该结构渐渐完成了我需求的功用,本系列文章将再次回忆该进程,将该结构的一步步的完成进程加以更详尽的重现。

下面正式开端结构的开发,首要咱们清晰下咱们的根本需求:

1.该结构针对简略实体类(POCO)

2.该结构能主动对实体类的特点进行效验

3.该实体能被ModelBinder运用

4.能便利或许主动的履行该效验,并获得效验成果和信息

为了完成上面的方针,咱们首要来确认一些需求运用的技术手法:

1.要能拜访恣意POCO的特点,必定用到反射

2.要能对特点进行约束,可挑选运用XML或许Attribute,对程序员来说,Attribute远比XML来的便利和友爱,因而挑选Attribute

3.完成实体验证办法,或许会运用Command形式,也或许不需求

下面开端咱们的实践了,首要咱们考虑测验代码,假定我具有实体Student,Student具有特点Source,要求Source是int类型,且规模为0-100,那么测验代码的形式应该如下:

Student student = new Student(){
Source = -1
};
bool validateResult = student.Validate();
Assert.IsFalse(validateResult);

也便是说,咱们需求在一个验证办法中对该目标的一切特点进行验证,那么咱们考虑对体系各部分的构建,首要咱们需求一个RangeAttribute,这个类能包括对特点的验证信息,大致如下:

public class RangeAttribute : Attribute{
public int Mix{ get; set; } //规模下限
public int Max{ get; set; } //规模上限
public string Message{ get; set;} //犯错信息

public RangeAttribute(int min, int max, string message){
Min = min;
Max = max;
Message = message;
}
}


这样一来咱们的Student就能够如此结构

public class Student{
[Range(0, 100, “分数的规模有必要在{0}和{1}之间.”)]
public int Source{ get; set; }
}


可是,这样仅仅是个花架子,在默许状况下这个Range没有起到任何效果,除了程序员看到代码之后知道了Source有这样的约束要求,那么,咱们需求如何将这个Attribute和验证结合起来呢?天然便是反射。

#p#

咱们在Student中完成如下办法:

public bool Validate(){
bool result = true;
Type type = this.GetType();
PropertyInfo property = type.GetProperty(“Source”); //获取Source特点
RangeAttribute [] attributes =
property.GetCustomAttributes(typeof(Attribute), true)
as RangeAttribute []; //获取Range特点调集
//遍历调集对特点进行验证
foreach(var item in attribute){
int value = (int)property.GetValue(this, null);
if(value item.Max){
result = false;
}
}
return result;
}


那么再回过头看从前的测验,咱们能够发现,测验成功运转了(相关代码见顺便项目的Leven.Validate01和test项目Validate01Test.cs).

咱们在看现在的代码,现在咱们能测验Source,假如咱们的Student类中还有一项Age,规模为6-150呢,那么Student中加上如下代码:

[Range(6, 150, "学生年纪有必要在{0}和{1}之间.")]
public int Age { get; set; }
那么咱们的Validate办法是否能正确验证呢?为了验证成果,咱们从头编写测验:

[TestMethod()]
public void ValidateTest() {
Student student = new Student() {
Source = 80,
Age = 0
};
bool validateResult = student.Validate();
Assert.IsFalse(validateResult);
student.
validateResult = student.Validate();
}


履行测验,很惋惜,测验无法通过了.咱们能够再看看Validate办法,能够发现,其间只对Source特点进行了验证,那么咱们能够想办法修正代码,让其能对Age和Source办法一起验证。

public bool Validate() {
bool result = true;
Type type = this.GetType();
PropertyInfo[] properties = type.GetProperties();
foreach (var property in properties) {
RangeAttribute[] attributes =
property.GetCustomAttributes(typeof(RangeAttribute), true) as RangeAttribute[];
foreach (var item in attributes) {
int value = (int)property.GetValue(this, null);
if (value item.Max) {
result = false;
}
}
}
return result;
}


修正过的办法中将遍历一切的特点,然后进行验证,这时分再次运转测验,生动的绿色代表咱们从头获得了成功。

下面咱们再次考虑新的或许状况,假如Student需求一个Name特点,这是一个有必要字段.咱们考虑新增一个RequiredAttribute来完成该功用,该部分代码如下(拜见项目Leven.Validate03):

[AttributeUsage(AttributeTargets.Property)]
public class RequiredAttribute : Attribute {
public bool IsRequired { get; set; }
public string Message { get; set; }
public RequiredAttribute(string message) {
IsRequired = true;
Message = message;
}
}


然后修正Student部分,新增下面部分:

[Required]
public string Name { get; set; }
再次修正测验代码:

[TestMethod()]
public void ValidateTest() {
Student student = new Student() {
Age = 20,
Source = 89,
Name = string.Empty
};
bool validateResult = student.Validate();
Assert.IsFalse(validateResult);
}


履行测验,成果失利了.检查原因,明显能够看到,是Validate办法中

RangeAttribute[] attributes =property.GetCustomAttributes(typeof(RangeAttribute), true) as RangeAttribute[];

只验证了RangeAttribute,那针对咱们参加的RequiredAttribute天然是力不从心了,为了能验证RequiredAttribute,咱们再次修正了代码:

public bool Validate() {
bool result = true;
bool requiredResult = true;
Type type = this.GetType();
PropertyInfo[] properties = type.GetProperties();
foreach (var property in properties) {
RangeAttribute[] attributes =
property.GetCustomAttributes(typeof(RangeAttribute), true)
as RangeAttribute[]; //获取RangeAttribute调集
RequiredAttribute[] requiredAttributes =
property.GetCustomAttributes(typeof(RequiredAttribute), true)
as RequiredAttribute[]; //获取RequiredAttribute调集
//遍历RangeAttribute进行验证
foreach (var item in attributes) {
int value = (int)property.GetValue(this, null);
if (value item.Max) {
result = false;
}
}
//遍历RequiredAttr进行验证
foreach (var item in requiredAttributes) {
object value = property.GetValue(this, null);
if (value is string) {
if (String.IsNullOrEmpty((value as string))) {
requiredResult = false;
}
} else {
if (value == null) {
requiredResult = false;
}
}
}
}
return result && requiredResult;
}


这次的代码量添加了不少,不过通过咱们的不懈努力,测验再一次通过了,可是,咱们再次回来检查验证部分的代码,不难发现一个问题,每次咱们新增了验证Attribute之后都有必要手动在Validate办法中添加呼应的代码,现在咱们还只有两个Attribute,假如一个体系中有20乃至200个Attribute(当然仅仅打个比如),该办法的长度恐怕将是个恐惧的数字,这样的办法必然无比丑恶。

【修改引荐】

  1. ASP.Net MVC结构装备与剖析
  2. ASP.net顶用axWebBrowser中提交表单
  3. MVC详解 什么是真实的"结构"
转载请说明出处
知优网 » MVC下ASP.NET的表单验证完成(asp.net mvc 表单验证)

发表评论

您需要后才能发表评论