ASP.NET でのユーザー入力の検証
アンソニー・ムーア
Microsoft Corporation
2000 年 7 月
更新日: 2002 年 3 月
概要: ASP.NET の検証フレームワークの概要と、検証をページに追加する例について説明します。 (11ページ印刷)
コンテンツ:
はじめに
問題
目的
Solution-Overview
クライアント機能
検証ツールとは
検証コントロール Walk-Through
それは自発的ではない
通常の取得
Apple と Apple の比較
ユーザー設定の自動調整
フィナーレ
サンプル コード
はじめに
ユーザー入力の検証は、Web ベースのアプリケーションで一般的なシナリオです。 運用アプリケーションの場合、開発者は多くの場合、このタスクに必要以上に多くの時間とコードを費やします。 ASP.NET ページ フレームワークを構築する際には、入力を検証するタスクを、以前よりもずっと簡単に行ってみる必要がありました。
問題
HTML 3.2 では、データの検証は困難なプロセスです。 要求を受け取るたびに、入力をチェックするコードを記述し、ユーザーがページに戻ったエラーを書き込んで、ユーザーがフォームに正しく入力できるようにする必要があります。 これは、エンド ユーザー、開発者、サーバーにとって同様の課税プロセスです。
DTHML とスクリプト言語では、ある程度改善されています。 不適切な入力に関するフィードバックをユーザーにすぐに提供し、修正されるまでページを投稿できないようにすることができます。 ただし、サイトのすべてのユーザーが必要なスクリプト環境を持っていることを保証することはほとんど不可能な場合があります。 これは通常、スクリプトを使用してページのインターフェイスを改善する場合は、クライアント スクリプトを実行できない場合に備えて、同じ検証ロジックを 2 回、クライアントに 1 回、サーバー上で再度記述する必要があることを意味します。
目的
検証の目的は次のとおりです。
- データ入力ページの一般的な入力検証タスクの 90% 以上を実行できるコンポーネントを提供します。
- これらのコンポーネントは、モダン ブラウザーで豊富なスクリプトベースの検証を実行するようにします。これにより、必要に応じて、純粋な HTML 3.2 サーバーベースの検証に効果的にフォールバックすることもできます。
- コンポーネントでカバーされていない検証タスクを簡単に完了できるように、柔軟な API を提供します。
これらのコンポーネントが処理するために必要なシナリオの種類を決定するために、多数の実際のページにアクセスしました。 今後のアプリケーションに必要な検証コードの量を大幅に削減したいと考えました。
ソリューション - 概要
検証コントロールは、ソリューションのメイン要素です。 検証コントロールは、別のコントロールの特定の有効性条件をチェックするビジュアル ASP.NET コントロールです。 通常、チェックしているコントロールがエラーになっているかどうかに応じて表示または非表示にするテキストとしてユーザーに表示されます。 また、画像にすることも、非表示にして便利な作業を行うこともできます。 さまざまな種類のチェックを実行する 5 種類の検証コントロールがあります。
ソリューションのもう 1 つの要素は、ValidationSummary コントロールです。 大きなデータ入力ページには、通常、すべてのエラーが一覧表示される領域があります。 ValidationSummary は、ページ上の検証コントロールからこのコンテンツを収集することによって、このコンテンツを自動的に生成します。
最後の要素は Page オブジェクト自体です。 すべての重要な "IsValid" プロパティが公開されます。このプロパティは、サーバー コードでチェックして、すべてのユーザー入力が OK かどうかを判断します。
クライアント機能
ほとんどの Web サイトでは、すべての検証チェックがサーバー上で行われます。 スクリプトを使用せずにクライアントに対してサーバー ベースのチェックを記述する必要があるため、リッチ クライアントに対してやり直しの記述を正当化するのは難しい場合があります。
検証コントロールは、複製されたロジックのほとんどがコントロールにカプセル化されているため、そのすべてを変更します。 インターネット エクスプローラー 4.0 以降のクライアントがページを使用している場合は、特別なクライアント スクリプトを記述しなくても、サーバー上で行われるのと同じ入力検証を実行できます。
クライアント側の検証には、次のような多くの機能があります。
- 正しくない入力が入力または修正された直後にエラーが表示され、消えることがあります。 この即時のフィードバックにより、不適切な入力を簡単に修正できます。
- クライアントで検出可能なエラーがある場合、ポストバックは防止され、ユーザーの時間を節約し、サーバー上のヒットを減らします。
- ValidationSummary は、エラーが検出された場合は、ポストバックせずにそれ自体を更新します。
- ValidationSummary は、必要に応じて、エラーがある場合にユーザーにメッセージ ボックスを表示できます。
- クライアント ロジックはすべて JScript ライブラリに含まれているため、ActiveX コンポーネントや Java アプレットは使用されません。
- オブジェクト モデルは、クライアント側の検証と動作の強化を可能にするために、クライアントで公開されます。
検証ツールとは
検証コントロールを効果的に使用するために、検証コントロールが何であるかをしっかりと定義するのに役立ちます。 前の定義を少し絞り込みましょう。
"検証コントロールは、特定の種類のエラー条件について 1 つの入力コントロールをチェックし、その問題の説明を表示するコントロールです。"
これは重要な定義です。これは、入力コントロールごとに複数の検証コントロールを頻繁に使用する必要があるためです。
たとえば、テキスト ボックス内のユーザー入力が (a) 空白でないかどうか、(b) 特定の範囲と (c) 別のテキスト入力コントロールの日付より小さい有効な日付であるかどうかをチェックする場合は、3 つの検証コントロールを使用します。 これは面倒に思えるかもしれませんが、ユーザーに役立つには、これらすべての場合に 3 つの異なるテキストの説明が必要であることを覚えておいてください。
さまざまな種類の検証コントロールを次に示します。
RequiredFieldValidator | ユーザーが何かを入力または選択したことを確認します。 |
RegularExpressionValidator | ユーザー入力を正規表現に対してチェックします。 これにより、さまざまなチェックを行い、郵便番号や電話番号などに使用できます。 |
CompareValidator | 入力コントロールを固定値または別の入力コントロールと比較します。 たとえば、パスワード検証フィールドに使用できます。 型指定された日付と数値の比較を行うこともできます。 |
RangeValidator | CompareValidator とよく似ていますが、入力が 2 つの固定値の間にあることをチェックできます。 |
Customvalidator | これにより、検証フレームワークに参加する独自のコードを記述できます。 |
検証コントロール Walk-Through
検証を示すために、既存のページに検証を追加するプロセスについて説明します。 要件の例を次に示します。
新しいユーザー ID とパスワードを収集する Web ページを作成します。 ユーザー ID には 6 ~ 10 文字のアルファ文字を含める必要があり、まだ使用することはできません。 パスワードには、4 ~ 12 文字と少なくとも 1 つの文字 "@#$%^&*/" が含まれている必要があります。ユーザーがパスワードを正しく入力したことを確認するには、パスワードを再入力する必要があります。
私は、ASP+ ページ フレームワークで動作するように最小限に変換された HTML ページから始めます。
ページを変換するプロセスには、次の手順が含まれます。
- 拡張子を ".html" または ".asp" から ".aspx" に変更します。
- フォームとすべての入力タグを "runat=server" に変更します。
- "name" の代わりに "ID" を使用します。
開始コード:
<html> <head> <title>Validation Sample</title> </head> <body> <form runat=server> <p>Please enter a new User ID and Password:</p> <table> <tr> <td>User ID:</td> <td><input type=text runat=server id=txtName></td> </tr> <tr> <td>Password:</td> <td><input type=password runat=server id=txtPWord></td> </tr> <tr> <td>Re-enter Password:</td> <td><input type=password runat=server id=txtRePWord></td> </tr> <table><br> <input type=submit runat=server id=cmdSubmit value=Submit> </form> </body> </html>
開始ページ:
それは自発的ではない
最初に強制する必要があるのは、フィールドがまったく入力されるということです。
各フィールドの前に、RequiredFieldValidator を追加します。 入力フィールドが空白の場合は、フィールドの前にアスタリスク (*) を表示し、サマリー領域にテキスト エラーを報告します。 RequiredFieldValidator を [ユーザー ID] フィールドに追加する方法を次に示します。
<tr> <td> <asp:RequiredFieldValidator runat=server ControlToValidate=txtName ErrorMessage="User ID is required."> * </asp:RequiredFieldValidator> </td> <td>User ID:</td> <td><input type=text runat=server id=txtName></td> </tr>
入力が空白の場合、ラベルの横に * が表示されます。 エラー メッセージが概要で報告されます。 "ControlToValidate" プロパティは、検証するコントロールの ID を指定します。 最後の手順では、次のように検証の概要をページの上部に追加します。
<asp:ValidationSummary runat=server HeaderText="There were errors on the page:" />
ページでの表示方法を次に示します。
通常の取得
次に、[ユーザー ID] フィールドと [パスワード] フィールドの文字要件を適用する必要があります。 ここでは、RegularExpressionValidator コントロールを使用します。 正規表現は、この種の情報のチェックと郵便番号、電話番号、電子メール アドレスを簡潔に表現する場合に非常に強力です。
ユーザー ID の制限を指定する方法を次に示します。
<td> <input type=text runat=server id=txtName> <asp:RegularExpressionValidator runat=server ControlToValidate="txtName" ErrorMessage="ID must be 6-10 letters." ValidationExpression="[a-zA-Z]{6,10}" /> </td>
この場合、タグ内の内部コンテンツは指定しなかったことに注意してください。 内部テキストは、コントロールの Text プロパティと同じです。 空白の場合は、コントロールが配置されている場所にエラー メッセージが表示され、概要にも表示されます。
パスワード チェックは、次の 2 つの検証コントロールで行うことができます。 複数を使用する場合は、入力が有効と見なされる前に、それらがすべて一致している必要があります。
<asp:RegularExpressionValidator runat=server display=dynamic ControlToValidate="txtPWord" ErrorMessage="Password must contain one of @#$%^&*/." ValidationExpression=".*[@#$%^&*/].*" /> <asp:RegularExpressionValidator runat=server display=dynamic ControlToValidate="txtPWord" ErrorMessage="Password must be 4-12 nonblank characters." ValidationExpression="[^\s]{4,12}" />
式を使用した動作中のフォームを次に示します。
Apple と Apple の比較
パスワードの再入力フィールドがパスワードと一致していることを確認する必要があります。 CompareValidator を使用してこれを行います。これは、一度に 2 つの入力コントロールを操作できるためです。
<asp:CompareValidator runat=server ControlToValidate=txtRePWord ControlToCompare=txtPWord ErrorMessage="Passwords do not match." />
既定では、CompareValidator は単純な文字列一致比較を行います。 必要に応じて、日付と数値を含むより複雑な比較を行うことができます。
ユーザー設定の自動調整
私たちがチェックする必要がある最後のことは、その名前がまだ仮定のサイトに入っていないということです。 これには、サーバー上のデータを確認する必要があります。 これをシミュレートするために、最初の文字が "a" ではないことを確認するダミー関数をサーバー側のコードに作成します。ページには、次の Visual Basic 関数が定義されています。
<%@ Page Language="vb" %> <script runat=server> public sub CheckID(source as Object, args as ServerValidateEventArgs) args.IsValid = args.Value.substring(0, 1).tolower() <> "a" end sub </script>
この関数を呼び出すために、開発者コードを呼び出してチェックを実行するように設計された CustomValidator を追加します。 宣言を次に示します。
<asp:CustomValidator runat=server controltovalidate="txtName" errormessage="ID is already in use." OnServerValidate="CheckID" />
スクリプトを使用するクライアントでは、送信を許可する前に、他のすべての検証コントロールが最初にクライアントでチェックを行います。 このようなサーバーのみのチェックでエラーが検出された場合は、それらのエラーを示すページがユーザーに送り返されます。
フィナーレ
ここで残っているのは、正常に検証されたデータを利用することです。 データベースの更新に進む場合は、Page の IsValid プロパティをチェックするだけで解決できます。 送信ハンドラーの外観を次に示します。
public sub OnSubmit(source as Object, e as EventArgs) if Page.IsValid then ' Now we can perform our transaction. end if end sub
ご覧のように、このハンドラーを使用すると、データ入力ページは、日常的な入力チェックを処理するコードでいっぱいになるのではなく、アプリケーションに固有のコードで構成されます。
最終的なページの動作を次に示します。
サンプル コード
<%@ Page Language="vb" %> <script runat=server> public sub CheckID(source as Object, args as ServerValidateEventArgs) args.IsValid = args.Value.substring(0, 1).tolower() <> "a" end sub public sub OnSubmit(source as Object, e as EventArgs) if Page.IsValid then ' Now we can perform our transaction. end if end sub </script> <html> <head> <title>Validation Sample</title> </head> <body> <form runat=server> <asp:ValidationSummary runat=server headertext="There were errors on the page:" /> <p>Please enter a User ID and Password:</p> <table> <tr> <td> <asp:RequiredFieldValidator runat=server controltovalidate=txtName errormessage="User ID is required.">* </asp:RequiredFieldValidator> </td> <td>User ID:</td> <td> <input type=text runat=server id=txtName> <asp:RegularExpressionValidator runat=server display=dynamic controltovalidate="txtName" errormessage="ID must be 6-10 letters." validationexpression="[a-zA-Z]{6,10}" /> <asp:CustomValidator runat=server controltovalidate="txtName" errormessage="ID is already in use." OnServerValidate="CheckID" /> </td> </tr> <tr> <td> <asp:RequiredFieldValidator runat=server controltovalidate=txtPWord errormessage="Password is required.">* </asp:RequiredFieldValidator> </td> <td>Password:</td> <td> <input type=password runat=server id=txtPWord> <asp:RegularExpressionValidator runat=server display=dynamic controltovalidate="txtPWord" errormessage="Password must contain one of @#$%^&*/." validationexpression=".*[@#$%^&*/].*" /> <asp:RegularExpressionValidator runat=server display=dynamic controltovalidate="txtPWord" errormessage="Password must be 4-12 nonblank characters." validationexpression="[^\s]{4,12}" /> </td> </tr> <tr> <td> <asp:RequiredFieldValidator runat=server controltovalidate=txtRePWord errormessage="Re-enter password is required.">* </asp:RequiredFieldValidator> </td> <td>Re-enter Password:</td> <td> <input type=password runat=server id=txtRePWord> <asp:CompareValidator runat=server controltovalidate=txtRePWord controltocompare=txtPWord errormessage="Passwords do not match." /> </td> </tr> </table><br> <input type=submit runat=server id=cmdSubmit value=Submit onserverclick=OnSubmit> </form> </body> </html>