如何在非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(它们装饰的字段的值)并返回true
或false
。
您可以使用这些属性和一些reflection来推动您自己的面向方面的validation器。 将validation器传递给对象,validation器将获得PropertyInfo
和FieldInfo
的列表。 对于其中的每一个,它可以调用GetCustomAttributes
来查找从ValidationAttribute
inheritance的那些,并为每个调用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; } } } }