从现在开始,我使用了优秀的
FluentValidation
库来验证我的模型类。在Web应用程序中,我将其与 jquery.validate插件结合使用,以执行客户端验证。
一个缺点是大多数验证逻辑在客户端上重复,并且不再集中在单个位置。
库来验证我的模型类。在Web应用程序中,我将其与 jquery.validate插件结合使用,以执行客户端验证。
一个缺点是大多数验证逻辑在客户端上重复,并且不再集中在单个位置。
为此,我正在寻找一种替代方案。有many示例there显示了使用数据注释来执行模型验证。它看起来很有前途。
有一件事我不能找到是如何验证一个依赖于另一个属性值的属性。
让我们举个例子下面的模型:
public class Event { [required] public DateTime? StartDate { get; set; } [required] public DateTime? EndDate { get; set; } }
我想确保EndDate大于StartDate。我可以写一个自定义
验证属性扩展ValidationAttribute以便执行自定义验证逻辑。不幸的是,我找不到一种方法来获得
模型实例:
public class CustomValidationAttribute : ValidationAttribute { public override bool IsValid(object value) { // value represents the property value on which this attribute is applied // but how to obtain the object instance to which this property belongs? return true; } }
我发现CustomValidationAttribute似乎做这项工作,因为它有这个ValidationContext属性包含要验证的对象实例。不幸的是,这个属性只能在.NET 4.0中添加。所以我的问题是:我可以实现相同的功能在.NET 3.5 SP1?
更新:
看来FluentValidation already supports客户端验证和元数据在ASP.NET MVC 2。
不过,最好知道,如果数据注释可以用于验证依赖属性。
MVC2提供了一个示例“PropertiesMustMatchAttribute”,显示如何获取DataAnnotations为您工作,它应该在.NET 3.5和.NET 4.0中工作。示例代码如下所示:
[AttributeUsage(AttributeTargets.Class,AllowMultiple = true,Inherited = true)] public sealed class PropertiesMustMatchAttribute : ValidationAttribute { private const string _defaultErrorMessage = "'{0}' and '{1}' do not match."; private readonly object _typeId = new object(); public PropertiesMustMatchAttribute(string originalProperty,string confirmProperty) : base(_defaultErrorMessage) { OriginalProperty = originalProperty; ConfirmProperty = confirmProperty; } public string ConfirmProperty { get; private set; } public string OriginalProperty { get; private set; } public override object TypeId { get { return _typeId; } } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentUICulture,ErrorMessageString,OriginalProperty,ConfirmProperty); } public override bool IsValid(object value) { PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value); object originalValue = properties.Find(OriginalProperty,true /* ignoreCase */).GetValue(value); object confirmValue = properties.Find(ConfirmProperty,true /* ignoreCase */).GetValue(value); return Object.Equals(originalValue,confirmValue); } }
当你使用该属性,而不是把它放在你的模型类的属性,你把它放在类本身:
[PropertiesMustMatch("NewPassword","ConfirmPassword",ErrorMessage = "The new password and confirmation password do not match.")] public class ChangePasswordModel { public string NewPassword { get; set; } public string ConfirmPassword { get; set; } }
当“IsValid”在您的自定义属性被调用时,整个模型实例被传递给它,所以你可以得到依赖的属性值。您可以轻松地按照此模式创建日期比较属性,甚至更一般的比较属性。
Brad Wilson has a good example on his blog,显示如何添加验证的客户端部分,尽管我不知道该示例是否将在.NET 3.5和.NET 4.0中工作。