ASP.NET MVC 自定义验证器教程

在本文中,将探讨如何在ASP.NET MVC中创建自定义验证器,并在服务器端检查表单中特定字段的值。这些验证是在服务器端进行的,因此无论客户端验证如何,应用程序都应进行服务器端验证。规则是除非经过验证,否则所有用户输入都是不可信的。因此,应在客户端、应用程序服务器级别以及数据库服务器(SQL Server / Oracle存储过程)进行验证。

应该对MVC应用程序的工作原理有基本的了解,尽管包含了如何创建第一个MVC应用程序的步骤,但本文是为那些了解MVC的用户准备的。这段代码是在VS 2010 .NET框架4.0中编写并测试的,但逻辑应该在更高版本中保持大致相同。

使用代码

首先,从创建MVC应用程序开始。

  1. 打开Visual Studio。转到文件 -> 新建项目 -> 其他语言 -> Web -> C# 选择ASP.NET MVC4应用程序。
  2. 点击确定后,将得到另一个窗口。选择基本并点击确定。
  3. 现在MVC应用程序已创建。现在将创建模型类。这个类将类似于希望从用户那里获得的HTML表单。右键单击模型文件夹,然后转到添加 -> 类。创建一个名为Employee.cs的新类。

Employee类的架构应该如下所示:

public class Employee { public int EmployeeId { get; set; } public string EmployeeName { get; set; } public string Department { get; set; } public int PhoneNumber { get; set; } public string DateOfBirth { get; set; } public string JoiningDate { get; set; } }

将从用户那里获取上述类的所有属性的输入。将在本教程的后面部分讨论这个问题。在此阶段编译项目,否则第3步将无法工作。

现在将添加视图并将其映射到这个Employee类。右键单击视图文件夹,然后转到添加 -> 新文件夹。在视图文件夹下创建一个名为Home的文件夹。现在右键单击Home文件夹,然后转到添加 -> 视图。将视图命名为index并按照下面截图中的设置进行设置。记得点击“创建一个强类型的视图”,并从下拉菜单中选择Employee类。如果在下拉菜单中看不到任何东西,请构建项目。

现在打开视图并进行如下更改:

@model MvcApplicationDataValidation.Models.Employee @{ ViewBag.Title = "index"; Layout = "~/Views/Shared/_Layout.cshtml"; } @using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" })) { @Html.ValidationSummary(true) <table> <tr><td>Employee Id</td> <td>@Html.TextBoxFor(m => m.EmployeeId)</td> <td>@Html.ValidationMessageFor(m => m.EmployeeId)</td> </tr> <tr><td>Employee Name</td> <td>@Html.TextBoxFor(m => m.EmployeeName)</td> <td>@Html.ValidationMessageFor(m => m.EmployeeName)</td> </tr> <tr><td>Department</td> <td>@Html.TextBoxFor(m => m.Department)</td> <td>@Html.ValidationMessageFor(m => m.Department)</td> </tr> <tr><td>Phone Number</td> <td>@Html.TextBoxFor(m => m.PhoneNumber)</td> <td>@Html.ValidationMessageFor(m => m.PhoneNumber)</td> </tr> <tr><td>Date Of Birth (dd/mm/yyyy)</td> <td>@Html.TextBoxFor(m => m.DateOfBirth)</td> <td>@Html.ValidationMessageFor(m => m.DateOfBirth)</td> </tr> <tr><td>Joining Date (dd/mm/yyyy)</td> <td>@Html.TextBoxFor(m => m.JoiningDate)</td> <td>@Html.ValidationMessageFor(m => m.JoiningDate)</td> </tr> <tr><td></td> <td><input type="submit" value="Submit"/></td> </tr> </table> }

这个视图的HTML如下所示:

注意,视图中的所有字段都映射到了模型的属性。

现在MVC应用程序的基本结构已经完成。将为这个表单的输入字段添加验证。

在MVC中有一个内置功能,对这些字段有一些预定义的验证。

