MVC2 comes with a nice sample of a validation attribute called "PropertiesMustMatchAttribute" that will compare two fields to see if they match. Use of that attribute looks like this:
[PropertiesMustMatch("NewPassword", "ConfirmPassword", ErrorMessage = "The new password and confirmation password do not match.")]
public class ChangePasswordModel
{
public string NewPassword { get; set; }
public string ConfirmPassword { get; set; }
}
The attribute is attached to the model class and uses a bit of reflection to do its work. You'll also notice the error message here is specified directly: "The new password and confirmation password do not match."
If you don't specify the message, the default message is generated using some code like this (shortened for clarity):
private const string _defaultErrorMessage = "'{0}' and '{1}' do not match.";
public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentUICulture, _defaultErrorMessage,
OriginalProperty, ConfirmProperty);
}
The problem with that is that the "OriginalProperty" and "ConfirmProperty" are the hardcoded strings in the attribute - "NewPassword" and "ConfirmPassword" in this example. They don't actually get the real model metadata (e.g., the DisplayNameAttribute) to put together a more flexible, localizable message. I'd like to have a more generally applicable comparison attribute that uses the metadata display name info and so forth that's been specified.
Assuming I don't want to create a custom error message for every instance of my ValidationAttribute, that means I need to get a reference to the model metadata (or, at the very least, the model type that I'm validating) so I can get that metadata information and use it in my error messages.
How do I get a reference to the model metadata for the model I'm validating from inside the attribute?
(While I've found several questions that ask about how to validate dependent fields in a model, none of the answers include handling the error message properly.)