【问题标题】:Using DataAnnotations to compare two model properties使用 DataAnnotations 比较两个模型属性
【发布时间】:2011-06-23 17:03:26
【问题描述】:

我将如何编写一个比较两个字段的自定义 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 的代码?

【问题讨论】:

    标签: c# asp.net-mvc validation data-annotations


    【解决方案1】:

    确保您的项目引用 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; }
    

    【讨论】:

    • 在这种情况下,您可以为第二个属性保存Required 属性,因为您已经强制与第一个属性进行比较,实际上是Required。
    • 请注意,从 C#6.0 开始,现在可以使用 nameof 关键字,而不是使用“魔术字符串”作为属性名称。这可以更好/更轻松地重构任何相关属性,因为它使用的是强类型属性名称(并且您不必记住更新魔术字符串(就像我做过几次一样))。另外,如果您以某种方式错过了一个,编译器会出错 - 从而使其“万无一失”。根据@Janx 的回答使用示例:[CompareAttribute(nameof(NewPassword), ErrorMessage = "Passwords don't match.")]
    【解决方案2】:

    在 ASP.NET MVC 3 框架中有一个 CompareAttribute 可以执行此操作。如果您使用的是 ASP.NET MVC 2 并以 .Net 4.0 为目标,那么您可以查看 ASP.NET MVC 3 源代码中的实现。

    【讨论】:

      【解决方案3】:

      这是达林答案的更长版本:

      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)

      【讨论】:

        【解决方案4】:

        您可以有一个自定义验证属性并将其应用于模型而不是单个属性。这是example,你可以看看。

        【讨论】:

          【解决方案5】:

          对于将来研究这个问题的人,我试图编写一个验证属性,如果对象的属性是某个值,它将评估正则表达式。就我而言,如果地址是送货地址,我不希望启用邮政信箱,所以这是我想出的:

          用法

          [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;
              }
          }
          

          【讨论】:

            【解决方案6】:

            如果你们正在使用 MVC 4,请尝试此代码..它将解决您的错误..

            请创建一个元数据类而不是部分类实现 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; }
            
            
                }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-03-22
              • 1970-01-01
              • 2017-01-24
              • 2015-03-19
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多