问题
I used a Custom validation attribute -AmountShouldBeLessOrEqualAttribute- that its validation process related to value of another property and this attribute works successfully.
But in the following scenario I have a problem with it:
- Start the Application
- Going to the Form page
- Submit the Form (POST the form for first time)
The
ModelBindingprocess cause that the value ofErrorMessagein theAmountShouldBeLessOrEqualattribute be formatted. For example:In the
ViewModelthere is anAmountproperty with the above attibuteand
Its ErrorMessage:
Your amount should be less than {0}Will be convert to:
Your amount should be less than 23Note:
23is the value ofMaxAmountproperty in theViewModelNow I change the
MaxAmountto83- We go to the Form page again and submit the form
- The
ModelBindingprocess will be start the validation process ofAmountShouldBeLessOrEqualAttibute. Now if I watch the value of ErrorMessage property it is notYour amount should be less than {0}, it remained as the old formatted text:Your amount should be less than 23. So it can not be formatted again toYour amount should be less than 83
My question:
How should I reset the formatted ErrorMessages to its Non-Formatted version each time to be formatted with new value?
In ViewModel:
[AmountShouldBeLessOrEqual(nameof(MaxAmount), ErrorMessage = "Your amount should be less than {0}")]
public decimal Amount { get; set; }
public decimal MaxAmount { get; set; }
AmountShouldBeLessOrEqualAttribute:
public class AmountShouldBeLessOrEqualAttribute : ValidationAttribute
{
private readonly string _comparisonProperty;
public AmountShouldBeLessOrEqualAttribute(string comparisonProperty)
{
_comparisonProperty = comparisonProperty;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
ErrorMessage = ErrorMessageString;
var currentValue = (decimal)value;
var comparisonValue = GetComparisonValue(_comparisonProperty, validationContext);
if (ErrorMessage == null && ErrorMessageResourceName == null)
{
ErrorMessage = "Amount is large";
}
else
{
ErrorMessage = string.Format(ErrorMessage ?? "", comparisonValue);
}
return currentValue >= comparisonValue
? new ValidationResult(ErrorMessage)
: ValidationResult.Success;
}
public override string FormatErrorMessage(string name)
{
return base.FormatErrorMessage(name);
}
private decimal GetComparisonValue(string comparisonProperty, ValidationContext validationContext)
{
var property = validationContext.ObjectType.GetProperty(comparisonProperty);
if (property == null)
throw new ArgumentException("Not Found!");
var comparisonValue = (decimal)property.GetValue(validationContext.ObjectInstance);
return comparisonValue;
}
}
回答1:
This is caused that you are setting value for ErrorMessage with string.Format(ErrorMessage ?? "", comparisonValue);. ErrorMessage is the value from [AmountShouldBeLessOrEqual(nameof(MaxAmount), ErrorMessage = "Your amount should be less than {0}")] which you should not change during IsValid.
Try to define a scoped variable in IsValid to store the formatted error message.
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string error = "";
var currentValue = (decimal)value;
var comparisonValue = GetComparisonValue(_comparisonProperty, validationContext);
if (ErrorMessage == null && ErrorMessageResourceName == null)
{
ErrorMessage = "Amount is large";
}
else
{
error = string.Format(ErrorMessage ?? "", comparisonValue);
}
return currentValue >= comparisonValue
? new ValidationResult(error)
: ValidationResult.Success;
}
来源:https://stackoverflow.com/questions/53636422/how-to-reset-the-formatted-errormessages-of-the-validation-attributes-in-asp-net