簡易検証を実行する (C#)

作成者: Stephen Walther

ASP.NET MVC アプリケーションで検証を実行する方法について説明します。 このチュートリアルでは、Stephen Walther がモデルの状態と検証 HTML ヘルパーについて説明します。

このチュートリアルの目的は、ASP.NET MVC アプリケーションで検証を実行する方法を説明することです。 たとえば、必須フィールドの値を含まないフォームを送信できないようにする方法について説明します。 モデルの状態と検証 HTML ヘルパーを使用する方法について説明します。

モデルの状態について

検証エラーを表すために、モデルの状態 (正確には、モデルの状態ディクショナリ) を使用します。 たとえば、リスト 1 の Create() アクションは、Product クラスをデータベースに追加する前に Product クラスのプロパティを検証します。

検証またはデータベース ロジックをコントローラーに追加することはお勧めしません。 コントローラーには、アプリケーション フロー制御に関連するロジックのみを含める必要があります。 簡単な方法で、物事をシンプルに保つようにします。

リスト 1 - Controllers\ProductController.cs

//
// POST: /Product/Create

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude="Id")] Product productToCreate)
{
    // Validation logic
    if (productToCreate.Name.Trim().Length == 0)
        ModelState.AddModelError("Name", "Name is required.");
    if (productToCreate.Description.Trim().Length == 0)
        ModelState.AddModelError("Description", "Description is required.");
    if (productToCreate.UnitsInStock

リスト 1 では、Product クラスの Name、Description、UnitsInStock プロパティが検証されます。 これらのプロパティのいずれかが検証テストに失敗した場合、エラーがモデルの状態ディクショナリに追加されます (Controller クラスの ModelState プロパティで表されます)。

モデルの状態にエラーがある場合、ModelState.IsValid プロパティは false を返します。 その場合、新しい製品を作成するための HTML フォームが再表示されます。 再表示されず、検証エラーがない場合は、新しい製品がデータベースに追加されます。

検証ヘルパーの使用

ASP.NET MVC フレームワークには、Html.ValidationMessage() ヘルパーと Html.ValidationSummary() ヘルパーの 2 つの検証ヘルパーが存在します。 検証エラー メッセージを表示するには、ビューでこれら 2 つのヘルパーを使用します。

Html.ValidationMessage() および Html.ValidationSummary() ヘルパーは、ASP.NET MVC スキャフォールディングによって自動的に生成される作成ビューと編集ビューで使用されます。 作成ビューを生成するには、次の手順に従います。

  1. Product コントローラーで Create() アクションを右クリックし、メニュー オプションの[ビューの追加] を選択します (図 1 を参照)。
  2. [ビューの追加] ダイアログで、[厳密に型指定されたビューを作成する] というラベルが付いたチェックボックスをオンにします (図 2 を参照)。
  3. [データ クラスの表示] ドロップダウン リストから、Product クラスを選択します。
  4. [ビュー コンテンツ] ドロップダウン リストから、[Create] を選択します。
  5. [追加] をクリックします。

ビューを追加する前に、必ずアプリケーションをビルドしてください。 そうしないと、[データ クラスの表示] ドロップダウン リストにクラスのリストが表示されません。

Screenshot of the Product Controller dot c s file in the code editor, which shows the right-click menu with the highlighted Add View menu item.

図 01: ビューの追加 (クリックするとフルサイズの画像が表示されます)

Screenshot of the Add View dialog box, which shows that the Create a strongly-typed view checkbox is filled.

図 02: 厳密に型指定されたビューの作成 (クリックするとフルサイズの画像が表示されます)

これらの手順を完了すると、リスト 2 の [Create] ビューが表示されます。

リスト 2 - Views\Product\Create.aspx

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcApplication1.Models.Product>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<title>Create</title>
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Create</h2>

    <%= Html.ValidationSummary() %>

    <% using (Html.BeginForm()) {%>

        <fieldset>
            <legend>Fields</legend>
            <p>
                <label for="Name">Name:</label>
                <%= Html.TextBox("Name") %>
                <%= Html.ValidationMessage("Name", "*") %>
            </p>
            <p>
                <label for="Description">Description:</label>
                <%= Html.TextBox("Description") %>
                <%= Html.ValidationMessage("Description", "*") %>
            </p>
            <p>
                <label for="Price">Price:</label>
                <%= Html.TextBox("Price") %>
                <%= Html.ValidationMessage("Price", "*") %>
            </p>
            <p>
                <label for="UnitsInStock">UnitsInStock:</label>
                <%= Html.TextBox("UnitsInStock") %>
                <%= Html.ValidationMessage("UnitsInStock", "*") %>
            </p>
            <p>
                <input type="submit" value="Create" />
            </p>
        </fieldset>

    <% } %>

    <div>
        <%=Html.ActionLink("Back to List", "Index") %>
    </div>

</asp:Content>

リスト 2 では、HTML.ValidationSummary() ヘルパーが HTML フォームのすぐ上に呼び出されます。 このヘルパーは、検証エラー メッセージの一覧を表示するために使用されます。 Html.ValidationSummary() ヘルパーは、箇条書きのエラーをレンダリングします。

Html.ValidationMessage() ヘルパーは、各 HTML フォーム フィールドの横に呼び出されます。 このヘルパーは、フォーム フィールドの横にエラー メッセージを表示するために使用されます。 リスト 2 の場合、エラーが発生すると Html.ValidationMessage() ヘルパーにアスタリスクが表示されます。

図 3 のページは、フィールドに値が指定されていなかったり、無効な値が指定されていたりする状態でフォームが送信されたときに、検証ヘルパーによってレンダリングされるエラー メッセージを示しています。

Screenshot of the Internet Explorer window, which shows the Create view with error messages resulting from fields filled with invalid values.

図 03: 問題が発生して送信された [Create] ビュー (クリックするとフルサイズの画像が表示されます)

検証エラーが発生すると、HTML 入力フィールドの外観も変ります。 Html.TextBox() ヘルパーによってレンダリングされるプロパティに関連付けられた検証エラーがある場合、Html.TextBox() ヘルパーは class="input-validation-error" 属性をレンダリングします。

検証エラーの外観を制御するために使用される 3 つのカスケード スタイル シート クラスがあります。

  • input-validation-error - Html.TextBox() ヘルパーによってレンダリングされる <input> タグに適用されます。
  • field-validation-error - Html.ValidationMessage() ヘルパーによってレンダリングされる <span> タグに適用されます。
  • validation-summary-errors - Html.ValidationSummary() ヘルパーによってレンダリングされた <ul> タグに適用されます。

これらのカスケード スタイル シート クラスを変更し、コンテンツ フォルダーにある Site.css ファイルを変更することで、検証エラーの外観を変更できます。

Note

HtmlHelper クラスには、検証に関連する CSS クラスの名前を取得するための読み取り専用の静的プロパティが含まれています。 これらの静的プロパティは、ValidationInputCssClassName、ValidationFieldCssClassName、ValidationSummaryCssClassName という名前です。

事前バインドの検証と事後バインドの検証

Product を作成するための HTML フォームを送信し、価格フィールドに無効な値を入力し、UnitsInStock フィールドに値を入力しないと、図 4 のような検証メッセージが表示されます。 これらの検証エラー メッセージはどこから来るのでしょうか。

Screenshot of the Internet Explorer window, which shows the Price and Units in Stock fields are flagging validation errors.

図 04: 検証エラーの事前バインド (クリックするとフルサイズの画像が表示されます)

実際には、HTML フォーム フィールドがクラスにバインドされる前に生成された検証エラー メッセージと、フォーム フィールドがクラスにバインドされた後に生成される検証エラー メッセージの 2 種類があります。 つまり、事前バインド検証エラーと事後バインド検証エラーがあります。

リスト 1 の Product コントローラーによって公開される Create() アクションは、Product クラスのインスタンスを受け入れます。 Create メソッドのシグネチャは次のようになります。

public ActionResult Create([Bind(Exclude="Id")] Product productToCreate)

Create フォームの HTML フォーム フィールドの値は、モデル バインダーと呼ばれるものによって productToCreate クラスにバインドされます。 既定のモデル バインダーは、フォーム フィールドをフォーム プロパティにバインドできない場合に、エラー メッセージをモデルの状態に自動的に追加します。

既定のモデル バインダーは、文字列 "apple" を Product クラスの Price プロパティにバインドできません。 10 進数のプロパティに文字列を割り当てることはできません。 そのため、モデル バインダーは、エラーをモデルの状態に追加します。

既定のモデル バインダーでは、null 値を受け入れないプロパティに null 値を割り当てることはできません。 特に、モデル バインダーは UnitsInStock プロパティに null 値を割り当てることができません。 もう一度、モデル バインダーは放棄し、エラー メッセージをモデルの状態に追加します。

これらの事前バインド エラー メッセージの外観をカスタマイズする場合は、これらのメッセージのリソース文字列を作成する必要があります。

まとめ

このチュートリアルでは、ASP.NET MVC フレームワークでの検証の基本的なメカニズムについて説明しました。 モデルの状態と検証 HTML ヘルパーを使用する方法について学習しました。 また、事前バインドと事後バインドの検証の違いについても説明しました。 その他のチュートリアルでは、コントローラーからモデル クラスに検証コードを移動するためのさまざまな戦略について説明します。