2015年12月02日

EntityFramework(21): DataAnnotationsによるデータの検証

  
「データベースからCode First」でPOCOクラスを自動生成すると、テーブル定義にしたがって 以下のような属性が付加されます。

        [Required]
        [StringLength(40)]
        public string ProductName { get; set; }


Required、StringLength は、System.ComponentModel.DataAnnotations 名前空間に 定義されている属性で、これをデータ注釈と呼んでいます。
このデータ注釈は、SaveChangesメソッドを呼び出した時の検証として利用される ものがあります。
代表的な検証用属性としては以下のようなものがあります。

Required
そのフィールドに値が設定されているかを検証

StringLength
文字列の長さが指定文字数以内かを検証

RegularExpression
文字列が正規表現パターンpatternにマッチするかを検証

Range
指定した最小値と最大値の範囲内にあるかを検証

Compare
指定したプロパティと同じ値かを検証

EmailAddress
電子メールアドレスかどうかを化粧


▪️実際の定義例

        [Required]
        [StringLength(40)]
        public string CompanyName { get; set; }

        [Range(1,9999)]
        public int ProductType { get; set; }

        [RegularExpression(@"\d{3}\-\d{4}")]
        public string PostalCode { get; set; }

        [Required]
        [EmailAddress()]
        public string EmailAddress { get; set; }

        [Compare("EmailAddress")]
        public string  VerifiedEmailAddress { get; set; }
 


では、実際に検証エラーを起こしてみましょう。

            using (var db = new NorthwindContext()) {
                Category cat = new Category {
                    CategoryName = "longest Category Name",
                    Description = "salad, croquette, tempura, cooked beans",
                };
                db.Categories.Add(cat);
                db.SaveChanges();
            }

CategoryNameには、 [StringLength(15)] と検証属性が付加されているので、 上のコードを実行すると、検証例外 System.Data.Entity.Validation.DbEntityValidationException が発生します。
では、どのプロパティでどんな検証エラーが発生したのかはどうやって知るのか?

この例外オブジェクトのMessageプロパティには

”1 つ以上のエンティティで検証が失敗しました。詳細については 'EntityValidationErrors' プロパティを参照してください。”

というメッセージが設定されています。でも、このEntityValidationErrorsの値って、Visual Studioのデバッガーでは 中身を確認することができません。(僕の確認の方法が悪いのかな?)

以下のようなコードを書けば、中身を確認できます。


     try {
         ...
         db.SaveChanges();
     } catch (DbEntityValidationException ex) {
         PrintEntityValidationErrors(ex.EntityValidationErrors);
     }
 ...
 
 private static void   PrintEntityValidationErrors(IEnumerable<DbEntityValidationResult> entityValidationErrors) {
     foreach (var er in entityValidationErrors) {
         foreach (var item in er.ValidationErrors) {
             Console.WriteLine("{0}:{1}", item.PropertyName, item.ErrorMessage);
         }
     }
 }




 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/52442247