0

いくつかのフィールドを持つエンティティがあると仮定して。一部のフィールドは特定の状態で必須ですが、その他のフィールドはさらに/他の状態でのみ必要です。

public class Entity
{
    //Required always
    public SomeReference {}

    //Required in specific situation/scenario
    public OtherReference {}
}

既知の検証フレームワークでそのシナリオを達成する方法、または自分でそれを行う方法は?

助けを求める: Udi Dahan はこれについていくつかの考えを持っています。 http://www.udidahan.com/2007/04/30/generic-validation/

4

2 に答える 2

1

現時点で使用しているソリューションがあります。私はFluent 検証を使用していますが、まだ慣れていません。私が持っている簡単なシナリオの例を挙げましょう。多分それは役立ちます。アドレス オブジェクト プロパティを持つユーザー クラスがあります。ある時点では、ユーザーの詳細 (名前、電子メール、パスワードなど) のみを検証し、別の状態ではユーザーの住所 (最初の行、郵便番号など) を検証したいと考えています。

クラスは次のようになります。

public class User {
    public virtual string Name { get; set; }
    public virtual string Email { get; set; }
    public virtual string Password { get; set; }
    public virtual Address Address { get; set; }        
}

public class Address {
    public virtual string Address1 { get; set; }
    public virtual string PostCode { get; set; }
}

次に、アドレス用とユーザー用の 2 つの (簡略化された) バリデーターを用意します。

    public AddressValidator() {
        RuleFor(address => address.Address1)
            .NotNull()
            .WithMessage("Please enter the first line of your address");

        RuleFor(address => address.PostCode)
            .NotNull()
            .WithMessage("Please enter your postcode")
            .Matches(UK_POSTCODE_REGEX)
            .WithMessage("Please enter a valid post code!");
    }

    public UserValidator() {
        RuleFor(user => user.FirstName)
            .NotNull()
            .WithMessage("Please provide a first name")
            .Length(3, 50)
            .WithMessage("First name too short");

        RuleFor(user=> user.Password)
            .Length(8, 50)
            .WithMessage("Password is too short");
    }

次に、Model Validator を作成します。たとえば、ユーザーが住所を入力するフォームがあるとします。AddressModelValidator を作成し、作成したバリデータを再利用できます。

    public AddressModelValidator()  {
        RuleFor(user => user.id)
            .NotNull()
            .WithMessage("An error has occured, please go back and try again");

        RuleFor(user => user.Address).SetValidator(new AddressValidator());
    }

したがって、少し考えれば、実際にいくつかの優れたモデルを作成し、検証コードの重複を減らすことができます!

于 2009-12-21T10:24:07.313 に答える
0

私の好みは、電子メールや日付の検証などの一般的な検証機能を、オブジェクトを渡すことができる ValidationService クラスにローカライズすることです。残りについては、バリデーションをクラス自体に入れる傾向があります。LINQ to SQL を使用している場合、次のように、オブジェクトをデータベースに保存する前に LINQ to SQL が呼び出す Validate() メソッドをオブジェクトに作成できます。

public void Validate()
{
    if(!IsValid)
        throw new ValidationException("Rule violations prevent saving");
}

public bool IsValid
{
    get { return GetRuleViolations().Count() == 0;}
}

public IEnumerable<RuleViolation> GetRuleViolations()
{
    if(this.TermID == 0)
        yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(1), "agreeWithTerms");

    if(ValidationService.ValidateDate(this.Birthdate.ToString()))
        yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(2), "birthDate");

    if (!(Username.Length >= ConfigurationService.GetMinimumUsernameLength()) ||
        !(Username.Length <= ConfigurationService.GetMaximumUsernameLength()))
        yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(5), "username");

    if(ValidationService.ValidateUsernameComplexity(Username))
        yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(6), "username");

    if (AccountID == 0 && ObjectFactory.GetInstance<IAccountRepository>().UsernameExists(this.Username))
        yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(7), "username");

    if (!ValidationService.ValidateEmail(Email))
        yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(8), "email");

    if (AccountID == 0 && ObjectFactory.GetInstance<IAccountRepository>().EmailExists(this.Email))
        yield return new RuleViolation(HelpMessageService.GetHelpMessageBodyByID(9), "email");

    yield break;
}

これを完全に理解するには、こちらをお読みください: http://nerddinnerbook.s3.amazonaws.com/Part3.htm

于 2009-06-22T20:19:50.333 に答える