MVC 中的验证






4.74/5 (50投票s)
MVC 中的验证
引言
为什么需要验证?
任何网站都会有很多输入字段。用户在这些输入字段中输入数据。现在,这些输入字段暴露给客户端浏览器。用户可以输入任何他们想要的内容。如果用户输入了错误的数据,那么我们的数据库中也会包含不相关或错误的数据。这样,如果不对输入字段进行任何限制,而允许用户输入我们又要插入数据库并用于多种目的的数据,就可能导致系统出现安全漏洞。
这就是验证发挥作用的地方。验证在任何网站的成功中都起着重要作用。
什么是验证?
简单来说,我们可以说验证是开发人员为满足特定输入字段的业务规则而在输入字段上设置的一些规则,以确保系统中拥有正确的数据。
验证有两种类型
- 服务器端验证
- 客户端验证
在执行验证时,我们不仅需要确保验证的正确性,还要确保验证符合业务规则和要求。从安全角度来看,有些黑客可能会绕过客户端验证,向服务器插入一些易受攻击的数据。
背景
不同的平台提供不同的验证方式。ASP.NET 具有验证控件,我们可以借助它们在服务器端进行验证。在客户端,我们可以使用 JavaScript/jQuery 进行验证。如今,有许多插件用于执行客户端验证。MVC 框架通过内置功能支持服务器端和客户端验证。在 MVC 中,验证自 MVC 2 起就不断发展。在 MVC 2 中,支持数据注解,但 MVC 3 对服务器端和客户端验证的数据注解进行了增强,并添加了远程验证和比较属性。
我们将了解 MVC 中的验证。验证可以使用以下方法执行。
- 使用 ModelState 对象
- 使用数据注解
- 使用 Jquery
- 可以使用 MVC 框架的类对输入字段应用自定义验证。
服务器端验证
我创建了一个名为 MVCValidation 的 MVC 项目,采用基本模板。对于这个模板,我创建了一个模型 Register.cs。让我们看一下 Register.cs。
利用这个模型,我将解释基本的服务器端验证。框架使用 ModelState 对象验证模型的所有字段。在代码中,我们需要检查 ModelState 对象的 IsValid 属性。如果任何输入字段存在验证错误,则 IsValid 属性将设置为 false。如果所有字段都满足要求,则 IsValid 属性将设置为 true。根据该属性的值,我们需要编写代码。MVC 框架为验证提供了数据注解功能。数据注解会自动执行上述所有验证,我们只需要检查 IsValid 属性。
我将首先解释在不使用数据注解属性而使用 ModelState 对象的情况下进行服务器端验证。
使用 ModelState 对象
我创建了一个强类型模型为 Register.cs 的视图 Register.cshtml。
该应用程序的 Register 视图将如下所示:
现在,我将创建一个 HTTPPOST 方法,该方法将在我单击 Register 视图上的“提交”按钮时被调用。
在此 Register 视图中,我们将检查模型中的输入属性(即 UserName、Password 和 ConfirmPassword)是否为 Null/Empty。如果这些字段为 Null/Empty,我们将根据相应的属性向 ModelState 对象添加错误。
请查看下面的代码图片。
如果我运行应用程序并尝试提交所有字段为空的注册表单,那么在控制器方法中,Register 模型的所有属性都将获得 null 值。
执行结束时,ModelState 对象将包含为失败验证添加的所有错误。同时,modelState 对象将包含错误消息。
由于我们正在检查 IsValid 属性的值,并且它被设置为 false,因此我们将用户重定向回注册视图以填写字段。
视图将如下所示,并带有错误消息。
这就是在不使用数据注解属性的情况下进行的服务器端验证。我们将看到数据注解如何使开发者的工作变得非常轻松。
数据注解属性
以下是一些数据注解属性及其用法。请注意,参考来自 MSDN。
属性名称 | 用途 |
DataType |
此属性指定属性的类型,例如 emailId 或 phoneNumber。 Ex [DataType(DataType.EmailAddress)] public string Email { get; set; }
|
Range |
指定属性的最大值和最小值。 Ex [Range(1,100)] public int Age { get; set; }
|
RegularExpression |
指定属性的有效值。 Ex [RegularExpression(@"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage="Please enter valid email id.")] public string EmailId { get; set; }
|
必需 |
指定必须提供属性的值。 Ex [Required(ErrorMessage="Please enter First Name")] public string FirstName { get; set; }
|
StringLength |
指定该属性允许的最大字符数。NULL 值不会触发 StringLength 验证。 Ex [StringLength(50)] public string FirstName { get; set; }
|
显示 |
此属性用于增强需要应用该属性的当前属性。 Ex [Display(Name = "First Name", Description="First Name of the person")] public string FirstName { get; set; }
|
DisplayFormat |
此属性用于指定字段应如何显示和格式化。 Ex [DisplayFormat(DataFormatString = "{0:C}")] public Decimal ListPrice { get; set; }
|
使用代码
在我们的代码中,我们将增加模型和视图中的一些属性,以解释这些属性的用法。
请查看下面的模型、视图以及验证后的结果。
模型
视图
验证结果
自定义服务器端验证
有时我们需要通过创建自定义属性来创建自定义验证。例如,我们想为员工的薪资设置一个下限。我将创建一个自定义验证属性。为了创建自定义验证属性,我们需要创建一个派生自 ValidationAttribute 类的类。ValidationAttribute 类中有一个执行验证部分的功能。在属性类中,我们必须重写 IsValid 函数,所有的自定义验证逻辑都应该放在这个 IsValid 函数中。让我们将该属性命名为 SalaryAttribute。
如果我填写了所有字段,输入薪资为 10000 并单击提交按钮,则 Salary 属性将验证薪资字段并返回服务器端错误。
如果输入的薪资值为 60000 并单击提交按钮,则表单将成功提交。所有验证都已通过,用户将被重定向到索引视图。
通过这种方式,我们实现了自定义服务器端验证。
远程验证
远程验证是 MVC 提供的一个重要且有用的功能。此功能允许用户从客户端调用控制器中的任何操作方法。例如,假设我们需要检查用户输入的电子邮件 ID 是否已存在于数据库中,并且当用户在 Email 字段中键入其电子邮件 ID 并单击 Email ID 文本字段外部时。如果此时使用远程验证器,则可以触发对操作方法的调用,并立即检查电子邮件 ID 是否已存在。我们不必等待单击提交按钮。
因此,远程验证的工作方式类似于 AJAX 调用。为了在电子邮件字段失去焦点时触发调用,我们需要在 cshtml 文件中包含以下文件。
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script> <script src="~/Scripts/jquery.validate.min.js"></script>
Remote Validation 属性将添加到 email 属性。
该操作方法将检查输入的电子邮件 ID 是否等于“mrpachbhai@gmail.com”。如果相等,则将错误消息立即返回给 UI。
UI 将在失去焦点时立即显示错误消息。
通过这种方式,我们完成了远程验证。
客户端验证
从性能角度来看,客户端验证非常有用。每当用户输入任何错误数据时,我们都需要转到服务器端进行验证。因此,如果我们进行客户端验证,就可以减少客户端到服务器的调用。最终,我们的性能将会提高。
此外,通过客户端验证,我们还使用户能够在将数据发送到服务器之前进行纠正。但是,如果存在客户端验证,那么还需要服务器端验证吗?有些浏览器或客户端不支持客户端脚本,此时我们需要服务器端验证来验证我们的数据,然后再将其存储在数据库中。MVC 提供了非侵入性客户端验证功能。
如何在 MVC 中启用客户端验证?
要在 MVC 中启用客户端验证,您需要按照以下步骤操作。
您需要将以下文件包含在视图中。
如果您想使用打包,则需要将 js 文件添加到包中。
验证是通过 jQuery Validation 库执行的。通常,在基于 Web 窗体的应用程序中,我们使用 JavaScript 来执行客户端验证。在 MVC 中,客户端验证不会在代码中引入任何 JavaScript 来执行验证。请参阅启用客户端验证后的 HTML 结构。
HTML:启用客户端验证之前
HTML:启用客户端验证之后
现在,对于模型中添加了验证属性的每个输入字段,框架都会创建上述结构。data-val 属性设置为 true,并根据模型中添加的属性添加 data-val-{Name} 属性。在此示例中,我们添加了 Required 属性,因此名称变为 data-val-required。错误消息被分配给 data-val-attribute。
请注意,需要在 html form 标签内放置需要在客户端进行验证的输入字段,以便通过验证 js 进行验证。
自定义客户端验证
在我们的模型“Register.cs”中,我们为 Salary 字段创建了服务器端自定义验证。此验证仅在服务器端触发。现在,我们将创建一个自定义客户端验证,该验证将在用户输入 Salary 字段中的任何值时立即触发,并且用户将立即收到错误消息。
为此,我创建了一个名为“CustomValidation.js”的 JavaScript 文件。该文件将包含一个验证规则——“checkSalary”。这个新添加的规则应用于表单的 Salary 字段。这在 .Validate 方法中有所说明,并且还设置了函数中的错误消息。请参阅下面的图片,其中将描述 js 代码的所有部分。
现在我们需要将脚本包含在我们的 cshtml 中。一旦我们执行应用程序并在输入薪资为 10000 后,请查看执行情况。如果验证失败,我们返回 false;如果验证成功,我们返回 true。
在这种情况下,Salary 字段的客户端验证失败,并且以下错误消息会立即显示给用户。
通过这种方式,我们在 MVC 中看到了服务器端验证和客户端验证。欢迎提出评论和建议。
参考文献
MSDN
关注点
欢迎提出评论和建议。