问题
I have a requirement to apply different min length values in a change password function to a new password being created based on a user's roles. If a user has no administrative roles min length is 12, if they have admin roles min length is 16.
The current code has no such variable requirement logic. The implementation for the new password property was like so in model class called 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; }
The validation attribute is set like so:
/// <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;
}
}
I want to be able to set the value of MinLength to 12 or 16 based on the value of IsAdmin however i cannot figure out how to decorate the attribute [PasswordMinLength(IsAdmin=myvarable)]. Only constants are allowed. How can I inject a property value into the ValidationAttribute that I can evaluate to determine the correct minimum length?
Thanks!
回答1:
Thanks to Steve Greene for providing this link to an example (http://odetocode.com/blogs/scott/archive/2011/02/21/custom-data-annotation-validator-part-i-server-code.aspx), I have the answer to my validation question. Here is the updated code:
/// <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;
}
}
I simply added an IsAdmin property to my Model class and decorated the PasswordMinLength attribute like so:
[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; }
Works like a charm. Thanks Steve!
来源:https://stackoverflow.com/questions/38982573/pass-variable-data-to-validationattribute