I have a view where I use a dropdown list with enum:
public enum MaterialWorthEnumViewModel
{
[Display(Name = "")] Undefined,
[Display(Name = "< 1.000€")] LessThan1000,
[Display(Name = "1.000€ < 10.000€")] Between1000And10000,
[Display(Name = "10.000€ < 100.000€")] Between10000And100000,
[Display(Name = "100.000€ < 25.000.000€")] Between100000And25000000,
[Display(Name = "> 25.000.000€")] GreaterThan250000000,
}
I use a view model with this view:
public class MaterialEditNewViewModel
{
public int RequestID { get; set; }
...
[EnumRequired]
public MaterialWorthEnumViewModel MaterialWorth { get; set; }
}
As you can see above, I used a custom validation [EnumRequired] I grab the code from a blog online.
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
public class EnumRequiredAttribute : RequiredAttribute
{
private const string UNDEFINED_VALUE = "Undefined";
public string UndefinedValue { get; set; }
public EnumRequiredAttribute() : this(UNDEFINED_VALUE)
{ }
public EnumRequiredAttribute(string undefinedValue) : base()
{
if (String.IsNullOrWhiteSpace(undefinedValue))
{
throw new ArgumentNullException("undefinedValue");
}
UndefinedValue = undefinedValue;
}
public override bool IsValid(object value)
{
if (value == null)
{
return false;
}
var undefined = Enum.Parse(value.GetType(), UndefinedValue);
return !Enum.Equals(value, undefined);
}
}
Below is for the client side validation
public class ModelClientValidationEnumRequiredRule : ModelClientValidationRule
{
public ModelClientValidationEnumRequiredRule(string errorMessage, string undefinedValue)
{
base.ErrorMessage = errorMessage;
base.ValidationType = "enumrequired";
base.ValidationParameters.Add("undefinedvalue", undefinedValue);
}
}
public class EnumRequiredAttributeAdapter : DataAnnotationsModelValidator<EnumRequiredAttribute>
{
public EnumRequiredAttributeAdapter(ModelMetadata metadata, ControllerContext context, EnumRequiredAttribute attribute)
: base(metadata, context, attribute)
{ }
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{
return new ModelClientValidationEnumRequiredRule[]
{
new ModelClientValidationEnumRequiredRule(base.ErrorMessage, Attribute.UndefinedValue)
};
}
}
Below is the javascript for the client side validation
Sys.Mvc.ValidatorRegistry.validators.enumrequired = function (rule) {
var undefinedValue = rule.ValidationParameters.undefinedvalue;
return function (value, context) {
return value != undefinedValue;
}
}
I also updated my GLobal.asax file:
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(EnumRequiredAttribute), typeof(EnumRequiredAttributeAdapter));
The validation works pretty well on the server side but the client side validation is never triggered. So when I didn’t choose any value on my view for my dropdown enum, I reach the action in the controller and then the server side validation occured and I go back to the view. I concluded that the client side validation didn’t occurred.
Does someone can help me doing valid client side validation for this dropdown enum ?
Thanks. I’m a bit lost.
I don’t see any relationship between your
EnumRequiredAttributeand the other 2 classes. If you are using ASP.NET MVC 3 you need to associate your custom validation attribute with the adapter. This could be done inApplication_Start:Also on your client side you have shown some js code that relies on
Microsoft*.jslibraries. Those are now obsolete and should no longer be used. The default standard in ASP.NET MVC 3 for client side validation is the jquery.validate plugin.So let’s take an example.
Model:
Controller:
View (
Index.cshtml):and finally the
enumrequiredadapter.jsadapter:Also don’t forget to remove all traces of
Microsoft*.jsscript references from your site. And that’s pretty much it.