DataList の編集インターフェイスに検証コントロールを追加する (C#)
このチュートリアルでは、DataList の EditItemTemplate に検証コントロールを追加して、より確実な編集ユーザー インターフェイスを提供する方法について説明します。
はじめに
ここまでの DataList 編集チュートリアルでは、製品名の不足やマイナスの価格などの無効なユーザー入力によって例外が発生するにもかかわらず、DataLists 編集インターフェイスに積極的なユーザー入力検証は含まれていませんでした。 前のチュートリアルでは、発生した例外キャッチしてその情報を適切に表示するために、DataList の UpdateCommand
イベント ハンドラーに例外処理コードを追加する方法を調べました。 ただし、編集インターフェイスには、ユーザーがそもそもこのような無効なデータを入力できないようにするための検証コントロールが含まれているのが理想的です。
このチュートリアルでは、DataList の EditItemTemplate
に検証コントロールを追加して、より確実な編集ユーザー インターフェイスを提供することがいかに簡単かを説明します。 具体的には、このチュートリアルでは、前のチュートリアルで作成した例を使用し、適切な検証を含むように編集インターフェイスを拡張します。
手順 1: 「BLL レベルと DAL レベルの例外の処理」の例を複製する
「BLL レベルと DAL レベルの例外の処理」のチュートリアルでは、2 列の編集可能な DataList に製品の名前と価格を一覧表示するページを作成しました。 このチュートリアルのゴールは、検証コントロールを含むように DataList の編集インターフェイスを拡張することです。 具体的には、検証ロジックで以下を行います。
- 製品名を指定することを必須にする
- 価格に入力された値が有効な通貨形式であることを確認する
- 負の
UnitPrice
の値は無効であるため、価格に入力された値が 0 以上であることを確認する
前の例を拡張して検証を含める前に、まず、EditDeleteDataList
フォルダーにある ErrorHandling.aspx
ページの例をこのチュートリアルのページ UIValidation.aspx
にレプリケートする必要があります。 これを実現するには、ErrorHandling.aspx
ページの宣言マークアップとそのソース コードの両方をコピーする必要があります。 まず、次の手順を実行して、宣言マークアップをコピーします。
- Visual Studio で
ErrorHandling.aspx
ページを開きます。 - ページの宣言マークアップに移動します (ページの下部にある [ソース] ボタンをクリックします)
- 図 1 に示すように、
<asp:Content>
と</asp:Content>
タグ内のテキスト (3 行目から 32 行目) をコピーします。
図 1: <asp:Content>
コントロール内のテキストをコピーする (フルサイズの画像を表示するにはクリックします)
UIValidation.aspx
ページを開きます- ページの宣言マークアップに移動します
<asp:Content>
コントロール内にテキストを貼り付けます
ソース コードをコピーするには、ErrorHandling.aspx.vb
ページを開き、EditDeleteDataList_ErrorHandling
クラス "内" のテキストのみをコピーします。 3 つのイベント ハンドラー (Products_EditCommand
、Products_CancelCommand
、および Products_UpdateCommand
) を DisplayExceptionDetails
メソッドと共にコピーしますが、クラスの宣言および using
ステートメントはコピーしません。 コピーしたテキストを UIValidation.aspx.vb
の EditDeleteDataList_UIValidation
クラス "内" に 貼り付けます。
コンテンツとコードを ErrorHandling.aspx
から UIValidation.aspx
に移動した後、ブラウザーでページをテストします。 同じ出力が表示され、これら 2 つの各ページで同じ機能が表示されます (図 2 を参照)。
図 2: UIValidation.aspx
ページは ErrorHandling.aspx
の機能を模倣 (フルサイズの画像を表示するにはをクリックします)
手順 2: DataList の EditItemTemplate に検証コントロールを追加する
データ入力フォームを作成するときは、ユーザーがすべての必須フィールドに入力し、指定されたすべての入力が適切に書式設定された有効な値であることが重要です。 ユーザーの入力が有効であることを確認するために、ASP.NET には、単一入力 Web コントロールの値を検証するように設計された 5 つの組み込みの検証コントロールが用意されています。
- RequiredFieldValidator は、値が指定されていることを確認します
- CompareValidator は、別の Web コントロール値または定数値に対して値を検証するか、値の形式が指定したデータ型に対して有効であることを確認します
- RangeValidator は、値が値の範囲内にあることを確認します
- RegularExpressionValidator は、正規表現に対して値を検証します
- CustomValidator は、カスタムのユーザー定義メソッドに対して値を検証します
これら 5 つのコントロールの詳細については、「編集と挿入のインターフェイスへの検証コントロールの追加」チュートリアルを参照するか、ASP.NET クイック スタート チュートリアルの「検証コントロール」セクションを確認してください。
このチュートリアルでは、RequiredFieldValidator を使用して製品名の値が指定されていることを確認し、CompareValidator を使用して、入力された価格の値が 0 以上で、有効な通貨形式で示されていることを確認する必要があります。
Note
ASP.NET 1.x には同じ 5 つの検証コントロールがありましたが、ASP.NET 2.0 では、多数の改良が加えられています。主要な 2 つとして、Internet Explorer に加えて、クライアント側スクリプトのブラウザーでのサポートと、ページ上の検証コントロールを検証グループに分割する機能があります。 2.0 の新しい検証コントロール機能の詳細については、「ASP.NET 2.0 での検証コントロールの解剖」を参照してください。
まず、DataList の EditItemTemplate
に必要な検証コントロールを追加します。 このタスクは、デザイナーで DataList のスマート タグから [テンプレートの編集] リンクをクリックするか、宣言型構文を使用して実行できます。 [デザイン] ビューの [テンプレートの編集] オプションを使用して、このプロセスを順番に実行してみましょう。 DataList の EditItemTemplate
を編集することを選択した後、ツールボックスから RequiredFieldValidatorをドラッグしてテンプレート編集インターフェイスに追加し、ProductName
TextBox の後に配置します。
図 3: RequiredFieldValidator を EditItemTemplate After
の ProductName
TextBox の後ろに追加する (フルサイズの画像を表示するにはクリックします)
すべての検証コントロールは、単一の ASP.NET Web コントロールの入力を検証することによって機能します。 そのため、追加した RequiredFieldValidator を ProductName
TextBox に対して検証する必要があることを示す必要があります。このためには、検証コントロールの ControlToValidate
プロパティ を適切な Web コントロールの ID
に設定します (この場合は ProductName
)。 次に、ErrorMessage
プロパティを "You must provide the product s name" に設定し、その Text
プロパティ を * に設定します。 Text
プロパティ値 (指定されている場合) は、検証が失敗した場合に検証コントロールによって表示されるテキストです。 必須の ErrorMessage
プロパティ値は ValidationSummary コントロールによって使用されます。Text
プロパティ値を省略すると、無効な入力に対して検証コントロールによって ErrorMessage
プロパティ値が表示されます。
RequiredFieldValidator のこれら 3 つのプロパティを設定すると、画面は図 4 のようになります。
図 4: RequiredFieldValidator の ControlToValidate
、ErrorMessage
、Text
プロパティを設定する (フルサイズの画像を表示するにはクリックします)
RequiredFieldValidator が EditItemTemplate
に追加されたので、後は、製品の価格 TextBox に必要な検証を追加するだけです。 レコードを編集するときに UnitPrice
は省略可能であるため、RequiredFieldValidator を追加する必要はありません。 ただし、CompareValidator を追加して、UnitPrice
が指定された場合は、通貨として適切に書式設定され、0 以上であることを確認する必要があります。
CompareValidator を EditItemTemplate
に追加し、その ControlToValidate
プロパティを UnitPrice
に設定し、ErrorMessage
プロパティ "The price must be greater than or equal to zero and cannot include the currency symbol" に、その Text
プロパティを * に設定します。 UnitPrice
値が 0 以上である必要があることを示すには、CompareValidator の Operator
プロパティ を GreaterThanEqual
に、その ValueToCompare
プロパティを 0 に、Type
プロパティ を Currency
に設定します。
これら 2 つの検証コントロールを追加した後、DataList の EditItemTemplate
の宣言型構文は次のようになります。
<EditItemTemplate>
Product name:
<asp:TextBox ID="ProductName" runat="server"
Text='<%# Eval("ProductName") %>'></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1"
ControlToValidate="ProductName"
ErrorMessage="You must provide the product's name"
runat="server">*</asp:RequiredFieldValidator>
<br />
Price:
<asp:TextBox ID="UnitPrice" runat="server"
Text='<%# Eval("UnitPrice", "{0:C}") %>'></asp:TextBox>
<asp:CompareValidator ID="CompareValidator1"
ControlToValidate="UnitPrice"
ErrorMessage="The price must be greater than or equal to zero
and cannot include the currency symbol"
Operator="GreaterThanEqual" Type="Currency" ValueToCompare="0"
runat="server">*</asp:CompareValidator><br />
<br />
<asp:Button ID="UpdateProduct" runat="server" CommandName="Update"
Text="Update" />
<asp:Button ID="CancelUpdate" runat="server" CommandName="Cancel"
Text="Cancel" />
</EditItemTemplate>
これらの変更を行った後、ブラウザーでページを開きます。 商品の編集時に名前を省略したり、無効な価格値を入力しようとすると、テキスト ボックスの横にアスタリスクが表示されます。 図 5 に示すように、$19.95 のように通貨記号を含む価格値は無効と見なされます。 CompareValidator s Currency
Type
では、数字区切り文字 (カルチャ設定に応じてコンマやピリオドなど) と先頭のプラス記号またはマイナス記号を使用できますが、通貨記号は 使用できません。 この動作は、編集インターフェイスが現在通貨形式を使用して UnitPrice
をレンダリングするため、ユーザーを困惑させる可能性があります。
図 5: 入力が無効なテキスト ボックスの横にアスタリスクが表示される (フルサイズの画像を表示するにはクリックします)
検証は想定通りに動作しますが、ユーザーはレコードを編集するときに通貨記号を手動で削除する必要があり、これは許容できません。 さらに、編集インターフェイスに無効な入力がある場合は、[更新] と [キャンセル] のどちらのボタンをクリックしてもとポストバックが呼び出されません。 [キャンセル] ボタンは、ユーザーの入力の有効性に関係なく、DataList を編集前の状態に戻すのが理想的です。 また、検証コントロールのクライアント側ロジックは、ブラウザーが JavaScript をサポートしていないか、サポートが無効になっている場合にユーザーがバイパスできるため、製品情報を更新する前に、DataList の UpdateCommand
イベント ハンドラーでページのデータが有効であることを確認する必要があります。
EditItemTemplate の UnitPrice TextBox から通貨記号を削除する
CompareValidator の Currency``Type
を使用する場合、検証対象の入力に通貨記号を含めてはなりません。 このようなシンボルが存在すると、CompareValidator によって入力が無効としてマークされます。 ただし、編集インターフェイスには現在、UnitPrice
TextBox に通貨記号が含まれています。つまり、ユーザーは変更を保存する前に通貨記号を明示的に削除する必要があります。 これを解決するために、次の 3 つのオプションがあります。
UnitPrice
TextBox の値が通貨として書式設定されないようにEditItemTemplate
を構成します。- CompareValidator を削除し、正しく書式設定された通貨値をチェックする RegularExpressionValidator に置き換えることで、ユーザーが通貨記号を入力できるようにします。 ここでの課題は、通貨値を検証する正規表現が CompareValidator ほど単純ではなく、カルチャ設定を組み込む場合にはコードを記述する必要があるということです。
- 検証コントロールを完全に削除し、GridView の
RowUpdating
イベント ハンドラーでカスタムのサーバー側検証ロジックを利用します。
このチュートリアルでは、オプション 1 を使用してみましょう。 現在、UnitPrice
は、EditItemTemplate
の TextBox のデータバインド式 (<%# Eval("UnitPrice", "{0:c}") %>
) により、通貨値として書式設定されています。 Eval
ステートメントを Eval("UnitPrice", "{0:n2}")
に変更することで、結果を有効桁数 2 桁の数値として書式設定します。 これは、宣言構文を使用して直接行うことも、DataList の EditItemTemplate
の UnitPrice
TextBox から [DataBindings の編集] リンクをクリックして行うこともできます。
この変更により、編集インターフェイスの書式設定された価格には、グループ区切り記号としてコンマと小数点区切り記号としてピリオドが含まれますが、通貨記号は省略されます。
Note
編集可能なインターフェイスから通貨形式を削除する場合、TextBox の外側に通貨記号をテキストとして配置すると便利です。 これにより、通貨記号を指定する必要がないことをユーザーに示すヒントとなります。
キャンセル ボタンを修正する
既定では、検証 Web コントロールは JavaScript を出力して、クライアント側で検証を実行します。 Button、LinkButton、または ImageButton がクリックされると、ポストバックが発生する前に、ページの検証コントロールがクライアント側でチェックされます。 無効なデータがある場合、ポストバックは取り消されます。 ただし、特定の Button の場合、データの有効性は重要ではないときがあります。このような場合、無効なデータのためにポストバックを取り消すことは迷惑です。
[キャンセル] ボタンはその一例です。 ユーザーが商品の名前を省略するなど、無効なデータを入力した後で、商品を保存しないことにし、[キャンセル] ボタンをクリックするとします。 現在、[キャンセル] ボタンがクリックされると、ページ上の検証コントロールがトリガーされます。これにより、製品名が見つからないことが報告され、ポストバックが実行されません。 ユーザーは、編集プロセスをキャンセルするために ProductName
TextBox にテキストを入力する必要があります。
幸いなことに、Button、LinkButton、および ImageButton には、Button のクリックで検証ロジックを開始するかどうかを示す CausesValidation
プロパティがあります (既定値は True
)。 [キャンセル] ボタンの CausesValidation
プロパティを False
に設定します。
UpdateCommand イベント ハンドラーで入力が有効であることを確認する
検証コントロールによって出力されるクライアント側スクリプトにより、ユーザーが無効な入力を入力した場合、検証コントロールは、CausesValidation
プロパティが True
(既定値) である Button、LinkButton、または ImageButton コントロールによって開始されたすべてのポストバックを取り消します。 ただし、ユーザーが古いブラウザー、または JavaScript のサポートが無効になっているブラウザーを使用してアクセスしている場合、クライアント側の検証チェックは実行されません。
すべての ASP.NET 検証コントロールは、ポストバックの直後に検証ロジックを繰り返し、Page.IsValid
プロパティを使用してページの入力の全体的な有効性を報告します。 ただし、Page.IsValid
の値に基づいてページ フローが中断または停止されることはありません。 開発者は、有効な入力データを前提とするコードを続行する前に、Page.IsValid
プロパティの値が True
であることを確認する必要があります。
ユーザーが JavaScript を無効にして、ページにアクセスし、商品を編集して価格の値として "Too expensive" を入力し、[更新] ボタンをクリックすると、クライアント側の検証はバイパスされ、ポストバックが続きます。 ポストバックでは、ASP.NET ページの UpdateCommand
イベント ハンドラーが実行され、"Too expensive" を Decimal
に解析しようとしたときに例外が発生します。 例外処理があるため、このような例外は正常に処理されますが、Page.IsValid
の値が True
のときにのみ UpdateCommand
イベント ハンドラーへと進むことで、そもそも無効なデータが通過してしまうことを防ぐことができます。
UpdateCommand
イベント ハンドラーの先頭の Try
ブロックの直前に次のコードを追加します。
if (!Page.IsValid)
return;
この追加により、送信されたデータが有効な場合にのみ、商品の更新が試みられます。 検証コントロールのクライアント側スクリプトにより、ほとんどのユーザーは無効なデータをポストバックできませんが、JavaScript をサポートしていない、または JavaScript のサポートが無効になっているブラウザーを使用するユーザーは、クライアント側のチェックをバイパスして無効なデータを送信できます。
Note
鋭い読者の方は、GridView でデータを更新するときに、ページの分離コード クラスで Page.IsValid
プロパティを明示的にチェックする必要がなかったことを思い出すでしょう。 これは、GridView が Page.IsValid
プロパティを自動的に参照し、True
の値が返された場合にのみ更新を続行するためです。
手順 3: データ入力の問題の概要
5 つの検証コントロールに加えて、ASP.NET には ValidationSummary コントロールが用意されています。これは、無効なデータを検出した検証コントロールの ErrorMessage
を表示します。 この概要データは、Web ページ上のテキストとして、またはクライアント側のモーダル メッセージ ボックスを介して表示できます。 検証の問題を要約したクライアント側のメッセージ ボックスを含むように、このチュートリアルを拡張しましょう。
これを実現するには、ツールボックスからデザイナーに ValidationSummary コントロールをドラッグします。 ValidationSummary コントロールの場所は重要ではありません。たんに要約をメッセージ ボックスとして表示するように構成するだけです。 コントロールを追加した後、その ShowSummary
プロパティを False
に、ShowMessageBox
プロパティ を True
に設定します。 これを追加することで、検証エラーはクライアント側のメッセージ ボックスにまとめられます (図 6 を参照)。
図 6: 検証エラーはクライアント側のメッセージ ボックスに要約される (フルサイズの画像を表示するにはクリックします)
まとめ
このチュートリアルでは、検証コントロールを使用して、更新ワークフローでユーザーの入力を使用する前に、ユーザーの入力が有効であることを事前に確認することで、例外の可能性を減らす方法について説明しました。 ASP.NET には、特定の Web コントロールの入力を検査し、入力の有効性を報告するように設計された 5 つの検証 Web コントロールが用意されています。 このチュートリアルでは、これらの 5 つのコントロールのうちの 2 つである RequiredFieldValidator と CompareValidator を使用して、商品名が指定されていること、および価格が 0 以上の値を持つ通貨形式であることを確認しました。
DataList の編集インターフェイスに検証コントロールを追加するには、ツールボックスからコントロールを EditItemTemplate
にドラッグして、いくつかのプロパティを設定するだけです。 既定では、検証コントロールはクライアント側の検証スクリプトを自動的に出力します。また、ポストバック時にサーバー側の検証を実行し、累積的な結果を Page.IsValid
プロパティに保存します。 Button、LinkButton、または ImageButton がクリックされたときにクライアント側の検証をバイパスするには、ボタンの CausesValidation
プロパティを False
に設定します。 また、ポストバック時に送信されたデータを使用してタスクを実行する前に、Page.IsValid
プロパティが True
を返すことを確認します。
これまでに見てきたすべての DataList 編集チュートリアルでは、非常に単純な編集インターフェイスに、製品名の TextBox と価格用の別の TextBox を使用しました。 ただし、編集インターフェイスには、DropDownList、Calendar、RadioButton、CheckBox など、さまざまな Web コントロールを混在させることができます。 次のチュートリアルでは、さまざまな Web コントロールを使用するインターフェイスの構築について説明します。
プログラミングに満足!
著者について
7 冊の ASP/ASP.NET 書籍の著者であり、 4GuysFromRolla.comの創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジに取り組んでいます。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の著書は Sams Teach Yourself ASP.NET 2.0 in 24 Hoursです。 にアクセスするか、ブログを使用して にアクセスmitchell@4GuysFromRolla.comできます。これは でhttp://ScottOnWriting.NET見つけることができます。
特別な感謝
このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は、Dennis Patterson 氏、Ken Pespisa 氏、Liz Shulok 氏でした。 今後の MSDN の記事を確認することに関心がありますか? その場合は、 mitchell@4GuysFromRolla.comに行をドロップしてください。