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 那样有点浪费。
XAF开发成品案例参考
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
作者博客: http://www.cnblogs.com/foreachlife
欢迎加入CIIP框架\XAF技术应用交流群: 336090194 群文件中有更多相关工具及文档资料
转载请注明出处。多谢!
欢迎加我微信: admiralcn 或扫码:

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端