I've been representing an enum within my razor view as a hidden field, which is posted back to an action result.
I've noticed that when it binds the string value provided within the HTML, it automatically validates the value for the enum.
/// <summary>
/// Quiz Types Enum
/// </summary>
public enum QuizType
{
/// <summary>
/// Scored Quiz
/// </summary>
Scored = 0,
/// <summary>
/// Personality Type Quiz
/// </summary>
Personality = 1
}
Razor:
@Html.HiddenFor(x => x.QuizType)
Rendered HTML:
<input data-val="true" data-val-required="Quiz Type is not valid" id="QuizType" name="QuizType" type="hidden" value="Scored">
If I change the value within the DOM to something incorrect and submit the form, ModelState.IsValid
returns false
and the following error is added to the ModelState:
"The value 'myincorrectvalue' is not valid for QuizType."
That's all gravy, but I thought that if I created a view model, that I had to explicitly set validation rules on my view model, such as the [Required]
attribute.
Also there is a validation attribute specifically for this called EnumDataType
.
[EnumDataType(typeof(QuizType))]
public QuizType QuizType { get; set; }
Question
If validation happens automatically when binding, what is the point in the EnumDataType
data validation attribute?
Ok, so I've found out the answer to my own question.
The error message that appeared is more of a generic error message for when the binding wasn't possible. When the binding attempts to bind a non-existent string representation of the enum value posted from the HTML to the enum, it produces the error:
The value 'myincorrectvalue' is not valid for QuizType.
The exact same error message would appear if I were to attempt to bind a string value to an int
within my View Model class.
It seems that the issue is that as well as the string representation, an enum can be any integer value. I can set the enum to any number, even if that number doesn't exist within my enum.
/// <summary>
/// Quiz Types Enum
/// </summary>
public enum QuizType
{
/// <summary>
/// Scored Quiz
/// </summary>
Scored = 0,
/// <summary>
/// Personality Type Quiz
/// </summary>
Personality = 1
}
Therefore, this is valid and will be bound without error to my enum value, even though 1000
doesn't exist within my enum:
<input data-val="true" id="QuizType" name="QuizType" type="hidden" value="1000">
// Binder will bind this just fine
QuizType = 1000
That's where the EnumDataType
validation attribute comes in. If I add the validation attribute to my enum within my view model:
[EnumDataType(typeof(QuizType), ErrorMessage = "Quiz type value doesn't exist within enum")]
public QuizType QuizType { get; set;}
With the attribute in place, I will only be able to assign my valid enum values (0 or 1 for this example).
So the incorrect STRING representations posted from the HTML is validated for you automatically upon binding, but a check for any integer value will not.
I hope that this clears up validating ENUMS within ASP.NET MVC.