Kum*_*mar 8 c# asp.net data-annotations asp.net-mvc-2
我有一个自定义验证属性,它检查两个属性是否具有相同的值(如密码和重新键入密码):
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public class EqualToPropertyAttribute : ValidationAttribute
{
public string CompareProperty { get; set; }
public EqualToPropertyAttribute(string compareProperty)
{
CompareProperty = compareProperty;
ErrorMessage = string.Format(Messages.EqualToError, compareProperty);
}
public override bool IsValid(object value)
{
if (value == null)
{
return true;
}
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
var property = properties.Find(CompareProperty, true);
var comparePropertyValue = property.GetValue(value).ToString();
return comparePropertyValue == value.ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个视图模型类,其中包含注册表单的所有字段,如下所示:
public class SignUpViewModel
{
[Required]
[StringLength(100)]
public string Username { get; set; }
[Required]
[Password]
public string Password { get; set; }
[Required]
[DisplayText("RetypePassword")]
[EqualToProperty("Password")]
public string RetypePassword { get; set; }
[Required]
[StringLength(50)]
[DisplayText("FirstName")]
public string FirstName { get; set; }
[Required]
[StringLength(100)]
[DisplayText("LastName")]
public string LastName { get; set; }
[Required]
[DisplayText("SecurityQuestion")]
public int SecurityQuestionID { get; set; }
public IEnumerable<SelectListItem> SecurityQuestions { get; set; }
[Required]
[StringLength(50)]
public string Answer { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
以下是我的控制器代码:
public virtual ActionResult Index()
{
var signUpViewModel = new SignUpViewModel();
signUpViewModel.SecurityQuestions = new SelectList(questionRepository.GetAll(),"SecurityQuestionID", "Question");
return View(signUpViewModel);
}
[HttpPost]
public virtual ActionResult Index(SignUpViewModel viewModel)
{
// Code to save values to database
}
Run Code Online (Sandbox Code Playgroud)
当我输入表单值并点击提交代码行时,尝试获取属性描述符var property = properties.Find(CompareProperty,true); 返回null.任何人都可以帮助我理解为什么会这样吗?
Ber*_*ron 13
因为object value参数IsValid()不是整个模型,而只是你的string RetypePassword.
它需要是一个影响整个模型对象的属性,而不仅仅是属性.
虽然我建议你使用PropertiesMustMatchAttribute.
[PropertiesMustMatch("Password", "RetypePassword",
ErrorMessage = "The password and confirmation password do not match.")]
public class SignUpViewModel
{
[Required]
[StringLength(100)]
public string Username { get; set; }
[Required]
[Password]
public string Password { get; set; }
[Required]
[DisplayText("RetypePassword")]
public string RetypePassword { get; set; }
//...
}
Run Code Online (Sandbox Code Playgroud)
该属性实际上不是ASP.NET MVC2框架的一部分,而是在默认的MVC 2项目模板中定义.
[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 );
}
}
Run Code Online (Sandbox Code Playgroud)
在旁注中,MVC 3有一个CompareAttribute完全符合您的要求.
public class SignUpViewModel
{
[Required]
[StringLength(100)]
public string Username { get; set; }
[Required]
[Password]
public string Password { get; set; }
[Required]
[DisplayText("RetypePassword")]
[Compare("Password")] // the RetypePassword property must match the Password field in order to be valid.
public string RetypePassword { get; set; }
// ...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7822 次 |
| 最近记录: |