We are trying to use the Foolproof validation annotation [RequiredIf]
to check if an email address is needed. We also created an enum to avoid using a lookup table id in the ViewModel. The code looks like this:
public enum NotificationMethods {
Email = 1,
Fax = 2
}
Then in the ViewModel:
[RequiredIf("NotificationMethodID", NotificationMethods.Email)]
public string email {get; set;}
In this senario we do not get an error when email is unfilled but selected as the notification type. Conversely this works as expected:
[RequiredIf("NotificationMethodID", 1)]
public string email {get; set;}
The only other reference to this I have found is here: https://foolproof.codeplex.com/workitem/17245
The bunch of software developers from the story could have avoided these hassles if they’d used enums instead of booleans. An enumerator is a data type consisting of a set of named values that can be used in a type-safe way.
valueOf () method returns the enum constant of the specified string value, if exists. enum can contain a constructor and it is executed separately for each enum constant at the time of enum class loading. We can’t create enum objects explicitly and hence we can’t invoke enum constructor directly.
enum can contain a constructor and it is executed separately for each enum constant at the time of enum class loading. We can’t create enum objects explicitly and hence we can’t invoke enum constructor directly. enum can contain both concrete methods and abstract methods.
First line inside enum should be list of constants and then other things like methods, variables and constructor. According to Java naming conventions, it is recommended that we name constant with all capital letters Important points of enum : Every enum internally implemented by using Class.
Given that your method NotificationMethodID
is returning an int
, the reason your check is failing is that, in c#, each enum
is its own type, inheriting from System.Enum
. I.e. if you do
var value = NotificationMethods.Email;
string s = value.GetType().Name;
You will see s
has the value "NotificationMethods"
not "Int32"
.
If you try to check the equality of an int with an enum directly, you get a compiler error:
var same = (1 == NotificationMethods.Email); // Gives the compiler error "Operator '==' cannot be applied to operands of type 'int' and 'NotificationMethods'"
If you box the enum and int values first (which is what happens when they are passed to the constructor of RequiredIfAttribute
) then there is no compiler error but Equals()
returns false, since the types differ:
var same = ((object)1).Equals((object)NotificationMethods.Email);
Debug.WriteLine(same) // Prints "False".
To check equality of underlying integer values, you can explicitly cast NotificationMethods.Email
to an integer before boxing:
var same = ((object)1).Equals((object)((int)NotificationMethods.Email));
Debug.WriteLine(same); // Prints "True"
And in the attribute application:
[RequiredIf("NotificationMethodID", (int)NotificationMethods.Email)]
public string email {get; set;}
You might also consider using const int
values instead of enums:
public static class NotificationMethods
{
public const int Email = 1;
public const int Fax = 2;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With