有几种方法可以用来声明一个验证规则。最常用的方法是使用对应的Attribute来定义。详见这里。验证模块还允许您通过在业务类实现 IRuleSource 接口定义自定义的验证规则的来源。
IRuleSource 接口公开两个成员。名称属性应返回自定义的验证规则源的唯一名称。CreateRules 方法应实例化自定义的验证规则。
一个场景中,您可能需要实现自定义验证规则来源执行验证规则存储在数据库中。可以使用这种方法,当您需要频繁地自定义验证规则在已部署的应用程序中,但您不能重新部署应用程序或自定义其应用程序模型。
下面的示例阐释了此方案。
此示例所示的 RuleRequiredFieldPersistent 类是一个普通的业务类。类实现 IRuleSource 接口,并用于创建和存储在数据库中的 RuleRequiredField 验证规则。在 CreateRules 方法中实例化一个 RuleRequiredField 验证规则,基于 RuleRequiredFieldPersistent 类的公共属性的值。RuleRequiredFieldPersistent 类标记 DefaultClassOptionsAttribute,以便最终用户可以手动创建验证规则通过相应的列表视图。
[DefaultClassOptions] public class RuleRequiredFieldPersistent : BaseObject, DevExpress.Persistent.Validation.IRuleSource { public RuleRequiredFieldPersistent(Session session) : base(session) { } public string RuleName { get { return GetPropertyValue<string>("RuleName"); } set { SetPropertyValue("RuleName", value); } } public string CustomMessageTemplate { get { return GetPropertyValue<string>("CustomMessageTemplate"); } set { SetPropertyValue("CustomMessageTemplate", value); } } public bool SkipNullOrEmptyValues { get { return GetPropertyValue<bool>("SkipNullOrEmptyValues"); } set { SetPropertyValue("SkipNullOrEmptyValues", value); } } public string Id { get { return GetPropertyValue<string>("Id"); } set { SetPropertyValue("Id", value); } } public bool InvertResult { get { return GetPropertyValue<bool>("InvertResult"); } set { SetPropertyValue("InvertResult", value); } } public string ContextIDs { get { return GetPropertyValue<string>("ContextIDs"); } set { SetPropertyValue("ContextIDs", value); } } public string Property { get { return GetPropertyValue<string>("Property"); } set { SetPropertyValue("Property", value); } } [Persistent("ObjectType")] protected string ObjectType { get { if(ObjectTypeCore != null) { return ObjectTypeCore.FullName; } return ""; } set { ObjectTypeCore = ReflectionHelper.FindType(value); } } [NonPersistent] [TypeConverter(typeof(DevExpress.Persistent.Base.LocalizedClassInfoTypeConverter))] public Type ObjectTypeCore { get { return GetPropertyValue<Type>("ObjectTypeCore"); } set { SetPropertyValue("ObjectTypeCore", value); } } #region IRuleSource Members public System.Collections.Generic.ICollection<IRule> CreateRules() { System.Collections.Generic.List<IRule> list = new System.Collections.Generic.List<IRule>(); RuleRequiredField rule = new RuleRequiredField(); rule.Properties.SkipNullOrEmptyValues = this.SkipNullOrEmptyValues; rule.Properties.Id = this.Id; rule.Properties.InvertResult = this.InvertResult; rule.Properties.CustomMessageTemplate = this.CustomMessageTemplate; rule.Properties.TargetContextIDs = new ContextIdentifiers(this.ContextIDs); rule.Properties.TargetType = this.ObjectTypeCore; if(rule.Properties.TargetType != null) { foreach(PropertyInfo pi in rule.Properties.TargetType.GetProperties()) { if(pi.Name == this.Property) { rule.Properties.TargetPropertyName = pi.Name; } } } for(int i = Validator.RuleSet.RegisteredRules.Count - 1; i >= 0; i--) { if(Validator.RuleSet.RegisteredRules[i].Id == this.Id) { Validator.RuleSet.RegisteredRules.RemoveAt(i); } } list.Add(rule); return list; } [Browsable(false)] public string Name { get { return this.RuleName; } } #endregion }
可以看到,这个示例中,只返回了一个规则,而在实际项目中,可以使用BO定义一个子集合,集合中定义N种规则。
不要定义N个BO并都实现 IRuleSource 那样有点浪费。
时间: 2024-10-10 09:36:08