【问题标题】:ASP.NET MVC - Pass model value to data annotation parameterASP.NET MVC - 将模型值传递给数据注释参数
【发布时间】:2014-02-10 15:01:38
【问题描述】:

我想将我模型中的一个属性中的一个值传递给我的数据注释以验证我的密码属性,但我不知道如何实现这一点。当我以这种方式执行此操作时,我收到以下错误:

an attribute argument must be a constant expression typeof expression or array

我的模特:

public class LoginModel
{
    public string Voornaam { get; set; }
    public string Achternaam { get; set; }
    public string Gebruikersnaam { get; set; }

    [Password(AttributeVoornaam = this.Voornaam, AttributeAchternaam = this.Achternaam, AttributeGebruikersnaam = this.Gebruikersnaam)]
    public string Wachtwoord { get; set; }
}

在我的数据注释中,我正在这样做:

public class PasswordAttribute : ValidationAttribute
{
    public string AttributeVoornaam { get; set; }
    public string AttributeAchternaam { get; set; }
    public string AttributeGebruikersnaam { get; set; }

    public override bool IsValid(object value)
    {
        string strValue = value.ToString();

        if (strValue.Contains(AttributeVoornaam.ToLower()) || strValue.Contains(AttributeAchternaam.ToLower()) ||
               strValue.Contains(AttributeGebruikersnaam.ToLower()))
        {
            ErrorMessage = "Uw wachtwoord mag niet uw voornaam, achternaam of gebruikersnaam bevatten.";
            return false;
        }
        else
        {
            return true;
        }
    }
}

【问题讨论】:

    标签: asp.net-mvc model data-annotations


    【解决方案1】:

    您不能将变量值(在编译时未计算的值)传递给属性。它们必须是文字值或常量值。

    可以传递给属性的是您想要在运行时评估的模型属性的名称,然后让您的IsValid 方法评估这些值通过访问返回 ValidationResultValidationResult 的覆盖中的 ValidationContext 来运行时。

    或者,如果您总是在评估这些相同的属性,那么您可以获取对模型的引用,然后直接使用它:

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        LoginModel loginModel = (LoginModel)validationContext.ObjectInstance;
    
        string strValue = value.ToString();
    
        if (strValue.Contains(loginModel.Voornaam.ToLower()) || 
            strValue.Contains(loginModel.Achternaam.ToLower()) ||             
            strValue.Contains(loginModel.Gebruikersnaam.ToLower()))
        {
            ErrorMessage = "Uw wachtwoord mag niet uw voornaam, achternaam of gebruikersnaam bevatten.";
            return false;
        }
        else
        {
            return true;
        }
    }
    

    【讨论】:

    • 这对我来说非常适合一些小的调整,谢谢!
    • 为什么返回布尔值而不是ValidationResults?
    【解决方案2】:

    这是不可能的,因为属性(包括它们的数据)在编译时被放入程序集的元数据中。请参阅 MSDN 上的 Attribute parameter types

    相反,您可以将依赖属性的名称作为字符串传递。我将向您展示一个具有一个属性的示例,您将以相同的方式添加其他属性:

    public class PasswordAttribute : ValidationAttribute
    {
        public PasswordAttribute(string voornaamPropertyName)
        {
            if(string.IsNullOrEmpty(voornaamPropertyName))
                throw new ArgumentNullException("voornaamPropertyName");
    
            VoornaamPropertyName = voornaamPropertyName;
        }
    
        public string VoornaamPropertyName { get; set; }
    
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            PropertyInfo voornaamPropertyInfo = validationContext.ObjectType.GetProperty(VoornaamPropertyName);
            if (voornaamPropertyInfo == null)
            {
                return new ValidationResult(String.Format(CultureInfo.CurrentCulture, "Could not find a property named {0}", VoornaamPropertyName));
            }
    
            var voornaamProperty = voornaamPropertyInfo.GetValue(validationContext.ObjectInstance); // here you have the value of the property
    
           ...
        }
    }
    

    然后

    [Password("Voornaam")]
    public string Wachtwoord { get; set; }
    

    【讨论】:

      【解决方案3】:

      据我所知,您不能将变量值传递给属性。您可以向模型添加自定义验证规则:

      public class LoginModel: IValidatableObject
      {
          public string Voornaam {get;set;}
          public string Achternaam {get;set;}
          public string Gebruikersnaam {get;set;}
      
          public string Wachtwoord { get; set; }
      
          public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
          {
              var results = new List<ValidationResult>();
              var pwd = this.Wachtwoord.ToLower();
              if(pwd.Contains(this.Voornaam.ToLower()) || pwd.Contains(this.Achternaam.ToLower()) || pwd.Contains(this.Gebruikersnaam.ToLower())){
                  results.Add(new ValidationResult("Uw wachtwoord mag niet uw voornaam, achternaam of gebruikersnaam bevatten."));
              }
              return results;
          }
      }
      

      您还可以将其更改为多个 if 语句并添加单独的 ValidationResults(一个用于 Voornaam,一个用于 Achternaam,一个用于 Gebruikersnaam)。

      【讨论】:

        猜你喜欢
        • 2023-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-18
        • 1970-01-01
        • 1970-01-01
        • 2020-01-09
        相关资源
        最近更新 更多