使用 ASP.NET MVC 进行模型级别验证






4.13/5 (6投票s)
将验证放在模型层的好处是,验证规则将在应用程序中访问数据库的任何地方执行。这也意味着我们可以在一个地方更改验证规则,并且我们应用程序中的每个 UI 元素都会自动更新。
引言
在构建您的 MVC 应用程序时,您希望使用您的应用程序控制器来处理输入和应用程序用户界面(视图)。您不希望将业务逻辑嵌入到您的控制器中。最好的做法是创建一个服务层,它基本上是控制器和数据层之间的层。当涉及到验证时,例如,我想确保单价大于零,或者说产品名称永远不能为空,我不希望在我的控制器或视图中编写代码。为此,我想把我的逻辑放在我的业务层中,也就是模型层。将此验证放在模型层的好处是,验证规则将在应用程序中访问数据库的任何地方执行。这也意味着我们可以在一个地方更改验证规则,并且我们应用程序中的每个 UI 元素都会自动更新到数据管理器。对于添加、编辑、删除场景,如果我们能够在模型层中添加验证,所有这些不同的操作规则都会在更新数据库之前强制执行验证规则。
在 ASP.NET MVC 中,有多种方法可以进行模型级别验证。您可以在业务层中编写自己的验证逻辑。在 ASP.NET MVC 1 版本中,我们支持 IDataErrorInfo
,这是 WPF 和 Windows Forms 支持的标准接口。在 ASP.NET MVC 2 中,我们有另一种内置机制,它使用数据注释功能,动态数据用于 ASP.NET Web 窗体。Silverlight 也在 RIA 服务中使用此功能。
IDataErrorInfo 示例
以下代码使用 IDataErrorInfo
接口生成验证错误消息。创建一个部分 Question
类,它扩展了 Entity Framework 生成的部分 Question
类的功能。接下来,我们将验证逻辑添加到 Question
类的 OnTitleChanging()
部分方法中。最后,实现 IDataErrorInfo
接口,以便将这些验证消息公开给 ASP.NET MVC 框架。
using System.Collections.Generic;
using System.ComponentModel;
namespace MvcApplication1.Models
{
public partial class Question : IDataErrorInfo
{
private Dictionary<string,> _errors =
new Dictionary<string,>();
partial void OnTitleChanging(string value)
{
if (value.Trim().Length > 20)
_errors.Add("Title",
"Title should not be more than 20 characters.");
}
#region IDataErrorInfo Members
public string Error
{
get
{
return string.Empty;
}
}
public string this[string columnName]
{
get
{
if (_errors.ContainsKey(columnName))
return _errors[columnName];
return string.Empty;
}
}
#endregion
}
}
ASP.NET MVC 框架通过使用模型绑定器(DefaultModelBinder
)创建传递给 Create()
操作的 Question
实例。模型绑定器负责通过将 HTML 表单字段绑定到 Movie
对象的实例来创建 Question
对象的实例。 DefaultModelBinder
检测一个类是否实现了 IDataErrorInfo
接口。如果一个类实现了这个接口,那么模型绑定器会为该类的每个属性调用 IDataErrorInfo.this
索引器。如果索引器返回错误消息,则模型绑定器会自动将此错误消息添加到模型状态中。
数据注释验证器
使用数据注释验证器的优点是,它们允许您通过向类属性添加一个或多个属性(例如 Required
或 StringLength
属性)来简单地执行验证。
C# 和 VB.NET 不支持部分属性。有一个称为伙伴类的概念,我们可以在其中添加我们的验证规则并将它们链接到实际的模型。以下示例显示了一个实现
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace MvcApplication1.Models
{
[MetadataType(typeof(Question_Validate))]
public partial class Question
{
}
public class Question_Validate
{
[StringLength(20, "Title should not be more than 20 characters.")]
public object Title { get; set; }
}
}
请注意,Question
部分类使用 MetadataType
属性进行装饰,该属性指向 Question_Validate
类。 Question_Validate
类包含 Question
类属性的代理属性。
客户端验证
默认情况下,上述示例将在服务器上运行,但要使其与客户端验证一起工作,我们只需要两个步骤。第一步是引用适当的脚本。
<script src="../../Scripts/jquery-1.3.2.min.js" type="text/javascript"/>
<script src="../../Scripts/jquery.validate.min.js" type="text/javascript"/>
<script src="../../Scripts/MicrosoftAjax.js" type="text/javascript"/>
<script src="../../Scripts/MicrosoftMvcValidation.js" type="text/javascript"/>
下一步是通过在调用 BeginForm
之前调用 EnableClientValidation
来启用表单的客户端验证。
<%Html.EnableClientValidation(); %>
摘要
我们已经看到了如何实现 IDataErrorInfo
接口,以及如何利用数据注释模型绑定器在 ASP.NET MVC 应用程序中执行验证。