はじめに
「より機能性と応答性に優れたユーザーフレンドリーなWebアプリケーションを作成する」という目標の実現に向けて、ASP.NET 2.0では、新しいサーバーコントロールが数多く追加されました。その1つがCreateUserWizardコントロールであり、これが今回の記事のテーマです。このコントロールになじみがない方のために簡単に説明しておきますが、CreateUserWizardはその名が示すとおり、ASP.NET 2.0のメンバシップシステムで新規ユーザーアカウントを作成するためのウィザードインターフェイスを実現するものです(Wizardコントロールとメンバシップシステムの詳細については、Scott Mitchellの記事『Creating a Step-by-Step User Interface with the ASP.NET 2.0 Wizard Control』と『Examining ASP.NET 2.0's Membership, Roles, and Profile』を参照してください)。
この記事では、CreateUserWizardをマルチステッププロセスにカスタマイズする手順を紹介します。項目数の多いデータ入力フォームの場合は、いくつかのステップに分けるとユーザーの抵抗感が減り、プロセスを最後までやり遂げやすくなります。今回作成するプロセスのステップは次のとおりです。
- 請求先住所の情報を収集するステップ
- 発送先情報を収集するステップ
- ユーザー情報を収集するステップ
では本題に入りましょう。
準備
この記事を深く理解し、サンプルコードを自分で試してみるためには、少なくとも、組み込みのメンバシッププロバイダ(SqlMembershipProvider
)と「App_Data」フォルダのSQL Expressデータベースを使うようにWebサイトをセットアップする基本的な方法を知っている必要があります。このプロセスの詳細については、記事シリーズ『Examining ASP.NET 2.0's Membership, Roles, and Profile』を参照してください。また、Scott Mitchellの記事『Creating a Step-by-Step User Interface with the ASP.NET 2.0 Wizard Control』も、Wizardコントロールを総合的に理解するために役立ちます。Wizardコントロールは今回のサンプルにも出てきます。
CreateUserWizardの基本
CreateUserWizardコントロールはWizardコントロールを拡張したもので、マルチステップのユーザー登録プロセスを作成するのに最適のコントロールです。しかし、次の図を見ても分かるように、既定のCreateUserWizardコントロールをページに配置しただけでは、実際のWebアプリケーションでは使い物になりません。
このように、入力するフィールドがUser Name(ユーザー名)、Password(パスワード)、E-mail(メールアドレス)、Secret Question(秘密の質問)、Secret Answer(秘密の質問の答え)しかないのです。しかし幸いなことに、このコントロールはテンプレート化されていて、レイアウトを変更したり、入力するフィールドの数を増やしたり、マルチステッププロセスに作り変えたりすることができます。このコントロールの最も素晴らしいところは、メンバシッププロバイダとのシームレスな統合を実現することです(詳しくは後述)。
CreateUserWizardコントロールを最初にページ上に配置したときに生成されるマークアップを次に示します。
<asp:CreateUserWizard ID="CreateUserWizard1" runat="server"> <WizardSteps> <asp:CreateUserWizardStep ID="CreateUserWizardStep1" runat="server"> </asp:CreateUserWizardStep> <asp:CompleteWizardStep ID="CompleteWizardStep1" runat="server"> </asp:CompleteWizardStep> </WizardSteps> </asp:CreateUserWizard>
この宣言から、CreateUserWizardコントロールのカスタマイズ方法が想像できるのではないでしょうか。まず<WizardSteps>
タグに注目してください。このタグの内側に、ユーザー登録プロセスのすべてのステップを記述します。その次に書かれているのは、登録プロセスの最初のステップです。ここでは次のように宣言されています。
<asp:CreateUserWizardStep ID="CreateWizardStep1" runat="server"> </asp:CreateUserWizardStep>
このステップは、既定では、先ほど紹介したフィールド群(User Name、Passwordなど)を表示します。その後、[Create User]ボタンがクリックされると、そのユーザーを表す適切なレコードをSQL Expressデータベース内に作成します。最後に、次のように宣言されたステップがあります。
<asp:CompleteWizardStep ID="CompleteWizardStep1" runat="server"> </asp:CompleteWizardStep>
このステップは、既定では、「Your account has been successfully created(アカウントが正常に作成されました)」というメッセージと[Continue]ボタンを表示します。[Continue]ボタンがクリックされると、CreateUserWizardコントロールのContinueDestinationPageUrl
プロパティに指定されているページへとユーザーを導きます。
CreateUserWizardコントロールのカスタマイズ
それでは、ウィザード内のステップをカスタマイズする方法を見ていきましょう。<asp:WizardStep>
要素を追加することで、ユーザー登録プロセスに新しいステップを追加します。例えば、ユーザー登録プロセスの第1ステップとして請求先情報を収集するためには、既存のステップの前に次のステップを追加します。
<asp:WizardStep ID="CreateUserWizardStep0" runat="server"> <table> <tr> <th>Billing Information</th> </tr> <tr> <td>Billing Address:</td> <td> <asp:TextBox runat="server" ID="BillingAddress" MaxLength="50" /> <asp:RequiredFieldValidator runat="server" ID="RequiredFieldValidator1" ControlToValidate="BillingAddress" ErrorMessage="Billing Address is required." /> </td> </tr> <tr> <td>Billing City:</td> <td> <asp:TextBox runat="server" ID="BillingCity" MaxLength="50" Columns="15" /> <asp:RequiredFieldValidator runat="server" ID="RequiredFieldValidator2" ControlToValidate="BillingCity" ErrorMessage="Billing City is required." /> </td> </tr> <tr> <td>Billing State:</td> <td> <asp:TextBox runat="server" ID="BillingState" MaxLength="25" Columns="10" /> <asp:RequiredFieldValidator runat="server" ID="RequiredFieldValidator3" ControlToValidate="BillingState" ErrorMessage="Billing State is required." /> </td> </tr> <tr> <td>Billing Zip:</td> <td> <asp:TextBox runat="server" ID="BillingZip" MaxLength="10" Columns="10" /> <asp:RequiredFieldValidator runat="server" ID="RequiredFieldValidator4" ControlToValidate="BillingZip" ErrorMessage="Billing Zip is required." /> </td> </tr> </table> </asp:WizardStep>
このWizardStep(ID
プロパティの値はCreateUserWizardStep0
)の内側に、今回のマルチステッププロセスの第1ステップで必要とされるすべての入力コントロールとRequiredFieldValidatorを配置します。具体的には、ユーザーが請求先の住所(番地、市、州、郵便番号)を入力するためのフィールドを用意し、これらをすべて必須フィールドにします。
ユーザーの発送先情報を収集するには、これとほとんど同じ<asp:WizardStep>
を、最初に紹介した<asp:WizardStep>
の直後に追加します。この発送先情報収集ステップでは、ユーザーに発送先の住所(番地、市、州、郵便番号)とその他の発送関連の情報の入力を求めます。このステップのマークアップについての説明は省略します。このサンプルの完全なソースコードは、記事の冒頭に示されているリンクからダウンロードすることができます。この新しいWizardStepのID
プロパティはCreateUserWizardStep1
にします。これでは同じページ上にあるCreateUserWizardStepのID
プロパティの値と衝突してしまうので、CreateUserWizardStepのID
プロパティをCreateUserWizardStep2
に変更します。これで最初の2つのカスタムステップが定義できました。
最初に作成したCreateUserWizardStepをそのままにして、既定のフィールドを表示するだけでもよいのですが、前の2つのステップに合わせてレイアウトをカスタマイズしてみましょう。これにより、後でこのステップを自分でもっと大きくカスタマイズするときに必要な知識が身につくと思います。このステップをカスタマイズするには、まずこのステップ内に<ContentTemplate>
タグを追加し、その内側に必要なコードをすべて記述します。このステップをカスタマイズするために必要なマークアップは次のようになります。細かい内容は後で説明します。
<asp:CreateUserWizardStep ID="CreateUserWizardStep2" runat="server"> <ContentTemplate> <table> <tr> <th>User Information</th> </tr> <tr> <td>Username:</td> <td> <asp:TextBox runat="server" ID="UserName" /> <asp:RequiredFieldValidator runat="server" ID="RequiredFieldValidator9" ControlToValidate="UserName" ErrorMessage="Username is required." /> </td> </tr> <tr> <td>Password:</td> <td> <asp:TextBox runat="server" ID="Password" TextMode="Password" /> <asp:RequiredFieldValidator runat="server" ID="RequiredFieldValidator10" ControlToValidate="Password" ErrorMessage="Password is required." /> </td> </tr> <tr> <td>Confirm Password:</td> <td> <asp:TextBox runat="server" ID="ConfirmPassword" TextMode="Password" /> <asp:RequiredFieldValidator runat="server" ID="RequiredFieldValidator13" ControlToValidate="ConfirmPassword" ErrorMessage="Confirm Password is required." /> </td> </tr> <tr> <td>Email:</td> <td> <asp:TextBox runat="server" ID="Email" /> <asp:RequiredFieldValidator runat="server" ID="RequiredFieldValidator11" ControlToValidate="Email" ErrorMessage="Email is required." /> </td> </tr> <tr> <td>Question:</td> <td> <asp:TextBox runat="server" ID="Question" /> <asp:RequiredFieldValidator runat="server" ID="RequiredFieldValidator12" ControlToValidate="Question" ErrorMessage="Question is required." /> </td> </tr> <tr> <td>Answer:</td> <td> <asp:TextBox runat="server" ID="Answer" /> <asp:RequiredFieldValidator runat="server" ID="RequiredFieldValidator14" ControlToValidate="Answer" ErrorMessage="Answer is required." /> </td> </tr> <tr> <td colspan="2"> <asp:CompareValidator ID="PasswordCompare" runat="server" ControlToCompare="Password" ControlToValidate="ConfirmPassword" Display="Dynamic" ErrorMessage="The Password and Confirmation Password must match."> </asp:CompareValidator> </td> </tr> <tr> <td colspan="2"> <asp:Literal ID="ErrorMessage" runat="server" EnableViewState="False"></asp:Literal> </td> </tr> </table>
このコードにはレイアウト用のHTML
タグ(<table>
など)も含まれていますが、それ以外の部分は、新規ユーザーを作成してエラー発生時にユーザーにフィードバックするために必要な情報を表しており、これらの情報がASP.NET 2.0のSqlMembershipProvider
に引き渡されます。このコードで重要なのは、各コントロールに適切な名前を付け(つまり正しいIDを指定し)、どのコントロールがどのユーザー属性を表しているかをASP.NETが認識できるようにすることです。例えば1つ目のTextBoxにはID="Username"
と指定されています。このようなIDを指定すると、ASP.NETは、このTextBoxがユーザーのユーザー名を表していることを認識します。ID="Password"
と指定されているTextBoxも同様です。ASP.NETは、このTextBoxに基づいてユーザーのパスワードを作成すればよいということを認識します。コードの残りの部分でも、サーバーコントロールのID
プロパティを見れば、それが何に使われるものであるかが分かります。後でこのステップを自分で大幅にカスタマイズする場合は(例えばニュースレターの配信を希望するかどうかを尋ねるCheckBoxを配置するなど)、最初の2つのステップを追加したときと同様の方法で、サーバーコントロールとマークアップを追加します。