我们在一个MVC3项目中创建了以下视图模型:
[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
{
.....
PropertiesMustMatch是我们创建的自定义属性,代码如下:
[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);
}
}
但是,在视图中,当1)电子邮件和确认电子邮件以及2)密码和确认密码都不匹配时,密码的验证消息显示在顶部。见下图:
我们希望电子邮件文本框的验证消息显示在顶部,因为这些文本框出现在密码文本框之前。
注意:本地构建(通过VS2010)上的消息顺序按预期工作。消息的顺序仅在DEV和TEST环境中搞砸。通过反射器查看已部署的DLL,这是显示的内容:(属性的顺序颠倒过来)
我们可以做些什么来解决发布版本问题? 任何帮助/建议将不胜感激。
感谢。
答案 0 :(得分:3)
我们仍然不知道为什么编译器弄乱了验证属性设置的顺序,有点废话!
我们必须使用不同的方法来解决这个问题。
我们摆脱了自定义验证属性,并在视图模型上实现了IValidatableObject。在Validate方法中,按照我们希望显示消息的顺序添加验证逻辑(代码如下):
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.");
}
}