データ検証注釈コントロールの検証 (C#)

by Microsoft

データ注釈モデル バインダーを利用して、ASP.NET MVC アプリケーション内で検証を実行します。 さまざまな種類のバリデーター属性を使用し、Microsoft Entity Framework でそれらを操作する方法について説明します。

このチュートリアルでは、データ注釈検証コントロールを使用して、ASP.NET MVC アプリケーションで検証を実行する方法について説明します。 データ注釈検証コントロールを使用する利点は、必須属性や StringLength 属性などの 1 つ以上の属性をクラス プロパティに追加するだけで検証を実行できる点です。

データ注釈モデル バインダーは、Microsoft ASP.NET MVC フレームワークの公式部分ではないことを理解しておくことが重要です。 データ注釈モデル バインダーは Microsoft ASP.NET MVC チームによって作成されましたが、Microsoft では、このチュートリアルで説明および使用されているデータ注釈モデル バインダーの公式製品サポートを提供していません。

データ注釈モデル バインダーの使用

ASP.NET MVC アプリケーションでデータ注釈モデル バインダーを使用するには、まず、Microsoft.Web.Mvc.DataAnnotations.dll アセンブリとSystem.ComponentModel.DataAnnotations.dll アセンブリへの参照を追加する必要があります。 メニュー オプション[ プロジェクト]、[参照の追加]を選択します。 次に、[ 参照 ] タブをクリックし、Data Annotations Model Binder サンプルをダウンロード (および解凍) した場所を参照します ( 図 1 を参照)。

[参照] タブの画像

図 1: データ注釈モデル バインダーへの参照の追加 (フルサイズの画像を表示する をクリックします)

Microsoft.Web.Mvc.DataAnnotations.dll アセンブリとSystem.ComponentModel.DataAnnotations.dll アセンブリの両方を選択し、[ OK] ボタンをクリックします。

データ注釈モデル バインダーと共に、.NET Framework Service Pack 1 に含まれるSystem.ComponentModel.DataAnnotations.dll アセンブリを使用することはできません。 Data Annotations Model Binder Sample ダウンロードに含まれているSystem.ComponentModel.DataAnnotations.dll アセンブリのバージョンを使用する必要があります。

最後に、DataAnnotations モデル バインダーを Global.asax ファイルに登録する必要があります。 Application_Start() メソッドが次のようになるように、Application_Start() イベント ハンドラーに次のコード行を追加します。

protected void Application_Start()
{
    RegisterRoutes(RouteTable.Routes);
    ModelBinders.Binders.DefaultBinder = new Microsoft.Web.Mvc.DataAnnotations.DataAnnotationsModelBinder();
}

このコード行は、ASP.NET MVC アプリケーション全体の既定のモデル バインダーとして ataAnnotationsModelBinder を登録します。

データ注釈バリデーター属性の使用

データ注釈モデル バインダーを使用する場合は、検証属性を使用して検証を実行します。 System.ComponentModel.DataAnnotations 名前空間には、次の検証属性が含まれています。

  • 範囲 – プロパティの値が指定した値の範囲の間にあるかどうかを検証できます。
  • RegularExpression – プロパティの値が指定した正規表現パターンと一致するかどうかを検証できます。
  • 必須 – プロパティを必須としてマークできます。
  • StringLength – 文字列プロパティの最大長を指定できます。
  • 検証 – すべてのバリデーター属性の基本クラス。

注意

検証のニーズが標準検証コントロールのいずれにも満たされない場合は、基本検証属性から新しい検証コントロール属性を継承してカスタム 検証コントロール属性を作成するオプションが常に用意されています。

リスト 1 の Product クラスは、これらのバリデーター属性を使用する方法を示しています。 Name、Description、UnitPrice プロパティは必須としてマークされます。 Name プロパティの文字列の長さは 10 文字未満である必要があります。 最後に、UnitPrice プロパティは、通貨額を表す正規表現パターンと一致する必要があります。

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace MvcApplication1.Models
{
    
    public class Product
    {
        public int Id { get; set; }

        [Required]
        [StringLength(10)]
        public string Name { get; set; }

        [Required]
        public string Description { get; set; }

        [DisplayName("Price")]
        [RegularExpression(@"^\$?\d+(\.(\d{2}))?$")]
        public decimal UnitPrice { get; set; }
    }
}

リスト 1: Models\Product.cs

Product クラスは、DisplayName 属性という 1 つの追加属性を使用する方法を示しています。 DisplayName 属性を使用すると、プロパティがエラー メッセージに表示されるときに、プロパティの名前を変更できます。 "UnitPrice フィールドは必須です" というエラー メッセージを表示する代わりに、"Price フィールドが必要です" というエラー メッセージを表示できます。

注意

検証コントロールによって表示されるエラー メッセージを完全にカスタマイズする場合は、次のように検証コントロールの ErrorMessage プロパティにカスタム エラー メッセージを割り当てることができます。 <Required(ErrorMessage:="This field needs a value!")>

リスト 1 の Product クラスは、リスト 2 の Create() コントローラー アクションで使用できます。 このコントローラー アクションは、モデルの状態にエラーが含まれている場合に、作成ビューを再表示します。

using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
    public class ProductController : Controller
    {
         //
        // GET: /Product/Create

        public ActionResult Create()
        {
            return View();
        } 

        //
        // POST: /Product/Create

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create([Bind(Exclude="Id")]Product productToCreate)
        {
            if (!ModelState.IsValid)
                return View();

            // TODO: Add insert logic here
            return RedirectToAction("Index");
        }

    }
}

