The problem with the solution from Gregoire and Faxanadu is that the "*" is always displayed, also when the field is validated using the normal validation and you use 'Html.ValidationMessageFor()'.
So if you use the html extension like this:
@Html.EditorFor(model => model.Email)
@Html.RequiredFieldFor(model => model.Email)
@Html.ValidationMessageFor(model => model.Email)
You'll see duplicate * in case the field has validation errors.
I've made this modified extension, based on this which does also check if the field was validated.
private static Type[] RequiredTypes = new Type[] { typeof(CustomRequiredAttribute), typeof(RequiredAttribute) };
/// <summary>
/// Generate a <span class="field-validation-error">*<< element.
///
/// See http://koenluyten.blogspot.com/2011/06/denote-required-fields-in-aspnet-mvc-3.html
/// </summary>
public static MvcHtmlString RequiredFieldFor<TModel, TValue>(this HtmlHelper<TModel> html,
Expression<Func<TModel, TValue>> expression, string validationMessage = "*")
{
// Get the metadata for the model
var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
string fieldName = metadata.PropertyName;
// Check if the field is required
bool isRequired = metadata
.ContainerType.GetProperty(fieldName)
.GetCustomAttributes(false)
.Count(m => RequiredTypes.Contains(m.GetType())) > 0;
// Check if the field is validated
bool isValidated = html.ViewData.ModelState[fieldName] != null;
// If the field is required and not validated; generate span with an asterix
if (isRequired && !isValidated)
{
var span = new TagBuilder("span");
span.AddCssClass("field-validation-error");
span.SetInnerText(validationMessage);
return MvcHtmlString.Create(span.ToString(TagRenderMode.Normal));
}
return null;
}