验证是作为模型类(Employee)属性上的属性添加的,代码如下所示:

[Required] [StringLength(50, MinimumLength = 3)] public string Department { get; set; }

这里,Required属性将使这个字段成为必填项,StringLength属性将使Department的值最大值为50,最小长度为3。如果点击提交按钮,如果让Department文本框为空,或者最小长度小于3,或者最大值大于50,应该看到错误消息。

到目前为止,已经实现了内置的MVC验证属性。现在将创建自己的自定义验证。

将验证“出生日期”和“加入日期”的日期格式。期望的格式是dd/mm/yyyy。还将验证加入日期应该大于出生日期,还将验证出生日期应该小于当前日期。在这里将了解如何编写自定义验证器。一旦理解了编写自定义验证器,可以通过编写自定义验证在MVC中执行任何类型的验证。

5.在项目中添加一个名为Validators的新文件夹。将在这个文件夹中保存自定义验证类。

6.在这个文件夹中添加一个新类,并将其命名为DateValidatorAttribute,并添加以下代码:

public class DateValidatorAttribute : ValidationAttribute { protected override ValidationResult IsValid(object value, ValidationContext validationContext) { try { string strValue = value.ToString(); var dateTime = DateTime.Parse(strValue); string pattern = @"(^(((0[1-9]|1[0-9]|2[0-8])[\/](0[1-9]|1[012]))|((29|30|31)[\/](0[13578]|1[02]))|((29|30)[\/](0[4,6,9]|11)))[\/](19|[2-9][0-9])\d\d$)|(^29[\/]02[\/](19|[2-9][0-9])(00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96)$)"; Match match = Regex.Match(strValue, pattern); if (match.Success) { var property = validationContext.ObjectType.GetProperty("JoiningDate"); if (property == null) return new ValidationResult(string.Format("Property '{0}' is Null", "JoiningDate")); var objJoiningDate = property.GetValue(validationContext.ObjectInstance, null); string strJoiningDate = objJoiningDate == null ? "" : objJoiningDate.ToString(); Match matchJoiningDate = Regex.Match(strJoiningDate, pattern); if (matchJoiningDate.Success) { var joiningDate = DateTime.Parse(strJoiningDate); if (dateTime > joiningDate) return new ValidationResult("Date of Birth can not be greater than Joining date"); if (dateTime > DateTime.Now) return new ValidationResult("Date of Birth can not be greater todays date"); } else return new ValidationResult("Invalid date format"); } else return new ValidationResult("Invalid date format"); return ValidationResult.Success; } catch (Exception) { return new ValidationResult("Invalid date format"); } } }

应该继承.NET ValidationAttribute类,以便可以编写自己的验证逻辑。现在将重写ValidationAttribute类的IsValid方法。

object value包含HTML字段的文本。这个HTML字段的值已经映射到了Employee类的属性。

首先将值转换为字符串并解析为DateTime.parse函数,以检查值是否有效,无论格式如何。现在使用了正则表达式来验证字符串是否在格式dd/mm/yyyy中。可以修改正则表达式以包含其他格式。

到目前为止,已经验证了日期是有效的并且格式正确。接下来将验证这个值不大于加入日期,也不大于当前日期。

var property = validationContext.ObjectType.GetProperty("JoiningDate");

上述代码获取了Employee类中JoiningDate属性的属性。现在将获取这个属性的值(这是用户在视图中的加入日期文本框中输入的)。

var objJoiningDate = property.GetValue(validationContext.ObjectInstance, null);

现在有了值的对象,将把它转换为字符串并再次进行正则表达式匹配以匹配模式。将检查加入日期是否也在正确的格式dd/mm/yyyy中。一旦所有验证通过,将把它们转换为DateTime格式并进行验证。

var joiningDate = DateTime.Parse(strJoiningDate); if (dateTime > joiningDate) return new ValidationResult("Date of Birth can not be greater than Joining date"); if (dateTime > DateTime.Now) return new ValidationResult("Date of Birth can not be greater todays date");
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485