リスト 2: Controllers\ProductController.vb

最後に、 リスト 3 でビューを作成するには、Create() アクションを右クリックし、メニュー オプションの [ビューの追加] を選択します。 Product クラスをモデル クラスとして使用して、厳密に型指定されたビューを作成します。 [コンテンツの表示] ドロップダウン リストから [ 作成 ] を選択します ( 図 2 を参照)。

[ビューの追加] ダイアログ ボックスの画像

図 2: 作成ビューの追加

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

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

    <h2>Create</h2>

    <%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %>

    <% 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="UnitPrice">Price:</label>
                <%= Html.TextBox("UnitPrice") %>
                <%= Html.ValidationMessage("UnitPrice", "*") %>
            </p>
            <p>
                <input type="submit" value="Create" />
            </p>
        </fieldset>

    <% } %>

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

</asp:Content>

リスト 3: Views\Product\Create.aspx

注意

[ ビューの追加 ] メニュー オプションによって生成された [作成] フォームから [ID] フィールドを削除します。 ID フィールドは ID 列に対応しているため、ユーザーがこのフィールドの値を入力できないようにします。

製品を作成するためのフォームを送信し、必要なフィールドの値を入力しない場合は、 図 3 の検証エラー メッセージが表示されます。

すべての検証エラーの画像

図 3: 必須フィールドがありません

無効な通貨金額を入力すると、 図 4 のエラー メッセージが表示されます。

無効な通貨検証エラーの画像

図 4: 通貨金額が無効です

Entity Framework でのデータ注釈バリデーターの使用

Microsoft Entity Framework を使用してデータ モデル クラスを生成する場合、バリデーター属性をクラスに直接適用することはできません。 Entity Framework Designer によってモデル クラスが生成されるため、モデル クラスに対して行った変更は、次回デザイナーで変更を加えた場合に上書きされます。

Entity Framework によって生成されたクラスでバリデーターを使用する場合は、メタデータ クラスを作成する必要があります。 検証コントロールは、実際のクラスに適用するのではなく、メタデータ クラスに適用します。

たとえば、Entity Framework を使用して Movie クラスを作成したとします ( 図 5 を参照)。 さらに、Movie Title プロパティと Director プロパティを必須プロパティにしたいとします。 その場合は、 リスト 4 で部分クラスとメタデータ クラスを作成できます。

ムービー クラスの画像

図 5: Entity Framework によって生成された Movie クラス

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace MvcApplication1.Models
{
    [MetadataType(typeof(MovieMetaData))]
    public partial class Movie
    {
    }

    public class MovieMetaData
    {
        [Required]
        public object Title { get; set; }

        [Required]
        [StringLength(5)]
        public object Director { get; set; }

        [DisplayName("Date Released")]
        [Required]
        public object DateReleased { get; set; }
    }

}

リスト 4: Models\Movie.cs

リスト 4 のファイルには、Movie と MovieMetaData という名前の 2 つのクラスが含まれています。 Movie クラスは部分クラスです。 これは、DataModel.Designer.vb ファイルに含まれる Entity Framework によって生成された部分クラスに対応します。

現在、.NET Framework は部分プロパティをサポートしていません。 したがって、 リスト 4 のファイルで定義されている Movie クラスのプロパティに検証コントロール属性を適用することで、DataModel.Designer.vb ファイルで定義されている Movie クラスのプロパティに検証コントロール属性を適用する方法はありません。

Movie 部分クラスは、MovieMetaData クラスを指す MetadataType 属性で装飾されていることに注意してください。 MovieMetaData クラスには、Movie クラスのプロパティのプロキシ プロパティが含まれています。

検証コントロールの属性は、MovieMetaData クラスのプロパティに適用されます。 Title、Director、DateReleased プロパティはすべて、必須プロパティとしてマークされます。 Director プロパティには、5 文字未満の文字列を割り当てる必要があります。 最後に、DisplayName 属性が DateReleased プロパティに適用され、"DateReleased フィールドが必要です" というエラーではなく、"リリース日フィールドが必要です" のようなエラー メッセージが表示されます。

注意

MovieMetaData クラスのプロキシ プロパティは、Movie クラスの対応するプロパティと同じ型を表す必要はありません。 たとえば、Director プロパティは Movie クラスの文字列プロパティ、MovieMetaData クラスのオブジェクト プロパティです。

図 6 のページは、Movie プロパティに無効な値を入力したときに返されるエラー メッセージを示しています。

無効なムービー値のエラー メッセージの画像

図 6: Entity Framework で検証コントロールを使用する (フルサイズの画像を表示する をクリックします)

まとめ

このチュートリアルでは、データ注釈モデル バインダーを利用して、ASP.NET MVC アプリケーション内で検証を実行する方法について説明しました。 Required 属性や StringLength 属性など、さまざまな種類のバリデーター属性を使用する方法を学習しました。 また、Microsoft Entity Framework を使用するときにこれらの属性を使用する方法についても学習しました。