ユーザー情報管理画面の変更
ここまでで、ユーザークラスと対応するデータベースの変更が完了しました。あとは、追加したプロファイル情報を登録するため、ユーザーの管理ページ(Account\Manage.aspxファイル)に変更を加えます。管理ページにはもともとパスワードの変更を行うための記載がありますので、そちらを参考に「プロファイルの変更」を行う項目を追加します(リスト2)。
… </asp:PlaceHolder> <asp:PlaceHolder runat="server" ID="changeProfileHolder" Visible="true"> <div class="form-horizontal"> <h4>プロファイルの変更フォーム</h4> <hr /> <asp:ValidationSummary runat="server" ShowModelStateErrors="true" CssClass="text-danger" ValidationGroup="ChangeProfile" /> <div class="form-group"> <asp:Label runat="server" ID="lastNameLabel" AssociatedControlID="lastName" CssClass="col-md-2 control-label">姓</asp:Label> <div class="col-md-10"> <asp:TextBox runat="server" ID="lastName" CssClass="form-control" /> </div> </div> <div class="form-group"> <asp:Label runat="server" ID="firstNameLabel" AssociatedControlID="firstName" CssClass="col-md-2 control-label">名</asp:Label> <div class="col-md-10"> <asp:TextBox runat="server" ID="firstName" CssClass="form-control" /> </div> </div> <div class="form-group"> <asp:Label runat="server" ID="birthdayLabel" AssociatedControlID="birthday" CssClass="col-md-2 control-label">誕生日</asp:Label> <div class="col-md-10"> <asp:TextBox runat="server" ID="birthday" CssClass="form-control" /> <asp:CompareValidator runat="server" Type="Date" Operator="DataTypeCheck" ControlToValidate="birthday" CssClass="text-danger" Display="Dynamic" ErrorMessage="日付を入力してください。" ValidationGroup="ChangeProfile" /> </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <asp:Button runat="server" Text="プロファイルの変更" ValidationGroup="ChangeProfile" OnClick="ChangeProfile_Click" CssClass="btn btn-default" /> </div> </div> </div> </asp:PlaceHolder> </section> <section id="externalLoginsForm"> …
ポイントというポイントは特にありませんが、強いて挙げるとすれば、次の2つがあります。
- 新たにPlaceHolderコントロールを配置して内部に項目を配置すること
- 検証コントロールによる検証処理がパスワード変更のものとバッティングしないよう、ValidationGroupを別にすること
- 「プロファイルの変更」ボタンで処理を行うようにすること
次にコードビハインド側にも変更を加えます。まずはPageのLoadイベントでログイン中のユーザーのプロファイルを表示します(リスト3)。
protected void Page_Load() { if (!IsPostBack) { // レンダリングするセクションを判別します var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); if (HasPassword(manager)) { changePasswordHolder.Visible = true; } else { setPassword.Visible = true; changePasswordHolder.Visible = false; } CanRemoveExternalLogins = manager.GetLogins(User.Identity.GetUserId()).Count() > 1; // (1) // ログインユーザーのプロファイル情報を表示する var user = manager.FindById(User.Identity.GetUserId()); // 姓 lastName.Text = user.LastName; // 名 firstName.Text = user.FirstName; // Eメールアドレス email.Text = user.Email; // 誕生日 birthday.Text = user.Birthday.HasValue ? user.Birthday.Value.ToString("yyyy/MM/dd") : ""; // 成功メッセージをレンダリングします var message = Request.QueryString["m"]; if (message != null) { // アクションからクエリ文字列を削除します Form.Action = ResolveUrl("~/Account/Manage"); SuccessMessage = message == "ChangePwdSuccess" ? "パスワードが変更されました。" : message == "SetPwdSuccess" ? "パスワードが設定されました。" : message == "RemoveLoginSuccess" ? "アカウントは削除されました。" : message == "ChangeProfileSuccess" ? "プロファイルが更新されました。" // (2) : String.Empty; successMessage.Visible = !String.IsNullOrEmpty(SuccessMessage); } } }
ポイントは次のとおりです。
(1)ログインユーザーのプロファイル情報を表示する
UserManagerクラスの拡張メソッドであるFindByIdメソッドを使い、ログインユーザーの情報を取得します。引数に渡すIDは、前回述べたようにHttpContextのUserプロパティにログインユーザーの情報を設定されているので、その値を使用します。
ユーザー情報を取得した後は、必要な項目を画面のコントロールに設定します。
(2)プロファイル変更後のメッセージを追加する
後述するプロファイル更新処理の最後で、クエリ文字列にプロファイル変更処理が完了したことを表す値を設定します。そして、その値を使って完了メッセージを切り替える処理を、パスワード変更などの記述を参考にして追加します。
最後に、「プロファイルの変更」ボタンの処理を記述します(リスト4)。
protected void ChangeProfile_Click(object sender, EventArgs e) { if (IsValid) { // ログイン中のユーザー情報を取得する var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>(); var user = manager.FindById(User.Identity.GetUserId()); // (1) if (user == null) { throw new InvalidOperationException("ログイン中のユーザー情報が削除されました。"); } // 画面の入力値を設定する user.FirstName = firstName.Text; user.LastName = lastName.Text; var birthdayText = birthday.Text; if (string.IsNullOrEmpty(birthdayText)) { user.Birthday = null; } else { user.Birthday = DateTime.Parse(birthdayText); } // ユーザー情報を更新する IdentityResult result = manager.Update(user); // (2) if (result.Succeeded) { Response.Redirect("~/Account/Manage?m=ChangeProfileSuccess"); // (3) } else { AddErrors(result); } } }
プロファイル変更処理のポイントは次の3つです。
(1)更新対象ユーザー情報を取得する
Page.Loadイベントハンドラーと同様に、処理対象となるユーザー情報をUserManagerクラスを使って取得します。画面の入力値はこのユーザー情報オブジェクトに設定します。
(2)ユーザー情報を更新する
UserManagerクラスの拡張メソッドであるUpdateメソッドを使い、ユーザー情報を更新します。内部ではEFを用いてAspNetUsersテーブルへの更新処理が行われます。
(3)完了メッセージのタイプを設定する
前述したように、Page.Loadイベントハンドラーで処理完了メッセージを表示するため、表示したいメッセージのタイプをここで設定します。