.NET Developer Empire

帝国の逆襲

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  15  : 記事  5  : コメント  48  : トラックバック  8

記事カテゴリ

書庫

EnterpriseLibrary3.1のValidation Application Blockで、構成ファイルから入力値検証ルールを設定する方法を、簡単なサンプルで解説します。

構成ファイルを使った入力値検証

まずは完成系です。DataGridViewには型付データセットがバインドされています。DataGridViewに値を入力してValidateボタンを押下すると、それぞれの項目に検証がかけられて、エラーがあればそれを表示するというサンプルです。

データベースから値を取得して、それを編集してまた戻すというような状況では、VABの構成ファイルを使った検証が便利です。属性を使った検証では、検証対象クラスのメソッドやプロパティに属性を設定しなければなりませんが、DataSetのように自動生成されてしまうコードの中に属性を設定することは現実的ではありません。そこで、この構成ファイルを使った検証が利用できるのです。

ここでは、構成ファイルを使った入力値検証の概要を紹介します。

ソリューション構成

ソリューション構成はこんな感じ。

  • 新規作成
    • CustomerDs.xsd
    • ConfigDsForm.cs
    • Validation.config
  • 編集
    • App.config

参照設定で、Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WinFormsはここでは不要です。

1. CustomerDs.xsd

いたって普通の型付データセットです。

  • CustomerTable
    • FirstName ・・・ System.String
    • LastName ・・・ System.String
    • DateOfBirth ・・・ System.DateTime
    • EMail ・・・ System.String
    • RewardPoints ・・・ System.Int32

2. App.config

続いてApp.configの設定です。EnterpriseLibraryでは構成ファイルを読み込むための共通モジュールとして、「Microsoft.Practices.EnterpriseLibrary.Common.dll」を利用しています。これを使うための設定が、<configSections>要素以下の設定です。

実際に入力値検証ルールを設定する構成ファイルのパスは、<enterpriseLibrary.ConfigurationSource>要素で指定します。

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

        <configSections>

                <section name="enterpriseLibrary.ConfigurationSource"

                         type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ConfigurationSourceSection, Microsoft.Practices.EnterpriseLibrary.Common" />

        </configSections>

        <enterpriseLibrary.ConfigurationSource selectedSource="File Configuration Source">

                <sources>

                        <add name="File Configuration Source"

                             type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.FileConfigurationSource, Microsoft.Practices.EnterpriseLibrary.Common"

                             filePath="..\..\Validation.config" />

                </sources>

        </enterpriseLibrary.ConfigurationSource>

</configuration>

!!注意!!

App.configでは、入力値検証ルールを設定する構成ファイルは1つしか指定できません。規模の小さい開発なら入力値検証ルール構成ファイル1つでも対応できるかもしれませんが、規模が大きくなればなるほど、1つの構成ファイルで全ての検証ルールを設定する事は難しくなります。

そんなときは、ValidationFactoryからValidatorを生成するときに、ValidationFactory.CreateValidator<T>(String, IConfigurationSource)メソッドを使ってください。IConfigurationSourceを実装したFileConfigurationSourceのインスタンスを自分で作成し、それをCreateValidatorの引数に渡す事で、任意の構成ファイルからValidatorを生成できます。

3. Validation.config

入力値検証ルールを設定した構成ファイルです。ここでは、以下のようなものを作りました。

<?xml version="1.0" encoding="utf-8"?>

<configuration>

  <configSections>

    <section name="validation" type="Microsoft.Practices.EnterpriseLibrary.Validation.Configuration.ValidationSettings, Microsoft.Practices.EnterpriseLibrary.Validation, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />

    <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />

  </configSections>

  <validation>

    <type assemblyName="ValidationABSample" name="ValidationABSample.DataSet.CustomerDs+CustomerTableRow">

      <ruleset name="RuleSetC">

        <properties>

          <property name="DateOfBirth">

            <validator lowerBound="1969-01-01" lowerBoundType="Inclusive"

              upperBound="" upperBoundType="Ignore" negated="false" messageTemplate="Must be born after 1969"

              messageTemplateResourceName="" messageTemplateResourceType=""

              tag="" type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.DateTimeRangeValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

              name="Date Range Validator" />

          </property>

          <property name="EMail">

            <validator pattern="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"

              options="None" patternResourceName="" patternResourceType=""

              messageTemplate="Invalid e-mail address" messageTemplateResourceName=""

              messageTemplateResourceType="" tag="" type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.RegexValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

              name="Regex Validator" />

          </property>

          <property name="FirstName">

            <validator lowerBound="0" lowerBoundType="Ignore" upperBound="5"

              upperBoundType="Inclusive" negated="false" messageTemplate="First name must be less than 20 characters"

              messageTemplateResourceName="" messageTemplateResourceType=""

              tag="" type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.StringLengthValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

              name="String Length Validator" />

          </property>

          <property name="LastName">

            <validator messageTemplate="LastName must start with X or end with z"

              messageTemplateResourceName="" messageTemplateResourceType=""

              tag="" type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.OrCompositeValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

              name="Or Composite Validator">

              <validator pattern="X.*" options="None" patternResourceName=""

                patternResourceType="" messageTemplate="Last name must start with &quot;X&quot;"

                messageTemplateResourceName="" messageTemplateResourceType=""

                tag="" type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.RegexValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

                name="Starts with X RegEx Validator" />

              <validator pattern=".*z" options="None" patternResourceName=""

                patternResourceType="" messageTemplate="Last name must end with &quot;z&quot;"

                messageTemplateResourceName="" messageTemplateResourceType=""

                tag="" type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.RegexValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

                name="Ends with z RegEx Validator" />

            </validator>

          </property>

          <property name="RewardPoints">

            <validator lowerBound="0" lowerBoundType="Inclusive" upperBound="0"

              upperBoundType="Ignore" negated="false" messageTemplate="" messageTemplateResourceName=""

              messageTemplateResourceType="" tag="" type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.RangeValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

              name="Range Validator" />

          </property>

        </properties>

      </ruleset>

    </type>

  </validation>

