Сравнить (пароль) атрибут
Я хотел бы создать модель представления для нового пользователя, используя следующий код. Класс "Пользователь" содержит только два свойства (упрощенных на данный момент), которые я сохраню в базе данных; модель вида добавляет поле "сравнить пароль", которое используется только в представлении. Я бы предпочел, чтобы модель представления использовала класс "Пользователь" напрямую, а не повторяла все поля, определенные в "Пользователь" .
Мой вопрос: как правильно ссылаться на "User.Password" в атрибуте [Compare] для поля "ComparePassword"?
public class User
{
[Required]
public string UserName { get; set; }
[Required]
[DisplayName("Password")]
[DataType(DataType.Password)]
public string Password { get; set; }
}
public class NewUserViewModel
{
public User User { get; set; }
[Required]
[DataType(DataType.Password)]
[DisplayName("Re-enter Password")]
[Compare("Password", ErrorMessage="Passwords must match")]
public string ComparePassword { get; set; }
}
HTML, который генерируется для "Password" и "ComparePassword", находится ниже.
<input class="text-box single-line password"
data-val="true"
data-val-required="The Password field is required."
id="User_Password"
name="User.Password"
type="password" value="" />
<input class="text-box single-line password"
data-val="true"
data-val-equalto="Passwords must match"
data-val-equalto-other="*.Password"
data-val-required="The Re-enter Password field is required."
id="ComparePassword"
name="ComparePassword"
type="password" value="" />
Ключом является то, что Javascript обрабатывает " data-val-equalto-other". Если я использую " Пароль" или " User_Password", ничего не происходит - проверка не выполняется. Если я использую " User.Password", проверка выполняется, но всегда терпит неудачу.
У меня нет реальной проблемы с этим непосредственно в jQuery, но я бы предпочел использовать атрибут [Compare], если это вообще возможно.
Ответы
Ответ 1
Просто нашел ответ через StackOverflow и Microsoft Connect:
См:
http://connect.microsoft.com/VisualStudio/feedback/details/665793/jquery-unobtrusive-validate-equalto-fails-with-compare-attribute
а также
JQuery 1.5 breaks Сравнить Validate (JQuery Validate 1.8)
Чтобы summerize, он выглядит как ошибка в файле jquery.validate.unobtrusive, который поставляется с MVC3. Обходной путь изменяет следующую строку в файле jquery.validate.unobtrusive.
element = $(options.form).find(":input[name=" + fullOtherName + "]")[0];
to
element = $(options.form).find(":input[name=" + fullOtherName.replace(".", "\\.") + "]")[0];
В Microsoft Connect говорится, что MS исправила его, но я не смог найти ссылку на новую версию. В любом случае, это работает для меня тем временем. Надеюсь, что это поможет.
Ответ 2
Я исправил эту проблему, используя два поля и сравнив их на сервере (через ненавязчивый JavaScript):
[Required(ErrorMessage = @"The new password is required")]
[StringLength(25, ErrorMessage = @"The new password must be at least {2} characters long", MinimumLength = 4)]
[DataType(DataType.Password)]
[Display(Name = @"New Password")]
public string NewPassword { get; set; }
[Required(ErrorMessage = @"The confirmation of password is required")]
[StringLength(25, ErrorMessage = @"The confirmation of new password must be at least {2} characters long", MinimumLength = 4)]
[DataType(DataType.Password)]
[Display(Name = @"Confirm New Password")]
public string ConfirmPassword { get; set; }
Код на стороне сервера:
[HttpPost]
public ViewResult ChangeUserPassword(ChangePasswordModel model)
{
Logger.Debug(LogBuilder.MethodEntry("ChangeUserPassword"));
if (model == null)
{
throw new ArgumentNullException("model");
}
if (model.NewPassword != model.ConfirmPassword)
{
ModelState.AddModelError("", Messages.ConfirmPasswordError);
return View(model);
}
if (ModelState.IsValid)
{
var changePasswordCompleted = false;
try
{
var userName = CurrentPerson.UserDetails.UserName;
var membershipUser = Membership.GetUser(userName);
if (membershipUser != null)
{
changePasswordCompleted = membershipUser.ChangePassword(model.OldPassword, model.NewPassword);
}
}
catch (Exception exception)
{
changePasswordCompleted = false;
Logger.Error(LogBuilder.LogMethodError("ChangeUserPassword", exception));
}
if (changePasswordCompleted)
{
return View("ChangePasswordCompleted");
}
}
ModelState.AddModelError("", Messages.ChangePasswordError);
return View(model);
}