Tuesday, 21 August 2018

Creating a validation attribute for multiple enum values in C#

This article will present a validation attribute for multiple enum value in C#. In C#, generics is not supported in attributes. The following class therefore specifyes the type of enum and provides a list of invalid enum values as an example of such an attribute.


using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace ValidateEnums
{

    public sealed class InvalidEnumsAttribute : ValidationAttribute
    {

        private List<object> _invalidValues = new List<object>();



        public InvalidEnumsAttribute(Type enumType, params object[] enumValues)
        {
            foreach (var enumValue in enumValues)
            {
                var _invalidValueParsed = Enum.Parse(enumType, enumValue.ToString());
                _invalidValues.Add(_invalidValueParsed);
            }
        }

        public override bool IsValid(object value)
        {
            foreach (var invalidValue in _invalidValues)
            {
                if (Enum.Equals(invalidValue, value))
                    return false;
            }
            return true;
        }

    }

}

Let us make use of this attribute in a sample class.

 public class Snack
    {
        [InvalidEnums(typeof(IceCream), IceCream.None, IceCream.All )]
        public IceCream IceCream { get; set; }

    }

We can then test out this attribute easily in NUnit tests for example:

[TestFixture]
    public class TestEnumValidationThrowsExpected
    { 

        [Test]
        [ExpectedException(typeof(ValidationException))]
        [TestCase(IceCream.All)]
        [TestCase(IceCream.None)]
        public void InvalidEnumsAttributeTest_ThrowsExpected(IceCream iceCream)
        {
            var snack = new Snack { IceCream = iceCream };
            Validator.ValidateObject(snack, new ValidationContext(snack, null, null), true);
        }

        [Test]
        public void InvalidEnumsAttributeTest_Passes_Accepted()
        {
            var snack = new Snack { IceCream = IceCream.Vanilla };
            Validator.ValidateObject(snack, new ValidationContext(snack, null, null), true);
            Assert.IsTrue(true, "Test passed for valid ice cream!"); 
        }


No comments:

Post a Comment