4

私の経験からすると、.NET の多くの検証フレームワークでは、たとえばフィールドが郵便番号や電子メール アドレスであることを確認するなど、一度に 1 つのフィールドを検証できます。私は通常、これらをフィールド内編集と呼んでいます。

私のプロジェクトでは、しばしばフィールド間編集を行う必要があります。たとえば、次のようなクラスがあるとします。

public class Range
{
    public int Min { get; set; }
    public int Max { get; set; }
}

Max が Min よりも大きいことを確認したい場合があります。外部オブジェクトに対して何らかの検証を行うこともできます。たとえば、次のようなクラスがあるとします。

public class Person
{
    public string PostalCode { get; set; }
}

何らかの理由で、提供されたデータベースまたはファイルに郵便番号が存在することを確認したい場合。ユーザーがデータ ディクショナリを提供し、そのデータ ディクショナリに対してオブジェクトを検証する場合など、より複雑な例があります。

私の質問は、.NET 用の既存の検証フレームワーク (TNValidate、NHibernate Validator) のいずれかを使用できるか、それともルール エンジンを使用する必要があるかなどです。現実の世界の人々は、この状況にどのように対処していますか? :-)

4

2 に答える 2

6

私がよく知っている検証フレームワークは 1 つだけで、それはEnterprise Library Validation Application Block (略して VAB) です。VAB の文脈からあなたの質問にお答えします。

最初の質問: VAB で状態 (フィールド間) の検証を実行できますか?

はい、できます。これを行うには複数の方法があります。次のように、自己検証メカニズムを選択できます。

[HasSelfValidation]
public class Range
{
    public int Min { get; set; }
    public int Max { get; set; }

    [SelfValidation]
    public void ValidateRange(ValidationResults results)
    {
        if (this.Max < this.Min)
        {
            results.AddResult(
                new ValidationResult("Max less than min", this, "", "", null));
        }
    }
}

個人的には、このタイプの検証は好きではないと言わざるを得ません。特に、ドメイン エンティティを検証する場合は、検証を検証ロジックから分離しておきたい (そして、ドメイン ロジックを検証フレームワークへの参照から解放したい) ためです。ただし、カスタム バリデータ クラスを作成する代替方法よりも必要なコードが大幅に少なくなります。次に例を示します。

[ConfigurationElementType(typeof(CustomValidatorData))]
public sealed class RangeValidator : Validator
{
    public RangeValidator(NameValueCollection attributes)
        : base(string.Empty, string.Empty) { }

    protected override string DefaultMessageTemplate
    {
        get { throw new NotImplementedException(); }
    }

    protected override void DoValidate(object objectToValidate,
        object currentTarget, string key, ValidationResults results)
    {
        Range range = (Range)currentTarget;

        if (range.Max < range.Min)
        {
            this.LogValidationResult(results,
                "Max less than min", currentTarget, key);
        }
    }
}

このクラスを作成した後、このクラスを次のように検証構成ファイルに接続できます。

<validation>
  <type name="Range" defaultRuleset="Default" assemblyName="[Range Assembly]">
    <ruleset name="Default">
      <validator type="[Namespace].RangeValidator, [Validator Assembly]"
        name="Range Validator" />
    </ruleset>
  </type>
</validation> 

2 番目の質問: データベース (VAB を使用) との相互作用の可能性がある複雑な検証を行う方法。

最初の質問で示した例は、これにも使用できます。同じ手法を使用できます: 自己検証とカスタム バリデーター。オブジェクトの有効性はそのコンテキストに基づいていないため、データベース内の値を確認するシナリオは実際には単純なものです。データベースに対してオブジェクトの状態を簡単に確認できます。オブジェクトが存在するコンテキストが重要になると、より複雑になります (ただし、VAB では可能です)。たとえば、すべての顧客が特定の時点で未発送の注文を 2 件以下にすることを保証する検証を書きたいとします。これは、データベースをチェックする必要があることを意味するだけでなく、おそらく同じコンテキスト内で追加された新しい注文または注文が削除されたことを意味します。この問題は VAB 固有の問題ではありません。選択したすべてのフレームワークで同じ問題が発生します。私は書いたこれらの状況で私たちが直面している複雑さを説明する記事(読んで身震いする)。

3 番目の質問: 現実世界の人々は、この状況にどのように対処しますか?

これらの種類の検証は、プロダクション コードで VAB を使用して行います。うまく機能しますが、VAB を習得するのは簡単ではありません。それでも、私は VAB でできることを気に入っており、v5.0 がリリースされて初めて改善されるでしょう。学習したい場合は、ハンズオン ラボのダウンロードにある ValidationHOL.pdf ドキュメントを読むことから始めてください。

これが役立つことを願っています。

于 2010-02-13T21:07:59.463 に答える
0

箱から出していないものが必要な場合は、カスタム検証コントロールを作成します。ここでの良い点は、これらのカスタムバリデーターが再利用可能であり、複数のフィールドで機能できることです。AtLeastOneOfバリデーターのCodeProjectに投稿した例を次に示します。これにより、グループ内の少なくとも1つのフィールドに値が必要になります。

http://www.codeproject.com/KB/validation/AtLeastOneOfValidator.aspx

ダウンロードに含まれているコードは、それを実行する方法の簡単なサンプルとして機能するはずです。ここでの欠点は、ASP.Netに含まれている検証コントロールがasp.net-ajaxではうまく機能しないことが多いことです。

于 2010-02-13T18:13:51.337 に答える