I am currently playing with MVC 2 RC and am having troubles with DataAnnotations for validation.
I have a model class that goes something like this:
public enum Gender { Male, Female)
public class MyAwesomeModel
{
// ... other properties ...
public Gender Gender { get; set; }
}
I have a view that spits out all the Html.EditorFor(...) fields for MyAwesomeModel properties. I also have a custom editor for the Geder type which gets displayed when using EditorFor(...) on the Gender property. This all works great. Everything binds properly to an instance of MyAwesomeModel that gets passed to my action.
The problem is I cannot apply any validators to that property. Let's say I have this validator class:
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public sealed class TestValidatorAttribute : ValidationAttribute
{
private const string _defaultErrorMessage = "'{0}' is not valid.";
public TestValidatorAttribute()
: base(_defaultErrorMessage)
{
}
public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString, name);
}
public override bool IsValid(object value)
{
return false;
}
}
If I decorate my property with that validator, nothing happens.
[TestValidator]
public Gender Gender { get; set; }
I put a breakpoint in the IsValid() method and it never gets hit when the object is validated. However, if I change the property to another type such as string or int, my validator gets called.
So I guess my question is this: do Validation Attributes not work when applied to enum type properties?
I am currently playing with MVC 2 RC and am having troubles with DataAnnotations for validation.
I have a model class with something like this:
public enum Gender { Male, Female)
public class MyAwesomeModel
{
public Gender Gender { get; set; }
}
I have a view that spits out all the Html.EditorFor(...) fields for MyAwesomeModel properties. I also have a custom editor for the Geder type which gets displayed when using EditorFor(...) on the Gender property. This all works great. Everything binds properly to an instance MyAwesomeModel
that gets passed to my action.
The problem is I cannot apply any validators to that property. Let's say I have this validator class:
If I decorate my property with that validator, nothing happens.
[TestValidator]
public Gender Gender { get; set; }
I put a breakpoint in the IsValid() method and it never gets hit when the object is validated. However, if I change the property to another type such as
string or int, my validator gets called.
So I guess my question is this: do Validation Attributes not work when applied to enum type properties?
You're right, that does work. I figured out my issue. The way I had this working in my original project was if it was the first time a user was enterting the requested information then niether of the radio buttons would be checked. If you submit without
checking an option then the validator does not get called.
You can see this with my above example by replacing the "(Model == Gender.Male/Female)" lines in the Gender view with "false" (obviously will not keep state on refresh, but just trying to illustrate a point here).
I'm guessing that because no "Gender" value is being posted then the Gender property is not validated. I had assumed that all of the properties in the class would be validated regardless of what fields are actually in the form being posted.
So how should I go about validating radio buttons? I can make the property nullable, that way if the user does not check an option the controller will see that property as null, but the validator still does not get called when trying this. Seems like my
only other option is to have a class level validator that checks if that property is null, though that's a shame since it's functionally equivilent to the Required attribute.
Validation only ensures that the values that were edited are valid. If we ran validaiton on all properties, whether they were edited or not, it would break partial-editing scenarios.
There are two ways to handle your radio button problem. The simpler one is to always ensure that at least one of the radio buttons was selected. The other way is to mimic what we do with check boxes: render an extra hidden input with the same name but a
uniquely identifiable value. You'll need to write a special model binder to deal with the times where there are only one value (no radio button was selected) vs. two values (a radio button with selected).
Marked as answer by SmallMike on Jan 17, 2010 02:19 AM
Playing some games with hidden fields did the trick. In fact, if the property is nullable, you can just spit out an extra radio button with an empty value and set the display style to "none". If the user does not select another value, it will bind to null
and the Required validator catches it.
SmallMike
Member
1 Points
4 Posts
ValidationAttribute on enum type property?
Jan 15, 2010 05:29 PM|LINK
I am currently playing with MVC 2 RC and am having troubles with DataAnnotations for validation.
I have a model class that goes something like this:
public enum Gender { Male, Female) public class MyAwesomeModel { // ... other properties ... public Gender Gender { get; set; } }I have a view that spits out all the Html.EditorFor(...) fields for MyAwesomeModel properties. I also have a custom editor for the Geder type which gets displayed when using EditorFor(...) on the Gender property. This all works great. Everything binds properly to an instance of MyAwesomeModel that gets passed to my action.
The problem is I cannot apply any validators to that property. Let's say I have this validator class:
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true, Inherited = true)] public sealed class TestValidatorAttribute : ValidationAttribute { private const string _defaultErrorMessage = "'{0}' is not valid."; public TestValidatorAttribute() : base(_defaultErrorMessage) { } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString, name); } public override bool IsValid(object value) { return false; } }If I decorate my property with that validator, nothing happens.
[TestValidator] public Gender Gender { get; set; }I put a breakpoint in the IsValid() method and it never gets hit when the object is validated. However, if I change the property to another type such as string or int, my validator gets called.
So I guess my question is this: do Validation Attributes not work when applied to enum type properties?
Thanks,
Mike
<div style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;" id="_mcePaste">I am currently playing with MVC 2 RC and am having troubles with DataAnnotations for validation.
I have a model class with something like this:
public enum Gender { Male, Female)
public class MyAwesomeModel
{
public Gender Gender { get; set; }
}
I have a view that spits out all the Html.EditorFor(...) fields for MyAwesomeModel properties. I also have a custom editor for the Geder type which gets displayed when using EditorFor(...) on the Gender property. This all works great. Everything binds properly to an instance MyAwesomeModel that gets passed to my action.
The problem is I cannot apply any validators to that property. Let's say I have this validator class:
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public sealed class TestValidatorAttribute : ValidationAttribute
{
private const string _defaultErrorMessage = "'{0}' is not valid.";
public TestValidatorAttribute()
: base(_defaultErrorMessage)
{
}
public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString, name);
}
public override bool IsValid(object value)
{
return false;
}
}
If I decorate my property with that validator, nothing happens.
[TestValidator]
public Gender Gender { get; set; }
I put a breakpoint in the IsValid() method and it never gets hit when the object is validated. However, if I change the property to another type such as string or int, my validator gets called.
So I guess my question is this: do Validation Attributes not work when applied to enum type properties?
</div>bradwils
Contributor
5779 Points
691 Posts
Microsoft
Re: ValidationAttribute on enum type property?
Jan 16, 2010 12:34 AM|LINK
This works just fine for me. I took your code, as is with the applied attribute.
This is my controller:
public class HomeController : Controller { public ActionResult Index() { return View(new MyAwesomeModel()); } [HttpPost] public ActionResult Index(MyAwesomeModel model) { return View(model); } }And this is what I put into my view:
<% using (Html.BeginForm()) { %> <%= Html.EditorForModel() %> <input type="submit" /> <% } %>When I click Submit, regardless of the value for Gender, it always comes back and says: 'Gender' is not valid.
SmallMike
Member
1 Points
4 Posts
Re: ValidationAttribute on enum type property?
Jan 16, 2010 02:51 AM|LINK
You're right, that does work. I figured out my issue. The way I had this working in my original project was if it was the first time a user was enterting the requested information then niether of the radio buttons would be checked. If you submit without checking an option then the validator does not get called.
You can see this with my above example by replacing the "(Model == Gender.Male/Female)" lines in the Gender view with "false" (obviously will not keep state on refresh, but just trying to illustrate a point here).
I'm guessing that because no "Gender" value is being posted then the Gender property is not validated. I had assumed that all of the properties in the class would be validated regardless of what fields are actually in the form being posted.
So how should I go about validating radio buttons? I can make the property nullable, that way if the user does not check an option the controller will see that property as null, but the validator still does not get called when trying this. Seems like my only other option is to have a class level validator that checks if that property is null, though that's a shame since it's functionally equivilent to the Required attribute.
bradwils
Contributor
5779 Points
691 Posts
Microsoft
Re: ValidationAttribute on enum type property?
Jan 16, 2010 07:13 PM|LINK
Validation only ensures that the values that were edited are valid. If we ran validaiton on all properties, whether they were edited or not, it would break partial-editing scenarios.
There are two ways to handle your radio button problem. The simpler one is to always ensure that at least one of the radio buttons was selected. The other way is to mimic what we do with check boxes: render an extra hidden input with the same name but a uniquely identifiable value. You'll need to write a special model binder to deal with the times where there are only one value (no radio button was selected) vs. two values (a radio button with selected).
SmallMike
Member
1 Points
4 Posts
Re: ValidationAttribute on enum type property?
Jan 17, 2010 12:09 AM|LINK
Playing some games with hidden fields did the trick. In fact, if the property is nullable, you can just spit out an extra radio button with an empty value and set the display style to "none". If the user does not select another value, it will bind to null and the Required validator catches it.
Thanks for the help!
- Mike