Search code examples
c#reflectionannotationsattributes.net-attributes

How to use a custom annotations validator POCO without any framework (no asp.net, no mvc, no ORM)


I have a custom validation class

using System;
using System.Collections.Generic;
using System.Reflection;

 internal class RequiredAttribute1 : Attribute
{
    public RequiredAttribute1()
    {
    }

    public void Validate(object o, MemberInfo info, List<string> errors)
    {
        object value;

        switch (info.MemberType)
        {
            case MemberTypes.Field:
                value = ((FieldInfo)info).GetValue(o);
                break;

            case MemberTypes.Property:
                value = ((PropertyInfo)info).GetValue(o, null);
                break;

            default:
                throw new NotImplementedException();
        }

        if (value is string && string.IsNullOrEmpty(value as string))
        {
            string error = string.Format("{0} is required", info.Name);

            errors.Add(error);
        }
    }
}

I am using it on the following object:-

class Fruit
{
 [RequiredAttribute1]
 public string Name {get; set;}

 [RequiredAttribute1]
 public string Description {get; set;}
}

Now, I want to run the validation rules on a list of fruits, to print to a string
All I can think of is :-

  1. Iterate through fruits
  2. For each fruit, iterate through its properties
  3. For each property, iterate through custom validators (only 1 here...)
  4. Call the Validate function
  5. Collect and print validator errors

Is there something easier than this and more built-in, for reading these annotations, without having to add framework dlls like (ASP.net / MVC /etc...) ?
This is just for a simple Console application.


Solution

  • I managed to get it working using

    using System.ComponentModel.DataAnnotations;
    
    class RequiredAttribute : ValidationAttribute
    { //... above code }
    

    In the main Driver class...

    using System.ComponentModel.DataAnnotations;
    
    class Driver
    {
    
    public static void Main(string[] args)
    {
                var results = new List<ValidationResult>();
                var vc = new ValidationContext(AreaDataRow, null, null);
                var errorMessages = new List<string>();
    
                if (!Validator.TryValidateObject(AreaDataRow, vc, results, true))
                {
                    foreach (ValidationResult result in results)
                    {
                        if (!string.IsNullOrEmpty(result.ErrorMessage))
                        {
                            errorMessages.Add(result.ErrorMessage);
                        }
                    }
    
                    isError = true;
                }
    }
    }
    

    No frameworks or ORMS required, just the DataAnnotations library.
    It can work with multiple [Attributes]