I've created a custom ASP.NET MVC ValidationAttribute and I'm trying to set my own default error message on it upon instantiation by passing a string to the base constructor:
public class BusinessLogicRegex : ValidationAttribute, IClientValidatable
{
private const string _defaultErrorMessage = "Invalid Password. {0}";
private string _description;
//Other private members
...
public BusinessLogicRegex(string getMember, Type getMemberType, string descriptionMember, Type descriptionMemberType)
: base(_defaultErrorMessage)
{
//Omitted the guts of initializing validation for brevity
...
}
public override string FormatErrorMessage(string name)
{
return String.Format(ErrorMessage, _description);
}
}
But when FormatErrorMessage is called, ErrorMessage is null. Why doesn't this base(_defaultErrorMessage) set the ErrorMessage property and how should I set it while still giving the user of this attribute the ability to override it?
Edit - 2nd, cleaner Example:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class TestValidator : ValidationAttribute
{
public TestValidator()
: base("Test Error on {0}")
{
}
public override string FormatErrorMessage(string name)
{
return String.Format(ErrorMessage, name);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
}
Here again, FormatErrorMessage throws a null reference exception because ErrorMessage is null. However ErrorMessageString == "Test Error on {0}". So my mistake seems to be in thinking that calling base("Test Error on {0}") sets the ErrorMessage property. I don't understand this at all. Here how the base constructor describes its errorMessage parameter:
The error message to associate with a validation control
Here is what MSDN says about the ErrorMessageString property:
The error message string is obtained by evaluating the ErrorMessage property or by evaluating the ErrorMessageResourceType and ErrorMessageResourceName properties. The two cases are mutually exclusive. The second case is used if you want to display a localized error message.
Yet inside of FormatErrorMessage at runtime, ErrorMessage, ErrorMessageResourceType and ErrorMessageResourceName are all null. So that description makes it sound like ErrorMessageString should also be null to me. This leaves me very confused about the usage and interaction between all of these properties and the constructor.
return String.Format(ErrorMessageString, name);namein the default message somewhere though. But it'sErrorMessagethat is null._descriptionis declared as a private instance member and initialized int he constructor. See my edit. The purpose of my validator is to go get a regular expression and a description of that expression from some specified class and method so that I can have it use the exact same validation expression that my business logic uses internally. I tried to only include what was relevant to the problem.ErrorMessageis the value that your assign in[Test(ErrorMessage = "...")]. Again, when you use: base("Test Error on {0}")- its assigns thatErrorMessageString