我如何编写一个比较两个字段的自定义ValidationAttribute?这是常见的“输入密码”,“确认密码”方案。我需要确保两个字段相同并保持一致,我想通过DataAnnotations实现验证。
所以在伪代码中,我正在寻找一种方法来实现以下内容:
public class SignUpModel
{
[Required]
[Display(Name = "Password")]
public string Password { get; set; }
[Required]
[Display(Name = "Re-type Password")]
[Compare(CompareField = Password, ErrorMessage = "Passwords do not match")]
public string PasswordConfirm { get; set; }
}
public class CompareAttribute : ValidationAttribute
{
public CompareAttribute(object propertyToCompare)
{
// ??
}
public override bool IsValid(object value)
{
// ??
}
}
所以问题是,我如何编码[Compare] ValidationAttribute?
答案 0 :(得分:57)
确保您的项目引用system.web.mvc v3.xxxxx。
然后你的代码应该是这样的:
using System.Web.Mvc;
。 。 。
[Required(ErrorMessage = "This field is required.")]
public string NewPassword { get; set; }
[Required(ErrorMessage = "This field is required.")]
[Compare(nameof(NewPassword), ErrorMessage = "Passwords don't match.")]
public string RepeatPassword { get; set; }
答案 1 :(得分:29)
ASP.NET MVC 3 Framework中有一个CompareAttribute可以执行此操作。如果您正在使用ASP.NET MVC 2并以.Net 4.0为目标,那么您可以查看ASP.NET MVC 3源代码中的实现。
答案 2 :(得分:7)
这是Darin答案的较长版本:
public class CustomAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
if (value.GetType() == typeof(Foo))
{
Foo bar = (Foo)value;
//compare the properties and return the result
}
throw new InvalidOperationException("This attribute is only valid for Foo objects");
}
}
和用法:
[MetadataType(typeof(FooMD))]
public partial class Foo
{
... functions ...
}
[Custom]
public class FooMD
{
... other data annotations ...
}
错误将显示在@Html.ValidationSummary(false)
答案 3 :(得分:3)
您可以拥有自定义验证属性并将其应用于模型而不是单个属性。这是example你可以看一下。
答案 4 :(得分:2)
如果你们使用MVC 4,请尝试使用此代码..它将解决您的错误..
请制作一个Metadataclass,而不是部分类impliment comfirmemail属性。请查看以下代码以获取更多详细信息。
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using StringlenghtMVC.Comman;
using System.Web.Mvc;
using System.Collections;
[MetadataType(typeof(EmployeeMetaData))] //here we call metadeta class
public partial class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public Nullable<int> Age { get; set; }
public string Gender { get; set; }
public Nullable<System.DateTime> HireDate { get; set; }
//[CompareAttribute("Email")]
public string ConfirmEmail { get; set; }
}
public class EmployeeMetaData
{
[StringLength(10, MinimumLength = 5)]
[Required]
//[RegularExpression(@"(([A-za-Z]+[\s]{1}[A-za-z]+))$", ErrorMessage = "Please enter Valid Name")]
public string Name { get; set; }
[Range(1, 100)]
public int Age { get; set; }
[CurrentDate]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
public DateTime HireDate { get; set; }
//[RegularExpression(@"^[\w-\._\%]+@(?:[\w]{2,6}$")]
public string Email { get; set; }
[System.Web.Mvc.CompareAttribute("Email")]
public string ConfirmEmail { get; set; }
}
答案 5 :(得分:1)
对于未来的人们来看这个问题,我试图编写一个验证属性,如果对象的属性是某个值,它将评估正则表达式。在我的情况下,如果地址是送货地址,我不希望启用邮政信箱,所以这就是我提出的:
用法
[Required]
public EAddressType addressType { get; set; } //Evaluate Validation attribute against this
[EvaluateRegexIfPropEqualsValue(Constants.NOT_PO_BOX_REGEX, "addressType", EAddressType.Shipping, ErrorMessage = "Unable to ship to PO Boxes or APO addresses")]
public String addressLine1 { get; set; }
这是验证属性的代码:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public class EvaluateRegexIfPropEqualsValue : ValidationAttribute
{
Regex _regex;
string _prop;
object _targetValue;
public EvaluateRegexIfPropEqualsValue(string regex, string prop, object value)
{
this._regex = new Regex(regex);
this._prop = prop;
this._targetValue = value;
}
bool PropertyContainsValue(Object obj)
{
var propertyInfo = obj.GetType().GetProperty(this._prop);
return (propertyInfo != null && this._targetValue.Equals(propertyInfo.GetValue(obj, null)));
}
protected override ValidationResult IsValid(object value, ValidationContext obj)
{
if (this.PropertyContainsValue(obj.ObjectInstance) && value != null && !this._regex.IsMatch(value.ToString()))
{
return new ValidationResult(this.ErrorMessage);
}
return ValidationResult.Success;
}
}