Reputation: 932
We have created the following view model in one of our MVC3 projects:
[PropertiesMustMatch("Email", "ConfirmEmail", ErrorMessage = "The email address you provided does not match the email address in the confirm email box.")]
[PropertiesMustMatch("NewPassword", "ConfirmPassword", ErrorMessage = "The new password you provided does not match the confirmation password in the confirm password box.")]
public class ActivationStep2ViewModel
{
.....
The PropertiesMustMatch is a custom attribute that we have created, code as below:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class PropertiesMustMatchAttribute : ValidationAttribute
{
private const string _defaultErrorMessage = "'{0}' and '{1}' do not match.";
private readonly object _typeId = new object();
public PropertiesMustMatchAttribute(string originalProperty, string confirmProperty)
: base(_defaultErrorMessage)
{
OriginalProperty = originalProperty;
ConfirmProperty = confirmProperty;
}
public string ConfirmProperty { get; private set; }
public string OriginalProperty { get; private set; }
public override object TypeId
{
get
{
return _typeId;
}
}
public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
OriginalProperty, ConfirmProperty);
}
public override bool IsValid(object value)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
object originalValue = properties.Find(OriginalProperty, true /* ignoreCase */).GetValue(value);
object confirmValue = properties.Find(ConfirmProperty, true /* ignoreCase */).GetValue(value);
return Object.Equals(originalValue, confirmValue);
}
}
However, on the view, when there is a mismatch between both the 1) Email and Confirm email and 2) the password and confirm password, the validation message for the password is displayed on top. See image below:
We would like the validation message for the Email text boxes to be displayed on top as these text boxes appear before the password text boxes.
NOTE: The order of the messages on local build (through VS2010) works as expected. The order of messages is screwed up only in our DEV and TEST environments. Looking at the deployed DLLs through reflector, this is what is displayed: (the order of attributes is reversed)
What can we do to fix this on the release builds? Any help / suggestions would be much appreciated.
Thanks.
Upvotes: 3
Views: 1243
Reputation: 932
We still do not know why the compiler muddles up the order of validation attributes set up, a bit crap!
We had to use a different approach to fix this.
We got rid of the custom validation attributes and implemented IValidatableObject on the view model. In the Validate method, added validation logic in the order that we wanted the messages displayed (code below):
public class ActivationStep2ViewModel : IValidatableObject
{
.
.
.
.
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if(Email != ConfirmEmail)
{
yield return new ValidationResult("The email address you provided does not match the email address in the confirm email box.");
}
if(NewPassword != ConfirmPassword)
{
yield return new ValidationResult("The new password you provided does not match the confirmation password in the confirm password box.");
}
}
Upvotes: 3