Share via


DataList の編集インターフェイスに検証コントロールを追加する (VB)

作成者: Scott Mitchell

PDF のダウンロード

このチュートリアルでは、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 ページの宣言マークアップとそのソース コードの両方をコピーする必要があります。 まず、次の手順を実行して、宣言マークアップをコピーします。

  1. Visual Studio で ErrorHandling.aspx ページを開きます。
  2. ページの宣言マークアップに移動します (ページの下部にある [ソース] ボタンをクリックします)
  3. 図 1 に示すように、<asp:Content></asp:Content> タグ内のテキスト (3 行目から 32 行目) をコピーします。

Copy the Text Within the <asp:Content> Control

図 2: <asp:Content> コントロール内のテキストをコピーする (フルサイズの画像を表示するにはをクリックします)

  1. UIValidation.aspx ページを開きます
  2. ページの宣言マークアップに移動します
  3. <asp:Content> コントロール内にテキストを貼り付けます

ソース コードをコピーするには、ErrorHandling.aspx.vb ページを開き、EditDeleteDataList_ErrorHandling クラス "内" のテキストのみをコピーします。 3 つのイベント ハンドラー (Products_EditCommandProducts_CancelCommand、および Products_UpdateCommand) を DisplayExceptionDetails メソッドと共にコピーしますが、クラスの宣言および using ステートメントはコピーしません。 コピーしたテキストを UIValidation.aspx.vbEditDeleteDataList_UIValidation クラス "内" に 貼り付けます。

コンテンツとコードを ErrorHandling.aspx から UIValidation.aspx に移動した後、ブラウザーでページをテストします。 同じ出力が表示され、これら 2 つの各ページで同じ機能が表示されます (図 2 を参照)。

The UIValidation.aspx Page Mimics the Functionality in ErrorHandling.aspx

図 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 の後に配置します。

Add a RequiredFieldValidator to the EditItemTemplate After the ProductName TextBox

図 3: RequiredFieldValidator を EditItemTemplate AfterProductName 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 のようになります。

Set the RequiredFieldValidator s ControlToValidate, ErrorMessage, and Text Properties

図 4: RequiredFieldValidator の ControlToValidateErrorMessageText プロパティを設定する (フルサイズの画像を表示するにはクリックします)

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 の CurrencyType では、桁区切り記号 (カルチャの設定に応じてコンマやピリオドなど) と先頭のプラス記号またはマイナス記号を使用できますが、通貨記号は使用 "できません"。 この動作は、編集インターフェイスが現在通貨形式を使用して UnitPrice をレンダリングするため、ユーザーを困惑させる可能性があります。

An Asterisk Appears Next to the Textboxes with Invalid Input

図 5: 入力が無効なテキスト ボックスの横にアスタリスクが表示される (フルサイズの画像を表示するにはクリックします)

検証は想定通りに動作しますが、ユーザーはレコードを編集するときに通貨記号を手動で削除する必要があり、これは許容できません。 さらに、編集インターフェイスに無効な入力がある場合は、[更新] と [キャンセル] のどちらのボタンをクリックしてもとポストバックが呼び出されません。 [キャンセル] ボタンは、ユーザーの入力の有効性に関係なく、DataList を編集前の状態に戻すのが理想的です。 また、検証コントロールのクライアント側ロジックは、ブラウザーが JavaScript をサポートしていないか、サポートが無効になっている場合にユーザーがバイパスできるため、製品情報を更新する前に、DataList の UpdateCommand イベント ハンドラーでページのデータが有効であることを確認する必要があります。

EditItemTemplate の UnitPrice TextBox から通貨記号を削除する

