تاريخ بدء NHiberate Validator قبل تاريخ الانتهاء
-
14-11-2019 - |
سؤال
باستخدام 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;
}
يبدو أن هذا يوفر تكاملًا جيدًا مع النظام الحالي.العيب هو أنه نظرًا لعدم تطبيق ذلك على كائن المجال، فأنت بحاجة إلى منطق إضافي هناك (أو في طبقة الخدمات التي تنشئ كائنات المجال، وما إلى ذلك) لفرضه من هذه النهاية أيضًا، في حالة استخدام نموذج مختلف في مكان آخر لإنشاء أو تحديث كائنات المجال.