チュートリアル: ASP.NET MVC アプリを使用して EF Database First のデータ検証を強化する

MVC、Entity Framework、ASP.NET スキャフォールディングを使用して、既存のデータベースへのインターフェイスを提供する Web アプリケーションを作成できます。 このチュートリアル シリーズでは、ユーザーがデータベース テーブル内に存在するデータを表示、編集、作成、削除できるようにするコードを自動的に生成する方法について説明します。 生成されたコードは、データベース テーブル内の列に対応します。

このチュートリアルでは、データ モデルにデータ注釈を追加して、検証要件と表示書式を指定することに重点を置いています。 これは、コメント セクション内のユーザーからのフィードバックに基づいて改善されました。

このチュートリアルでは、次の作業を行いました。

  • データ注釈を追加する
  • メタデータ クラスを追加する

前提条件

データ注釈を追加する

前のトピックで確認したように、一部のデータ検証規則はユーザーによる入力に自動的に適用されます。 たとえば、Grade プロパティには数字のみを指定できます。 さらに多くのデータ検証規則を指定するには、モデル クラスにデータ注釈を追加できます。 これらの注釈は、指定したプロパティに対して、その Web アプリケーション全体に適用されます。 プロパティの表示方法を変更する書式属性を適用することもできます (テキスト ラベルに使用される値の変更、など)。

このチュートリアルでは、データ注釈を追加して、FirstName、LastName、MiddleName プロパティに指定される値の長さを制限します。 データベース内では、これらの値は 50 文字に制限されています。ただし、Web アプリケーション内に、その文字制限は現在適用されていません。 ユーザーがそれらの値の 1 つを 50 文字より多く指定した場合、その値をデータベースに保存しようとするとページがクラッシュします。 また、Grade を 0 から 4 の値に制限します。

Models>ContosoModel.edmx>ContosoModel.tt を選択し、Student.cs ファイルを開きます。 次の強調表示されたコードをクラスに追加します。

namespace ContosoSite.Models
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    public partial class Student
    {
        public Student()
        {
            this.Enrollments = new HashSet<Enrollment>();
        }
    
        public int StudentID { get; set; }
        [StringLength(50)]
        public string LastName { get; set; }
        [StringLength(50)]
        public string FirstName { get; set; }
        public Nullable<System.DateTime> EnrollmentDate { get; set; }
        [StringLength(50)]
        public string MiddleName { get; set; }
    
        public virtual ICollection<Enrollment> Enrollments { get; set; }
    }
}

Enrollment.cs を開き、次の強調表示されたコードを追加します。

namespace ContosoSite.Models
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    public partial class Enrollment
    {
        public int EnrollmentID { get; set; }
        [Range(0, 4)]
        public Nullable<decimal> Grade { get; set; }
        public int CourseID { get; set; }
        public int StudentID { get; set; }
    
        public virtual Course Course { get; set; }
        public virtual Student Student { get; set; }
    }
}

ソリューションをビルドします。

[List of students] をクリックし、[Edit] を選択します。 50 文字より多く入力しようとすると、エラー メッセージが表示されます。

show error message

ホーム ページに戻ります。 [List of enrollments] をクリックし、[Edit] を選択します。 4 より大きい Grade を指定しようとします。 次のエラーが表示されます。The field Grade must be between 0 and 4.

メタデータ クラスを追加する

検証属性をモデル クラスに直接追加することは、データベースへの変更を想定しない場合にはうまくいきます。ただし、データベースが変更され、モデル クラスを再生成する必要がある場合は、そのモデル クラスに適用したすべての属性が失われます。 このアプローチは非常に効率が悪く、重要な検証規則が失われる傾向があります。

この問題を回避するには、属性を含むメタデータ クラスを追加できます。 モデル クラスをメタデータ クラスに関連付けると、それらの属性がモデルに適用されます。 このアプローチでは、メタデータ クラスに適用されたすべての属性を失わずに、モデル クラスを再生成できます。

