以下のコードを使用して、新しいユーザーのビューモデルを作成したいと思います。 「User」クラスには、データベースに保持する2つのプロパティ(ここでは簡略化)のみが含まれています。ビューモデルは、ビューでのみ使用される「パスワードの比較」フィールドを追加します。 「User」で定義されたすべてのフィールドを繰り返すのではなく、ビューモデルで「User」クラスを直接使用することをお勧めします。
私の質問は、「ComparePassword」フィールドの[Compare]属性で「User.Password」を適切に参照するにはどうすればよいですか?
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; }
}
「Password」と「ComparePassword」用に生成されるHTMLは以下のとおりです。
<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="" />
重要なのは、「data-val-equalto-other "がJavascriptによってどのように処理されるかです。 "Password"または "ser_Password"を使用すると、何も起こりません-チェックは実行されません。 "ser.Password"を使用すると、チェックは実行されますが、常に失敗します。
JQueryで直接これを行うのに実際の問題はありませんが、可能であれば[Compare]属性を使用したいと思います。
StackOverflowとMicrosoftConnectを介して答えを見つけました:
見る:
http://connect.Microsoft.com/VisualStudio/feedback/details/665793/jquery-unobtrusive-validate-equalto-fails-with-compare-attribute および JQuery1.5ブレーク比較検証(JQuery Validate 1.8)
要約すると、MVC3に付属のjquery.validate.unobtrusiveファイルのバグのように見えます。回避策は、jquery.validate.unobtrusiveファイルの次の行を変更することです。
element = $(options.form).find(":input[name=" + fullOtherName + "]")[0];
に
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);
}