ホーム > .NET, ASP.NET 備忘録 > EnabelDynamicDataで簡単データ検証(LINQ to SQL 編)

EnabelDynamicDataで簡単データ検証(LINQ to SQL 編)

.NET Framework 4ではDataAnnotationによるデータ検証が様々なところで使えるようになっています。
WebフォームではDynamicDataプロジェクトの中であればこのDataAnnotationによるデータ検証が使えましたが、そのためだけにDynamicDataプロジェクトを採用するのはちょっとおおげさな感じでした。

ASP.NET 4ではEnableDynamicDataという拡張メソッドが導入され、簡単にデータ検証を設定することができるようになっています。
この記事ではLINQ to SQLクラスをベースに、GridViewとDetailsViewを使ったサイト構築に簡単にデータ検証を追加する方法をまとめています。

用意したテーブルは以下のような定義になっています。

Table

ここから作成したLINQ to SQLクラスはこのようになります。

L2Sclass

新規にクラスファイルを追加し、下記の内容を記述します。
LINQ to SQLクラスにMetaDataクラスを関連づけています。

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

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

[MetadataType(typeof(MetaPerson))]
public partial class Person
{
    partial void OnValidate(System.Data.Linq.ChangeAction action)
    {
        if (age >= 20 && mail == null)
            throw new ValidationException("成人はメールアドレス必須です");
    }
}

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;
    }
}

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

Default.aspxにはGridViewとLinqDataSourceの設定(とValidation関係の設定をちょっと)を行います。
以下のように記述します。

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

<%@ 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="LinqDataSource1">
            <Columns>
                <asp:CommandField ShowEditButton="True" />
            </Columns>
        </asp:GridView>
        <asp:LinqDataSource ID="LinqDataSource1" runat="server"
            ContextTypeName="DataClassesDataContext" EnableDelete="True"
            EnableInsert="True" EnableUpdate="True" EntityTypeName="" TableName="Person">
        </asp:LinqDataSource>
    </div>
    </form>
</body>
</html>

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

GridViewに対してウィザードでLinqDataSourceを追加していくと、デフォルトではGridView内に各項目の定義が自動的に追加されてしまいます。
ここは必要ないので削除し、自動的に項目が追加されるようにしておきます。

Default.aspx.csクラスにはEnableDynamicDataの記述を行います。
GridViewに対してプログラムを記述するのはこの部分だけです。

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

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(Person));
    }
    protected void Page_Load(object sender, EventArgs e)
    {

    }
}

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

さて、これで動かしてみましょう。

GridView検証テスト1

MetaDataクラスの中で設定した検証ルールが適用されていることがわかります。

GridView検証テスト2

DataAnnotationでは、予め用意されている検証方法の他に、CustomValidationという形で自分で検証内容を作成し、適用することができます。
上記でこのCustomValidationが正しく動作していることが確認できます。

GridView検証テスト3

クラス内の項目間の関連をチェックする検証はCustomValidationを使っても設定できないようです。
CustomValidationはクラスに対して設定することができる属性なのですが、GridViewとEnableDynamicDataの組み合わせではどうもクラスに設定したCustomValidationをチェックしてくれません。
なので、ここではLINQ to SQLクラスのOnValidateパーシャルメソッドを記述し、ValidationExceptionをDynamicValidatorに拾わせることで検証を行っています。

GridViewではデータの追加はできませんから、データ追加のためのDetailsViewをDefault2.aspxに設定します。

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

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

<!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="DetailsView1" Display="None" />
        <asp:DetailsView ID="DetailsView1" runat="server" DataKeyNames="id"
            DataSourceID="LinqDataSource1" DefaultMode="Insert">
            <Fields>
                <asp:CommandField ShowInsertButton="True" />
            </Fields>
        </asp:DetailsView>
        <asp:LinqDataSource ID="LinqDataSource1" runat="server"
            ContextTypeName="DataClassesDataContext" EnableDelete="True"
            EnableInsert="True" EnableUpdate="True" EntityTypeName="" TableName="Person">
        </asp:LinqDataSource>
    </div>
    </form>
</body>
</html>

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

Default2.aspx.csはこんなふうになります。

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

using System;
using System.Web.UI;

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

    }
}

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

これでDefault2.aspxを動かすと、検証機能が正しく動作することがわかります。

DetailsView検証テスト1

DetailsView検証テスト2

DetailsView検証テスト3

検証ルールは一箇所に書いてあるだけなのに、Default.aspx、Default2.aspxの2つのページで同じ検証が実行されます。
GridViewやDetailsViewにValidationコントローラを埋め込む作業も要りません。
うまく使えると便利な機能なんじゃないでしょうか。

このサンプルを動作させてみるとわかりますが、実はエラーチェックの実行順序等に癖(といっていいのかな?)があり、広く一般に使ってもらうサイトには向かないかもしれません。
ただ、イントラネット内で動作させるプログラムを作るといった限定的なところでは使えるんじゃないでしょうか。

特に検証ルールを後から追加したり変更したりするのが楽なので、とにかく動くものを提供してだんだん作りこんでいくといった方法がとりやすい気がします。

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

コメントを残す

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

WordPress.com ロゴ

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

Twitter 画像

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

Facebook の写真

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

Google+ フォト

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

%s と連携中

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