ホーム > .NET, ASP.NET 備忘録 > EnableDynamicDataで簡単データ検証(Entity Data Model編)

EnableDynamicDataで簡単データ検証(Entity Data Model編)

LINQ to SQL編と同様のことをEntity Data Modelを使うとどう記述するのか、という部分をまとめます。
利用したテーブルの定義と動き方はLINQ to SQL編を参考にしてください。

作成したEntity Data Model(以下EDM)は次のようになります。

EntityDataModel

ここでMetaDataを関連づけたり、クラス内の項目間の関連チェックを行うには、以下のようなソースを記述する必要があります。

——————————————————————————————————————-

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Data.Objects;

namespace DatabaseModel
{
    public partial class DatabaseEntities
    {
        partial void OnContextCreated()
        {
            this.SavingChanges += new System.EventHandler(OnSavingChanges);
        }

        public void OnSavingChanges(object sender, System.EventArgs e)
        {
            var stateManager = ((DatabaseEntities)sender).ObjectStateManager;
            var changedEntities = ObjectStateManager.GetObjectStateEntries(EntityState.Modified | EntityState.Added);

            foreach (ObjectStateEntry stateEntryEntity in changedEntities)
            {
                if (stateEntryEntity.Entity is Person)
                {
                    Person p = (Person)stateEntryEntity.Entity;
                    if (p.age >= 20 && p.mail == null)
                        throw new ValidationException("成人はメールアドレス必須です");
                }
            }
        }
    }

    [MetadataType(typeof(MetaPerson))]
    public partial class Person
    {
    }

    public class MetaPerson
    {
        [Editable(false)]
        [DisplayName("ユーザID")]
        public int id { get; set; }

        [Required(ErrorMessage = "名前は必須項目です")]
        [DisplayName("名前")]
        public string name { get; set; }

        [DisplayName("年齢")]
        [Required(ErrorMessage = "年齢は必須項目です")]
        [Range(0, 120, ErrorMessage = "年齢に誤りがあります")]
        public int age { get; set; }

        [DisplayName("メールアドレス")]
        [RegularExpression(@"\w+([-+.’]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*", ErrorMessage = "正しいメールアドレスを入力してください")]
        public string mail { get; set; }

        [DisplayName("備考")]
        [CustomValidation(typeof(MetaPerson), "CheckMinLength")]
        public string memo { get; set; }

        public static ValidationResult CheckMinLength(string memo, ValidationContext vCont)
        {
            if (memo == null || memo.Length < 5)
                return new ValidationResult("5文字以上入力入力してください");
            return ValidationResult.Success;
        }
    }
}

——————————————————————————————————————-

EDMを生成すると、namespace(ここではDatabaseModel)が設定されることに注意する必要があります。
また、LINQ to SQLでは項目間のチェックはOnvalidateパーシャルメソッドを記述するだけでよかったのですが、EDMでは独自のイベントを追加する記述が必要です。
この部分の書き方はMSDNの「方法:データモデルのデータフィールド検証をカスタマイズする」ページを参考にしています。

Default.aspxページは以下のようになります。

——————————————————————————————————————-

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head runat="server">
    <title></title>
    <style type="text/css">
        .DDControl
        {
            color: Red;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ValidationSummary ID="ValidationSummary1" runat="server"
            CssClass="DDControl" />
        <asp:DynamicValidator ID="DynamicValidator1" runat="server"
            ControlToValidate="GridView1" Display="None" />
        <asp:GridView ID="GridView1" runat="server" DataKeyNames="id"
            DataSourceID="EntityDataSource1">
            <Columns>
                <asp:CommandField ShowEditButton="True" />
            </Columns>
        </asp:GridView>
        <asp:EntityDataSource ID="EntityDataSource1" runat="server" EnableDelete="True"
            EnableFlattening="False" EnableInsert="True" EnableUpdate="True"
            EntitySetName="Person" ContextTypeName="DatabaseModel.DatabaseEntities">
        </asp:EntityDataSource>
    </div>
    </form>
</body>
</html>

——————————————————————————————————————-

実はここですごいはまりました。
EDMに追加したOnSavingChangesメソッドがどうやっても呼び出されないのです。
で、いろいろ検索してみたところ、このページが見つかりました。
ウィザードから作成したEntityDataSourceではDefaultContainerNameプロパティとConnectionStringプロパティが設定されているのですが、この設定を使うかわりにContextTypeNameプロパティを利用して使用するEDMの完全修飾型名を指定する必要があったんですね。
上記のソースはこのContextTypeNameを利用しています。

Default.aspx.csはLINQ to SQLとほぼ変わりません。
が、namespaceが設定されている点にだけ注意が必要です。

——————————————————————————————————————-

using System;
using System.Web.UI;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Init(object sender, EventArgs e)
    {
        GridView1.EnableDynamicData(typeof(DatabaseModel.Person));
    }
    protected void Page_Load(object sender, EventArgs e)
    {

    }
}

——————————————————————————————————————-

Default2.aspxのほうは同じ点に気をつけてソースを見てもらえばいいですね。

カテゴリー:.NET, ASP.NET 備忘録
  1. まだコメントはありません。
  1. No trackbacks yet.

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。