【问题标题】:Pass variable data to ValidationAttribute将变量数据传递给 ValidationAttribute
【发布时间】:2016-12-23 06:45:30
【问题描述】:

我需要在更改密码功能中将不同的最小长度值应用于基于用户角色创建的新密码。如果用户没有管理角色,则最小长度为 12,如果他们有管理员角色,则最小长度为 16。

当前代码没有这样的可变需求逻辑。新密码属性的实现就像在名为 ChangePasswordData 的模型类中:

    ///summary>
    /// Gets and sets the new Password.
    /// </summary>
    [Display(Order = 3, Name = "NewPasswordLabel", ResourceType = typeof(UserResources))]
    [Required]
    [PasswordSpecialChar]
    [PasswordMinLower]
    [PasswordMinUpper]
    [PasswordMaxLength]
    [PasswordMinLength]
    [PasswordMinNumber]
    public string NewPassword { get; set; }

validation 属性设置如下:

/// <summary>
/// Validates Password meets minimum length.
/// </summary>
public class PasswordMinLength : ValidationAttribute
{
    public int MinLength { get; set; }

    public bool IsAdmin { get; set; }

    public PasswordMinLength()
    {
        // Set this here so we override the default from the Framework
        this.ErrorMessage = ValidationErrorResources.ValidationErrorBadPasswordLength;

        //Set the default Min Length
        this.MinLength = 12;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value == null || !(value is string) || !UserRules.PasswordMinLengthRule(value.ToString(), this.MinLength))
        {
            return new ValidationResult(this.ErrorMessageString, new string[] { validationContext.MemberName });
        }

        return ValidationResult.Success;
    }
}

我希望能够根据 IsAdmin 的值将 MinLength 的值设置为 12 或 16,但是我不知道如何装饰属性 [PasswordMinLength(IsAdmin=myvarable)]。只允许使用常量。如何将属性值注入到 ValidationAttribute 中,我可以对其进行评估以确定正确的最小长度?

谢谢!

【问题讨论】:

  • 我认为您想要实现的目标是不可能的,因为属性值中只允许使用静态常量。
  • 我意识到我不能只用变量值装饰属性,但是有没有办法将值注入到验证上下文项集合或其他方法中,以便在 IsValid 中我可以评估一些东西来知道相关用户具有管理员角色?
  • 一种选择是在您的视图模型上使用class level validation。否则,您应该能够创建像 [PasswordMinLength("IsAdmin")] 这样的注释,然后使用类似于以下的技术在验证中访问该属性:odetocode.com/blogs/scott/archive/2011/02/21/…
  • 优秀的参考!我会努力解决这个问题,谢谢!

标签: entity-framework data-annotations validationattribute


【解决方案1】:

感谢 Steve Greene 提供此示例链接 (http://odetocode.com/blogs/scott/archive/2011/02/21/custom-data-annotation-validator-part-i-server-code.aspx),我得到了验证问题的答案。这是更新的代码:

/// <summary>
/// Validates Password meets minimum length.
/// </summary>
public class PasswordMinLength : ValidationAttribute
{
    public int MinLength { get; set; }

    public PasswordMinLength(string IsAdminName)
    {
        // Set this here so we override the default from the Framework
        this.ErrorMessage = ValidationErrorResources.ValidationErrorBadPasswordLength;
        IsAdminPropertyName = IsAdminName;
        //Set the default Min Length
        this.MinLength = 12;
    }

    public string IsAdminPropertyName{ get; set; }

    public override string FormatErrorMessage(string name)
    {
        return string.Format(ErrorMessageString, name, IsAdminPropertyName);
    }

    protected bool? GetIsAdmin(ValidationContext validationContext)
    {
        var retVal = false;
        var propertyInfo = validationContext
                              .ObjectType
                              .GetProperty(IsAdminPropertyName);
        if (propertyInfo != null)
        {
            var adminValue = propertyInfo.GetValue(
                validationContext.ObjectInstance, null);

            return adminValue as bool?;
        }
        return retVal;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (GetIsAdmin(validationContext) != null)
        {
            if (GetIsAdmin(validationContext) == true)
                this.MinLength = 16;
            else
                this.MinLength = 12;
        }
        else
            this.MinLength = 12;

        if (value == null || !(value is string) || !UserRules.PasswordMinLengthRule(value.ToString(), this.MinLength))
        {
            return new ValidationResult(this.ErrorMessageString, new string[] { validationContext.MemberName });
        }

        return ValidationResult.Success;
    }

}

我只是在我的 Model 类中添加了一个 IsAdmin 属性,并像这样装饰了 PasswordMinLength 属性:

[Display(Order = 3, Name = "NewPasswordLabel", ResourceType = typeof(UserResources))]
[Required]
[PasswordSpecialChar]
[PasswordMinLower]
[PasswordMinUpper]
[PasswordMaxLength]
[PasswordMinLength("IsAdmin")]
[PasswordMinNumber]
public string NewPassword { get; set; }

public bool IsAdmin { get; set; }

像魅力一样工作。谢谢史蒂夫!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-24
    • 2017-07-23
    • 2018-04-06
    • 1970-01-01
    • 2023-01-08
    • 2023-02-24
    相关资源
    最近更新 更多