.NET中的validation框架,可以在字段之间进行编辑

根据我的经验,.NET中的许多validation框架允许您一次validation一个字段,例如确保字段是邮政编码或电子邮件地址。 我通常将这些内部编辑称为。

在我的项目中,我们经常需要进行场间编辑。 例如,如果您有这样的类:

public class Range { public int Min { get; set; } public int Max { get; set; } } 

您可能希望确保Max大于Min。 您可能还想对外部对象进行一些validation。 例如,鉴于你有一个这样的类:

 public class Person { public string PostalCode { get; set; } } 

无论出于何种原因,您希望确保邮政编码存在于数据库或提供给您的文件中。 我有更复杂的例子,比如用户提供数据字典,你想要针对该数据字典validation你的对象。

我的问题是:我们可以使用任何现有的validation框架(TNValidate,NHibernate Validator)用于.NET,还是我们需要使用规则引擎或者什么? 现实世界中的人们如何处理这种情况? 🙂

我只知道一个validation框架,即Enterprise Library Validation Application Block ,简称VAB。 我将从VAB的背景中回答您的问题。

第一个问题:你能在VAB中进行状态(场间)validation吗?

是的你可以。 有多种方法可以做到这一点。 您可以选择自我validation机制,如下所示:

 [HasSelfValidation] public class Range { public int Min { get; set; } public int Max { get; set; } [SelfValidation] public void ValidateRange(ValidationResults results) { if (this.Max < this.Min) { results.AddResult( new ValidationResult("Max less than min", this, "", "", null)); } } } 

我必须说我个人不喜欢这种类型的validation,特别是在validation我的域实体时,因为我喜欢将validation与validation逻辑分开(并保持我的域逻辑不受任何validation框架的引用)。 但是,它们需要的代码比替代方案少得多,后者正在编写自定义validation器类。 这是一个例子:

 [ConfigurationElementType(typeof(CustomValidatorData))] public sealed class RangeValidator : Validator { public RangeValidator(NameValueCollection attributes) : base(string.Empty, string.Empty) { } protected override string DefaultMessageTemplate { get { throw new NotImplementedException(); } } protected override void DoValidate(object objectToValidate, object currentTarget, string key, ValidationResults results) { Range range = (Range)currentTarget; if (range.Max < range.Min) { this.LogValidationResult(results, "Max less than min", currentTarget, key); } } } 

编写此类后,您可以在validation配置文件中挂起此类,如下所示:

        

第二个问题:如何通过数据库(使用VAB)进行复杂的validation。

我给第一个问题的例子也可用于此。 您可以使用相同的技术:自我validation和自定义validation器。 您想要检查数据库中的值的方案实际上很简单,因为对象的有效性不是基于其上下文。 您只需根据数据库检查对象的状态即可。 当对象生存的上下文变得重要时(但VAB可能),它会变得更加复杂。 想象一下,例如,您想要编写一个validation,确保每个客户在给定的时间点,不超过两个未发货的订单。 这不仅意味着您必须检查数据库,而且可能在同一上下文中删除添加的新订单或订单。 此问题不是VAB特定的,您选择的每个框架都会遇到同样的问题。 我写了一篇文章 ,描述了我们在这些情况下面临的复杂性(阅读和颤抖)。

第三个问题:现实世界中的人们如何处理这种情况?

我在生产代码中使用VAB进行这些类型的validation。 它工作得很好,但VAB不是很容易学习。 尽管如此,我喜欢我们可以用VAB做什么,而且只有当v5.0问世时它才会变得更好。 如果您想学习它,请先阅读您可以在动手实验室下载中找到的ValidationHOL.pdf文档。

我希望这有帮助。

当我需要任何不包含在内的东西时,我会构建自定义validation控件。 这里的好处是这些自定义validation器可以重复使用,它们可以在多个字段上运行。 这是我发布到AtProastOneOfvalidation器的CodeProject的示例,它允许您要求组中的至少一个字段具有值:

http://www.codeproject.com/KB/validation/AtLeastOneOfValidator.aspx

下载中包含的代码应该是一个易于理解的样本,您可以如何处理它。 这里的缺点是ASP.Net中包含的validation控件通常不能与asp.net-ajax一起使用。