Asynchronous
Asynchronous

Reputation: 3977

How to use Enum to provide descriptive status for data validation

I need to use enum so that the validation in my application is easily readable and can be easy to understand and manage:

However, I feel that my approach is a bit extraneous. Is there a way to do this with less code?

Please note: For brevity sake, I have remove the actual validation from the code.

Code:

public enum LastName
{
    ContainNumbers,
    ContainIlligalCharacters,
    ContainEmptyString,
    PassedValidation,
}

public enum FirstName
{
    ContainNumbers,
    ContainIlligalCharacters,
    ContainEmptyString,
    PassedValidation,
}
public class DataMember 
{

    int _lastNameState;
    int _firstNameState;

    public DataMember(string lastName, string firstName)
    {
        LastName lName;
        FirstName fName;

        _lastNameState = (int)(lName = (lastName == "A" ? 
            LastName.PassedValidation : LastName.ContainEmptyString));

        _firstNameState = (int)(fName = (firstName == "B" ? 
            FirstName.PassedValidation : FirstName.ContainEmptyString));
    }

    public int UserLastName
    {
        get
        {
            return _lastNameState;
        }
        set
        {
            _lastNameState = value;
        }
    }

    public int UserFirstName
    {
        get
        {
            return _firstNameState;
        }
        set
        {
            _firstNameState = value;
        }
    }

}

Calling code:

    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        DataMember dataMember = new DataMember(txtLastName.Text, txtFirstName.Text);

   bool isValidLastName = (dataMember.UserLastName ==  (int)LastName.PassedValidation);
   bool isValidFirstName = (dataMember.UserFirstName == (int)FirstName.PassedValidation);

     lblDisplayLastNameStatus.Text = isValidLastName.ToString();
     lblDisplayFirstNameStatus.Text = isValidFirstName.ToString();
    }

Upvotes: 1

Views: 76

Answers (3)

Yatrix
Yatrix

Reputation: 13775

Why do you need two identical enumerations? Just name it generically and name your variables smartly.

public enum NameValidation
{
    ContainNumbers,
    ContainIlligalCharacters,
    ContainEmptyString,
    PassedValidation,
}

NameValidation lNameValidation;
NameValidation fNameValidation;

If you wanted to define two, but they have different, but similar sets of values, you can always define a class and inherit.

public abstract class BaseValidation {
    public const ContainNumbers int = 1;
    public const ContainIlligalCharacters = 2;
    public const ContainEmptyString = 3;
    public const PassedValidation = 4
}

public class FirstName: BaseValidation {
    public const SomethingDifferent = 5;
}

public class LastName: BaseValidation {
    public const SomethingMoreDifferent = 5;
    public const SomethingEvenMoreDifferent = 6;
}

I would not recommend my second solution, as it's overkill, but that's one other way you could go.

Upvotes: 2

druidicwyrm
druidicwyrm

Reputation: 500

Here is an update on the top code to allow for basic validation that is much cleaner. The bonus to the [Flags] attribute is that it extends your ability to know ALL the invalid states. In other words, you could share a message with the client that says their name contains both numbers and illegal characters.

There was also no need to cast the enum to an int. You can compare enums in the same manner as ints. You can also use the default properties.

[Flags]
public enum NameValidation
{
    PassedValidation = 0,
    ContainNumbers = 1,
    ContainIllegalCharacters = 2,
    ContainEmptyString = 4,
}

public class DataMember 
{
    public NameValidation FirstNameState {get; set;}
    public NameValidation LastNameState {get; set;}

    public DataMember(string lastName, string firstName)
    {
        FirstNameState = ValidateName(firstName);
        LastNameState = ValidateName(lastName);
    }

    private NameValidation ValidateName(string name)
    {
        var validation = NameValidation.PassedValidation;
        if(string.IsNullOrEmpty(name)) validation |= NameValidation.ContainEmptyString;
        //Validate illegal characters
        //Validate numbers
        return validation;
    }
}

I left these printing out true/false as that is what the original call did. However, you could also print out the flag values to provide the validation states.

protected void btnSubmit_Click(object sender, EventArgs e)
{
    DataMember dataMember = new DataMember(txtLastName.Text, txtFirstName.Text);

    lblDisplayLastNameStatus.Text = (dataMember.LastNameState ==  NameValidation.PassedValidation).ToString();
    lblDisplayFirstNameStatus.Text = (dataMember.FirstNameState ==  NameValidation.PassedValidation).ToString();
}

Upvotes: 1

ANewGuyInTown
ANewGuyInTown

Reputation: 6447

Define a single enum for both last name and first name.

public enum NameValidation
{
   [Description("Contains Numbers"]
   ContainNumbers,

   [Description("Contains Illigal Characters"]
   ContainIlligalCharacters,

   [Description("Contains empty strings"]
   ContainEmptyString,

   [Description("Success. Passed Valiation"]
   PassedValidation,
}

Have an Enum Helper extension method to read description:

 public static class EnumHelper
{
    public static string GetDescription<T>(this T enumVal) where T : struct
    {
        Type type = enumVal.GetType();
        if (!type.IsEnum)
        {
            throw new ArgumentException("Must be enum type","enumVal");
        }
        MemberInfo[] memberInfo = type.GetMember(enumVal.ToString());
        if (memberInfo.Length > 0)
        {
            object[] attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);

            if (attrs.Length > 0)
            {
                return ((DescriptionAttribute)attrs[0]).Description;
            }
        }
        return enumVal.ToString();
    }
}

And on Submit button, assign the description to the label text.

lblDisplayFirstNameStatus.Text= ValidateFirstName().GetDescription();
lblDisplayFirstNameStatus.Text= ValidateLastName().GetDescription();

Here ValidateFirstName and ValidateLastName returns NameValidation enum type.

Upvotes: 2

Related Questions