自定义validation属性MVC2
我有一个自定义validation属性,它检查两个属性是否具有相同的值(如密码和重新键入密码):
[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(); } }
我有一个视图模型类,其中包含注册表单的所有字段,如下所示:
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 SecurityQuestions { get; set; } [Required] [StringLength(50)] public string Answer { get; set; } }
以下是我的控制器代码:
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 }
当我输入表单值并点击提交代码行,试图获取属性描述符var property = properties.Find(CompareProperty,true); 返回null。 任何人都可以帮助我理解为什么会这样吗?
因为IsValid()
的object value
参数不是整个模型,而只是你的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; } //... }
编辑
该属性实际上不是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 ); } }
另外,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; } // ... }
我不确定为什么你的代码不起作用,但通过GetType()
你可以得到预期的结果:
var property = value.GetType().GetProperty(CompareProperty); var comparePropertyValue = property.GetValue(value, null).ToString();
根据https://msdn.microsoft.com/en-us/library/ybh0y4fd.aspx,TypeDescroptor.GetProperties “返回指定组件的属性集合。” 它还接着说:
组件的属性可能与类的属性不同,因为如果组件位于该组件,则该站点可以添加或删除属性。
所以在我看来,这不是用于获取类属性的正确方法。 我认为@ Pieter的方法更像是你真正想要的。
上述就是C#学习教程:自定义validation属性MVC2分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1014661.html