次のようなドメイン モデルがあるとします。
public class MyDomainEntity
{
public double SomeVar { get; set; }
}
SomeVar をパーセンテージで表示したいビューがあります。したがって、私のビューモデルは次のようになります。
public class MyViewEntity
{
public double SomeVarAsPercentage { get; set; }
}
そして、変数を単純に除算して100倍するビューモデルとドメインモデルの間でマッピングするマッピングクラスがあります。
次に、ドメイン モデルでいくつかの検証を行いたいと思います。この場合のビジネス ルールでは、ドメイン モデルの SomeVar は 0.0 から 1.0 までの範囲である必要があります。これは、System.ComponentModel.DataAnnotations.RangeAttribute を使用して簡単に実行できます。
public class MyDomainEntity
{
[Range(0.0, 1,0)]
public double SomeVar { get; set; }
}
そして、次を使用して検証を実行できます
MyDomainEntity r = new MyDomainEntity();
...
//mapping code from view-model to domain model
...
IList<ValidationResult> results = new List<ValidationResult>();
ValidationContext context = new ValidationContext(r, null, null);
Validator.TryValidateObject(r, context, results, true);
foreach (ValidationResult e in results)
{
//I would like to display the error messages, if any, to the user
}
ただし、検証はドメイン モデルで行われるため、エラー メッセージは次のようになります。
"The field SomeVar must be between 0 and 1"
一方、上記のエラー メッセージは、ビュー モデルに変換して読み取る必要があります。
"The field SomeVarAsPercentage must be between 0 and 100"
ユーザーにとって意味のあるものにするため。
ここでの質問は次のとおりです。
- DataAnnotations には、この「エラー メッセージの変換」を行う機能がありますか?
- この場合、ドメイン モデルで検証を行うべきではありませんか?
- おそらく、検証メカニズムとしての DataAnnotations は、ここでは十分または適切ではないでしょうか? この場合、他のフレームワークを提案してください
アップデート:
この問題についてもう少し考えてみたところ、いくつかのアプローチがあるようです
アプローチ 1: View-Model での検証
次のように、検証をビューモデルに移動します。
public class MyViewEntity
{
[Range(0.0, 100.0)]
public double SomeVarAsPercentage { get; set; }
}
そのため、DataAnnotations は必要なエラー メッセージを生成できます。
ただし、ビューモデルで検証を行う (ドメイン モデルに適用されるように) のは、より WET です。私のフォームが 2 つのビューを切り替えることができるとします。1 つは SomeVar がパーセンテージで表示され、もう 1 つは SomeVar が「そのまま」表示されますが、小数点以下 2 桁までしか表示されません。それから私はしなければなりません:
public class MyViewEntity1
{
[Range(0.0, 100.0)]
public double SomeVarAsPercentage { get; set; }
}
public class MyViewEntity2
{
[Range(0.0, 1.0)]
public double SomeVarToTwoDp { get; set; }
}
Range ルールを 2 つの場所に配置する必要がありますが、どちらも実際には同じルールです。
長所:シンプル
短所:少しウェット
アプローチ 2: わずかに変更された検証メソッドを使用して、ドメイン モデルで検証する
DataAnnotations 検証フレームワークを拡張して、エラー プロパティ名だけでなく、違反したルールとエラー メッセージ ファクトリを返すようにします。そのため、View-Model エンティティと Domain Model エンティティ間のマッピングは、エラー メッセージ ファクトリとルール (これもマッピングする必要があります) を使用して意味のあるエラー メッセージを生成します。
利点: より DRY、検証ルールはドメイン モデルに 1 回しか表示されない
欠点: より複雑