سؤال

باستخدام Nhibernate Validator (مع S#harp Architecture / MVC3)، كيف يمكنني كتابة سمة مخصصة، ويفضل ألا تكون خاصة بالكائن (نظرًا لأن هذا مطلب شائع إلى حد ما) يفرض أن PropertyA >= PropertyB (أو في الحالة الأكثر عمومية، قد يكون كلاهما فارغًا).

شيء مثل

public DateTime? StartDate { get; set; }

[GreaterThanOrEqual("StartDate")]
public DateTime? EndDate { get; set; }

أرى أنه يمكنني التجاوز IsValid في الخصوص Entity لكنني لم أكن متأكدًا مما إذا كان هذا هو النهج الأفضل، ولم أرى كيفية تقديم رسالة في هذه الحالة.

هل كانت مفيدة؟

المحلول

عندما تحتاج إلى مقارنة خصائص متعددة لكائن ما كجزء من التحقق من الصحة، فأنت بحاجة إلى أداة التحقق من صحة الفئة.ثم يتم تطبيق السمة على الفئة، وليس الخاصية.

لا أعتقد أن هناك واحدًا يفعل ما تريد، لكن من السهل أن تكتب ما تريد.

إليك مخططًا تفصيليًا للكود ليوضح لك تقريبًا الشكل الذي يمكن أن يبدو عليه جهاز التحقق الخاص بك

[AttributeUsage(AttributeTargets.Class)]
[ValidatorClass(typeof(ReferencedByValidator))]
public class GreaterThanOrEqualAttribute : EmbeddedRuleArgsAttribute, IRuleArgs
{        
    public GreaterThanOrEqualAttribute(string firstProperty, string secondProperty)
    {
        /// Set Properties etc
    }
}

public class ReferencedByValidator : IInitializableValidator<GreaterThanOrEqualAttribute>
{       
    #region IInitializableValidator<ReferencedByAttribute> Members

    public void Initialize(GreaterThanOrEqualAttribute parameters)
    {
        this.firstProperty = parameters.FirstProperty;
        this.secondProperty = parameters.SecondProperty;
    }

    #endregion

    #region IValidator Members

    public bool IsValid(object value, IConstraintValidatorContext constraintContext)
    {
       // value is the object you are trying to validate

        // some reflection code goes here to compare the two specified properties
   }
    #endregion

}

}

نصائح أخرى

في الوقت الحالي، إذا كنت بحاجة إلى القيام بذلك على نموذج ما، فأنا سأقوم بتنفيذ النموذج IValidatableObject

public class DateRangeModel : IValidatableObject {

   public DateTime StartDate { get; set; }
   public DateTime EndDate { get; set; }


   public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        List<ValidationResult> results = new List<ValidationResult>();
        if (StartDate > EndDate)
        {
            results.Add(new ValidationResult("The Start Date cannot be before the End Date.", "StartDate"));
        }
        return results;
    }

يبدو أن هذا يوفر تكاملًا جيدًا مع النظام الحالي.العيب هو أنه نظرًا لعدم تطبيق ذلك على كائن المجال، فأنت بحاجة إلى منطق إضافي هناك (أو في طبقة الخدمات التي تنشئ كائنات المجال، وما إلى ذلك) لفرضه من هذه النهاية أيضًا، في حالة استخدام نموذج مختلف في مكان آخر لإنشاء أو تحديث كائنات المجال.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top