如何在非ASP.NET网络环境中使用C#中的数据validation属性?

我想在库程序集中使用数据validation属性,以便数据的任何使用者都可以在不使用ModelBinder的情况下对其进行validation(例如,在控制台应用程序中)。 我该怎么做?

其实这很酷。 我最近在WFPvalidation实施中使用它。 大多数人最终使用reflection来编写大量代码来迭代属性,但是有一个内置函数。

var vc = new ValidationContext(myObject, null, null); return Validator.TryValidateObject(myObject, vc, null, true); 

您还可以在单​​个命名属性上validation属性。 您还可以选择传入列表以访问错误消息:

 var results = new List(); var vc = new ValidationContext(myObject, null, null) { MemberName = "UserName"}; var isValid = Validator.TryValidateProperty(value, vc, results); // get all the errors var errors = Array.ConvertAll(results.ToArray(), o => o.ErrorMessage); 

System.ComponentModel.DataAnnotations.ValidationAttribute类具有执行validation逻辑的IsValid方法。 它们获取一个Object(它们装饰的字段的值)并返回truefalse

您可以使用这些属性和一些reflection来推动您自己的面向方面的validation器。 将validation器传递给对象,validation器将获得PropertyInfoFieldInfo的列表。 对于其中的每一个,它可以调用GetCustomAttributes来查找从ValidationAttributeinheritance的那些,并为每个调用IsValid ,传递属性或字段的值。 这可以完全动态地完成,而不需要知道要在设计时validation的类的结构。

TryValidateProperty编写得很糟糕 – 你必须跳过箍才能让它在Controller之外工作,即便如此,如果你使用它两次,它最终会安静地将ModelState设置为有效/无效并停止改变该状态,并停止从那时起返回准确的结果。

我放弃了它,只是写了我自己的validation器。 这将循环遍历任何上下文中的任何对象集,并告诉您它们是否有效:

 bool isValid = true; var invalidFields = new List(); foreach (var o in viewModels) { var properties = o.GetType() .GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach(var prop in properties) { var attrs = prop.GetCustomAttributes(true); if (attrs != null) { var val = prop.GetValue(o); ValidationAttribute[] validatorAttrs = attrs .Where(a => a is ValidationAttribute) .Select(a => (ValidationAttribute)a).ToArray(); foreach(var attr in validatorAttrs) { bool thisFieldIsValid = attr.IsValid(val); if (!thisFieldIsValid) invalidFields.Add(prop.Name); isValid = isValid && thisFieldIsValid; } } } }