简体   繁体   English

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

[英]How can I use the Data Validation Attributes in C# in a non-ASP.net context?

I'd like to use the data validation attributes in a library assembly, so that any consumer of the data can validate it without using a ModelBinder (in a console application, for instance). 我想在库程序集中使用数据验证属性,这样数据的任何使用者都可以在不使用ModelBinder的情况下对其进行验证(例如,在控制台应用程序中)。 How can I do it? 我该怎么做?

Actually this is pretty cool. 其实这很酷。 I used it in a WFP validation implementation recently. 我最近在WFP验证实施中使用它。 Most people end up writing lots of code using reflection to iterate the attributes, but there's a built in function for this. 大多数人最终使用反射来编写大量代码来迭代属性,但是有一个内置函数。

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

You can also validate attributes on a single named property. 您还可以在单​​个命名属性上验证属性。 You can also optionally pass in a list in order to access the error messages : 您还可以选择传入列表以访问错误消息:

var results = new List<ValidationResult>();
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);

The System.ComponentModel.DataAnnotations.ValidationAttribute classes have IsValid methods that perform the validation logic. System.ComponentModel.DataAnnotations.ValidationAttribute类具有执行验证逻辑的IsValid方法。 They take an Object (the value of the field they decorate) and return true or false . 它们获取一个Object(它们装饰的字段的值)并返回truefalse

You can use these attributes, and a little reflection, to roll your own aspect-oriented validator. 您可以使用这些属性和一些反射来推动您自己的面向方面的验证器。 Pass your validator an object, and the validator will get a list of PropertyInfo s and FieldInfo s. 将验证器传递给对象,验证器将获得PropertyInfoFieldInfo的列表。 For each of these, it can call GetCustomAttributes to look for those that inherit from ValidationAttribute , and for each of these, call IsValid , passing the value of the property or field. 对于其中的每一个,它可以调用GetCustomAttributes来查找从ValidationAttribute继承的那些,并为每个调用IsValid ,传递属性或字段的值。 This can be done totally dynamically without knowing the structure of the class to be validated at design-time. 这可以完全动态地完成,而不需要知道要在设计时验证的类的结构。

TryValidateProperty is just badly written - you have to jump through hoops to get it to work outside a Controller, and even then, if you use it twice, it will end up quietly setting ModelState to valid/invalid and stop alterring that state, and stop returning accurate results from then on. TryValidateProperty编写得很糟糕 - 你必须通过箍来让它在Controller之外工作,即使这样,如果你使用它两次,它最终会安静地将ModelState设置为有效/无效并停止改变该状态,并停止从那时起返回准确的结果。

I gave up on it and just wrote my own validator. 我放弃了它,只是写了我自己的验证器。 This'll loop over any set of objects in any context and tell you if they're valid: 这将循环遍历任何上下文中的任何对象集,并告诉您它们是否有效:

bool isValid = true;
var invalidFields = new List<string>();

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;
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何创建一个在ASP.NET和非ASP.NET应用程序中工作的类库? - How do I make a class library that works in ASP.NET and non-ASP.NET applications? 将非 ASP.NET 应用程序与 IIS 集成? - Integrating a non-ASP.NET application with IIS? 我可以使用 model 验证/验证属性在非 ASP 项目中初始化 object 吗? - Can I use model validation/validation attributes for initializing an object in non-ASP projects? 相当于MachineKey.Protect / Unprotect的非ASP.Net - Non-ASP.Net equivalent of MachineKey.Protect/Unprotect 如何使用c#asp.net从URL获取数据? - How can I use c# asp.net to get data from url? 如何使用c#属性? - How can I use c# attributes? 在.NET / C#上下文中,什么是二进制搜索?如何/为什么要使用二进制搜索? - In a .NET/C# context, what is a binary search and how/why can I use one? 如何在不使用ASPNETDB.MDF的情况下使用角色管理 - asp.net/c# - how can i use rolemanagement without the use of ASPNETDB.MDF - asp.net/c# 如何强制.NET(C#)使用方法的非泛型重载? - How Can I Force .NET (C#) to Use the non-generic overload of a method? 如何在 Asp Net Core 3.1 Web API 中的派生类型列表上实现数据验证属性 - How do I implement data validation attributes on a list of derived types in Asp Net Core 3.1 Web API
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM