ASP.NET MVC - 将模型值传递给数据注释参数


我想将一个

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

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

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

但是,可以传递到属性中的是要在运行时评估的模型属性的名称,然后通过访问返回ValidationResult ValidationAttribute 的重写中的ValidationContext,让 IsValid 方法在运行时评估这些值。

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

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

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

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

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

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

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)。

最新更新