Models フォルダー内に、Metadata.cs という名前のクラスを追加します。

Metadata.cs 内のコードを次のコードに置き換えます。

using System;
using System.ComponentModel.DataAnnotations;

namespace ContosoSite.Models
{
    public class StudentMetadata
    {
        [StringLength(50)]
        [Display(Name="Last Name")]
        public string LastName;

        [StringLength(50)]
        [Display(Name="First Name")]
        public string FirstName;

        [StringLength(50)]
        [Display(Name="Middle Name")]
        public string MiddleName;

        [Display(Name = "Enrollment Date")]
        public Nullable<System.DateTime> EnrollmentDate;
    }

    public class EnrollmentMetadata
    {
        [Range(0, 4)]
        public Nullable<decimal> Grade;
    }
}

これらのメタデータ クラスには、以前にモデル クラスに適用したすべての検証属性が含まれています。 Display 属性は、テキスト ラベルに使用される値を変更するために使用されます。

ここで、モデル クラスをメタデータ クラスに関連付ける必要があります。

Models フォルダー内に、PartialClasses.cs という名前のクラスを追加します。

このファイルの内容を次のコードに置き換えます。

using System;
using System.ComponentModel.DataAnnotations;

namespace ContosoSite.Models
{
    [MetadataType(typeof(StudentMetadata))]
    public partial class Student
    {
    }

    [MetadataType(typeof(EnrollmentMetadata))]
    public partial class Enrollment
    {
    }
}

各クラスが partial クラスとしてマークされ、それぞれが自動的に生成されるクラスの名前および名前空間と一致することに注目してください。 メタデータ属性を部分クラスに適用することで、データ検証属性が自動的に生成されたクラスに確実に適用されるようになります。 メタデータ属性は再生成されない部分クラス内に適用されるため、モデル クラスを再生成しても、これらの属性は失われません。

自動生成されたクラスを再生成するには、ContosoModel.edmx ファイルを開きます。 もう一度、デザイン サーフェイス上で右クリックし、[データベースからモデルを更新] を選択します。 データベースを変更していない場合でも、このプロセスによってクラスが再生成されます。 [更新] タブ内で、[テーブル][完了] を選択します。

ContosoModel.edmx ファイルを保存して、変更を適用します。

Student.cs ファイルまたは Enrollment.cs ファイルを開くと、前に適用したデータ検証属性がファイルの中にもう存在しないことがわかります。 ただし、アプリケーションを実行してデータを入力すると、検証規則がまだ適用されることに注目してください。

まとめ

このシリーズでは既存のデータベースから、ユーザーがデータを編集、更新、作成、削除できるようにするコードを生成する方法の簡単な例を示しました。 ASP.NET MVC 5、Entity Framework、ASP.NET スキャフォールディングを使用してプロジェクトを作成しました。

Code First 開発の入門的な例については、「ASP.NET MVC 5 の概要」を参照してください。

さらに高度な例については、ASP.NET MVC 4 アプリの Entity Framework データ モデルを作成するを参照してください。 Database First でデータを操作するために使用する DbContext API は、Code First でデータを操作するために使用する API と同じであることに注目してください。 Database First を使用するつもりの場合でも、関連するデータの読み取りと更新、コンカレンシーの競合の処理など、より複雑なシナリオに対応する方法を、Code First のチュートリアルから学習できます。 唯一の違いは、データベース、コンテキスト クラス、エンティティ クラスの作成方法です。

その他のリソース

プロパティとクラスに適用できるデータ検証注釈の全一覧については、「System.ComponentModel.DataAnnotations」を参照してください。

次のステップ

このチュートリアルでは、次の作業を行いました。

  • データ注釈を追加しました
  • メタデータ クラスを追加しました

Web アプリと SQL データベースを Azure App Service にデプロイする方法については、次のチュートリアルを参照してください。