你的位置:首页 > ASP.net教程

[ASP.net教程]XAF实现运行时填加验证规则并保存到数据库中


 

有几种方法可以用来声明一个验证规则。最常用的方法是使用对应的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 那样有点浪费。