포럼: Open Discussion (Thread #22560)

入力値検証機能でのDBNull 値の扱いについて (2009-04-27 21:29 by Anonymous #43491)

現在TERASOLUNA Server/Client Framework for .NETを検証中です。

入力値検証機能のRequiredValidatorを動作させようとしていますが、
検証対象のDataSetのカラムの値がDBNull 値であると、
「DBNull 値を検証することはできません。」とTerasolunaExceptionが発生します。

カラムの値がDBNull 値であれば、Exceptionではなく、IsValid=Falseの状態にしたいのですが、
解決方法はないでしょうか?

Reply to #43491×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login

RE: 入力値検証機能でのDBNull 値の扱いについて (2009-04-28 20:56 by sejimos #43517)

検証対象のDataSetのカラムに対して、NullValueプロパティを
「Null」か「Empty」に設定してください。
(既定では「Throw exception」に設定されています)

TerasolunaExceptionは発生せず、IsValid=Falseとなります。

Reply to #43491

Reply to #43517×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login

RE: 入力値検証機能でのDBNull 値の扱いについて (2009-04-29 11:17 by Anonymous #43524)

返信ありがとうございます。

DataSetのカラムの型がSystem.Stringであれば、
NullValueプロパティを「Null」もしくは「Empty」に設定でき、IsValid=Falseの状態になりました。

しかし、System.String以外の型(System.Datetime,System.Decimal等)のカラムの場合、
NullValueプロパティは「Throw exception」以外に変更ができません。

実案件でカラムがSystem.String以外の型で、DbNull値を扱う場合は、
TERASONULAの入力検証機能以外の検証方法で検証を実施しているのでしょうか?
(ex.System.Decimal型のカラムの入力必須チェック)
Reply to #43517

Reply to #43524×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login

RE: 入力値検証機能でのDBNull 値の扱いについて (2009-04-29 11:45 by tatsumihr #43525)

DbNull値を扱いたい場合は、2種類の対応方法があります。

1. EventControllerのCustomValidatingイベントで、入力チェックをコードで実装する
 →機能説明書をご覧ください。

2. TERASOLUNAのValidatorを拡張する
 →VabValidatorの拡張で対応する。

DataSetのデータカラムをDecimal型などでDBNullを許可した場合、
仮にカラムにDBNullが入っていると、そのカラムにアクセスしただけで例外が発生します。
したがって、DecimalRangeValidatorなどの個別検証ルールの拡張では
対応できないことにご注意ください。

個別検証ルールをまとめて実行しているVabValidatorの中で、
対象のカラムがDBNullかどうかをDataRow.IsNullメソッドなどでチェックし、
対象のカラムがDBNullでなかったらDecimalRangeValidatorに値を渡す、
DBNullであったら入力値検証エラーとして返す、という処理を作り込む必要があります。

このような処理は個別システムの要件に依存することが多いため、
TERASOLUNA標準機能としては、DBNullはエラーとして扱っています。
Reply to #43524

Reply to #43525×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login

RE: 入力値検証機能でのDBNull 値の扱いについて (2009-04-30 12:02 by Anonymous #43537)

返信ありがとうございます。

TERASOLUNA標準機能としての、DBNullの扱い・検証ルールの動作についてご説明ありがとうございました。

ご提示いただいた対応方法で、「2. VabValidatorの拡張で対応する」方法で実装を検討しています。

拡張VabValidatorクラスを作成し、「入力値検証実行クラスの変更」で、VabValidatorに替わって動作させています。

VabValidator.ValidateDataSetメソッド内で、
row.RowState <> DataRowState.Deleted の判断を行っている箇所辺りで、
対象のカラムがSystem.String型でないか、DBNullかどうかの判断を行おうとしています。


しかし、EntlibのValidatorに渡すオブジェクトがDataRow単位で、カラム単位ではないことと、
VabValidator.ValidateDataSetメソッド内で、入力検証ルールが取得できないので、
検証ルール実行前に、検証対象カラムの特定・検証対象カラムの情報取得ができません。
(typeの情報から、検証対象のDataRow自体の型とルールセット名は分かるのですが・・・。)

検証ルール実行前に、検証対象カラムの特定・検証対象カラムの情報取得はできないでしょうか?

上記ができたとしても、検証対象のカラムごとに、型・DbNullかを判断して検証を実行させようとすると、

EntlibのValidateメソッドを拡張するしか方法はないでしょうか?

以上、よろしくお願いします。
Reply to #43491

Reply to #43537×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login

RE: 入力値検証機能でのDBNull 値の扱いについて (2009-04-30 22:01 by tatsumihr #43543)

EntLibのValidateメソッドの拡張でも対応は難しいかと思います。

TERASOLUNAではValueObjectとしてDataSetを使うことを想定しているため、
標準の入力値検証のかけ方がDataRow単位となっています。
これはEntLibの仕様に引きずられているものではありません。

どうしてもカラム単位で検証を行いたい場合は、
VabValidator.ValidateDataSetメソッドの引数にIConfigurationSourceが渡ってきているので、
ここから設定ファイルの情報を取得し、
検証ルールの生成とカラム単位の検証を独自に実装することになるかと思います。

これはEntLibのValidationFactory相当のものから作り直すようなイメージです。
ValidationFactoryではIConfigurationSourceを元に各検証ルールを生成しているので、
実現はできると思います。


ただし、ここまでやることが大変なので、TERASOLUNA Client Framework for .NETを使って
Windowsフォームアプリケーションを開発する場合、
画面とバインドするDataSetのカラムの型は、すべてString型とすることが多くあります。
画面のTextBoxやGridViewなどとDataSetをバインドさせる場合、
入力されるのは文字列なので、これで特に問題は起こりません。

ビジネスロジックでのデータアクセスの関係などで、どうしてもDateTime型やDecimal型が必要な場合、
まずは画面から入力された日付や数値を一時的にString型で受けて、VabValidatorで検証をかけます。
その後、EventControllerのPreProcessedイベントでデータをString型からDateTime型などに詰め替えて、
ビジネスロジック以降に渡すことで対処できます。

または、先日回答しました通り、
EventControllerのCustomValidatingイベントで、入力チェックを実装することで対処します。


DBNullをどう扱うか?という点については、開発中にかなり考えました。
しかし、なかなか良い案は見つかりませんでした。
基本的には画面とのデータバインドは、すべてString型で受ける。
その他のデータ型で扱いたい場合は、入力値検証後、EventControllerのイベントで変換する。
というような指針で開発することが多いです。

美しくないと言えばその通りかもしれませんが、
現在のところ、このような方法でも十分対処できています。
Reply to #43537

Reply to #43543×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login