CompareValidator の Currency``Type を使用する場合、検証対象の入力に通貨記号を含めてはなりません。 このようなシンボルが存在すると、CompareValidator によって入力が無効としてマークされます。 ただし、編集インターフェイスには現在、UnitPrice TextBox に通貨記号が含まれています。つまり、ユーザーは変更を保存する前に通貨記号を明示的に削除する必要があります。 これを解決するために、次の 3 つのオプションがあります。

  1. UnitPrice TextBox の値が通貨として書式設定されないように EditItemTemplate を構成します。
  2. CompareValidator を削除し、正しく書式設定された通貨値をチェックする RegularExpressionValidator に置き換えることで、ユーザーが通貨記号を入力できるようにします。 ここでの課題は、通貨値を検証する正規表現が CompareValidator ほど単純ではなく、カルチャ設定を組み込む場合にはコードを記述する必要があるということです。
  3. 検証コントロールを完全に削除し、GridView の RowUpdating イベント ハンドラーでカスタムのサーバー側検証ロジックを利用します。

このチュートリアルでは、オプション 1 を使用してみましょう。 現在、UnitPrice は、EditItemTemplate の TextBox のデータバインド式 (<%# Eval("UnitPrice", "{0:c}") %>) により、通貨値として書式設定されています。 Eval ステートメントを Eval("UnitPrice", "{0:n2}") に変更することで、結果を有効桁数 2 桁の数値として書式設定します。 これは、宣言構文を使用して直接行うことも、DataList の EditItemTemplateUnitPrice 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 Not Page.IsValid Then
    Exit Sub
End If

この追加により、送信されたデータが有効な場合にのみ、商品の更新が試みられます。 検証コントロールのクライアント側スクリプトにより、ほとんどのユーザーは無効なデータをポストバックできませんが、JavaScript をサポートしていない、または JavaScript のサポートが無効になっているブラウザーを使用するユーザーは、クライアント側のチェックをバイパスして無効なデータを送信できます。

Note

鋭い読者の方は、GridView でデータを更新するときに、ページの分離コード クラスで Page.IsValid プロパティを明示的にチェックする必要がなかったことを思い出すでしょう。 これは、GridView が Page.IsValid プロパティを自動的に参照し、True の値が返された場合にのみ更新を続行するためです。

手順 3: データ入力の問題の概要

5 つの検証コントロールに加えて、ASP.NET には ValidationSummary コントロールが用意されています。これは、無効なデータを検出した検証コントロールの ErrorMessage を表示します。 この概要データは、Web ページ上のテキストとして、またはクライアント側のモーダル メッセージ ボックスを介して表示できます。 検証の問題を要約したクライアント側のメッセージ ボックスを含むように、このチュートリアルを拡張しましょう。

これを実現するには、ツールボックスからデザイナーに ValidationSummary コントロールをドラッグします。 ValidationSummary コントロールの場所は重要ではありません。たんに要約をメッセージ ボックスとして表示するように構成するだけです。 コントロールを追加した後、その ShowSummary プロパティFalse に、ShowMessageBox プロパティTrue に設定します。 これを追加することで、検証エラーはクライアント側のメッセージ ボックスにまとめられます (図 6 を参照)。

The Validation Errors are Summarized in a Client-Side Messagebox

図 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 コントロールを使用するインターフェイスの構築について説明します。

プログラミングに満足!

著者について

Scott Mitchell は、ASP/ASP.NET に関する 7 冊の書籍の著者であり、4GuysFromRolla.com の設立者でもあります。1998 年以降、Microsoft の Web テクノロジを活用した業務を行っています。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズは24時間で2.0 ASP.NET 自分自身を教えています。 にアクセスするか、ブログを使用して にアクセスmitchell@4GuysFromRolla.comできます。これは でhttp://ScottOnWriting.NET見つけることができます。

特別な感謝

このチュートリアル シリーズは、多くの役に立つ校閲者によってレビューされました。 このチュートリアルのリード レビュー担当者は、Dennis Patterson 氏、Ken Pespisa 氏、Liz Shulok 氏でした。 今後の MSDN の記事を確認することに関心がありますか? その場合は、 にmitchell@4GuysFromRolla.com行をドロップしてください。