</configuration>

こんなの手で書いてたら死んでしまいます!!ということで、実際にはEnterpriseLibraryをインストールすると一緒にインストールされる、「Enterprise Library Configuration」というツールを使って書いていくことになると思います。Enterprise Library Configurationでは、GUIベースで構成ファイルを作成することができます。Visual Studio のアドインとしても利用できます。

さて、ここでのポイントですが、検証対象のクラスとして、「ValidationABSample.DataSet.CustomerDs+CustomerTableRow」を指定している事です。これはDataSetを作ると自動で作成されるTableRowですが、このCustomerTableRowの各プロパティに対して検証ルールを設定していきます。このように、Visual Studioによって自動生成されたプロパティに対しても構成ファイルによって検証ルールを設定する事で、ソースコードを変更することなく、検証ルールの変更ができます。

各プロパティに対して設定した検証ルールを簡単に説明しておきます。

  • FirstName
    • String Length Validator
      • 文字列長が5文字以内
  • LastName
    • Or Composite Validator (以下の2つのValidatorのうち、どちらか一方の検証ルールを満たしていれば良い)
      • Regex Validator
        • 文字列が「X」で始まっている
      • Regex Validator
        • 文字列が「z」で終わっている
  • DateOfBirth
    • Date Range Validator
      • 1969/01/01 以降である
  • EMail
    • Regex Validator
      • メールアドレスのフォーマットに合っている
  • RewardPoint
    • Range Validator
      • 0以上である

4. ConfigDsForm.cs

まずは画面のデザインから。適当ですが。こんな感じです。CustomerDsをコンポーネントとして画面に追加して、DataGridViewにバインドさせています。

続いて、Validateボタン押下時のイベントハンドラの実装です。特に難しいことはしていません。Validatorを生成して、各Rowに対して検証をかけているだけです。最後に、エラーがあったRowの該当するColumnにエラーメッセーを設定します。

private void buttonValidate_Click(object sender, EventArgs e)

{

    ValidationResults dsResults = new ValidationResults();

    // Validatorの生成

    Validator<CustomerDs.CustomerTableRow> dsValidator = ValidationFactory.CreateValidator<CustomerDs.CustomerTableRow>("RuleSetC");

    // CustomerTableRowの各Rowに対して検証

    foreach (DataRow row in customerDs.CustomerTable.Rows)

    {

        // 前回検証時のエラーを消去

        row.ClearErrors();

        // 入力値検証実施

        ValidationResults rowResults = dsValidator.Validate(row);

        dsResults.AddAllResults(rowResults);

        foreach (ValidationResult result in rowResults)

        {

            // エラーのあったRowに対して、エラーメッセージを設定

            row.SetColumnError(result.Key, result.Message);

        }

    }

}

これで完了です。無事動かせたでしょうか???

まとめ

Validation Application Blockで構成ファイルを使って入力値検証を行う方法を解説しました。基本的な使い方はこれだけですので、あとは応用していくだけです。構成ファイルとして検証ルールを外部に切り出す事ができるので、Visual Studioによって自動生成されたコードに対して、ソースコードに変更を加えることなく検証をかけられるというところが嬉しいと思います。

リンク

Validation Application Block を使おう!! ~属性編~

投稿日時 : 2007年8月5日 13:05

コメント

# re: Validation Application Block を使おう!! ~構成ファイル編~ 2007/08/05 14:43 えムナウ
「Validateボタン」でやったら「System.Int32」に「a」とか入れたら行変更時にDataGridViewがエラーにしちゃうんじゃないだろうか?

# re: Validation Application Block を使おう!! ~構成ファイル編~ 2007/08/05 19:48 tatsumihr
>えムナウさん
昨日の勉強会はお疲れ様でした。
匿名型が分かったらLINQ構文が理解できるようになりましたよ!

確かにこのサンプルだと、DataGridViewに文字列を入れた時点でエラーになりますね。

対応策としては、型付データセットのRewardPointsをStringにしてしまい、カスタムValidatorを作ってStringに対して数値範囲チェックを行うという方法があります。

試しに実装してみたら動いたので、あとで日記に書いておきますね。

# re: Validation Application Block を使おう!! ~構成ファイル編~ 2007/08/05 22:05 tatsumihr
カスタムValidatorのことは、こちらに書きました。カスタムValidatorのこともそのうちまとめます。

えムナウさんからの宿題
<http://blogs.wankuma.com/tatsumihr/archive/2007/08/05/88908.aspx>

Post Feedback

タイトル
名前
Url:
コメント: