I developed my own custom htmlhelper for managing my radio buttons. No problems for generating basic html tag from my custom helper. But I have problems for injecting validation attributes in my html tag (client side unobtrusive validation). I used the htmlHelper.GetUnobtrusiveValidationAttributes(prefix) for retrieving validation attributes from my model (data annotations) but it doesn’work for my custom RequiredAttribute.
Here is a part of my view model:
public class MaterialEditNewViewModel
{
public int RequestId { get; set; }
[CustomRequired]
Public bool ADR { get; set; }
...
}
Here is my CustomRequired:
public class CustomRequiredAttribute : RequiredAttribute
{
public override string FormatErrorMessage(string name)
{
string translatedFieldName = UserResource.ResourceManager.GetString(name);
if (string.IsNullOrWhiteSpace(translatedFieldName))
translatedFieldName = name;
return string.Format(UserResource.FieldRequired, translatedFieldName);
}
}
Here is my custom html helper:
public static IHtmlString RadioButtonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object value, string labelText)
{
var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
string prefix = ExpressionHelper.GetExpressionText(expression);
var validationAttributes = htmlHelper.GetUnobtrusiveValidationAttributes(prefix);
object currentValue = metadata.Model;
string property = metadata.PropertyName;
// Build the radio button html tag
var htmlRadio = new TagBuilder("input");
htmlRadio.GenerateId(property + value);
htmlRadio.Attributes["type"] = "radio";
htmlRadio.Attributes["name"] = property;
htmlRadio.Attributes["value"] = Convert.ToString(value);
foreach (KeyValuePair<string, object> pair in validationAttributes)
{
htmlRadio.MergeAttribute(pair.Key, pair.Value.ToString());
}
if (object.Equals(currentValue, value))
{
htmlRadio.Attributes["checked"] = "checked";
}
// Build the label html tag
var label = new TagBuilder("label");
label.Attributes["for"] = htmlRadio.Attributes["id"];
label.SetInnerText(labelText);
// Return the concatenation of both tags
return new HtmlString(htmlRadio.ToString(TagRenderMode.SelfClosing) + label.ToString()
);
}
-
You have to know that my CustomRequired data annotation works for basic helper like @Html.RadioButtonFor(model => model.ADR) but it doesn’t work when used on custom htmlhelpers.
-
I know that when I use ‘classic’ data annotation like [Required] in my model I have no problems retrieving validation attributes BUT when using my CustomRequiredAttribute the GetUnobtrusiveValidationAttributes returns nothing!
Any idea why? If I’m not clear, don’t hesitate to ask me to clarify.
I forgot to say that I use Entity Framework Code First with MVC3.
Thanks.
Since the RequiredAttribute doesn’t implement the IClientValidatable interface you must register a custom adapter for your custom attribute. You could do this by adding the following line in
Application_Start:There are 2 ways to implement client side validation attributes:
IClientValidatableinterfaceThe
RequiredAttributeuses the second approach. It associates theRequiredAttributeAdapterto all required attributes. But since you have derived from the RequiredAttribute, your custom attribute no longer has the adapter. So you need to register it inApplication_Start.