We have a model with properties decorated with [Required] which works great for validation. However, what we'd like to do is mark those required fields in the view with an asterisk (or some other style) to denote they are required before the user enters any data for validation.
I don't seem to be able to find anything built into the MVC framework to allow me to do this and therefore wondered if anyone else had already solved this and how?
Ultimately what we're trying to prevent is the need to change code in two places if we subsequently remove a [Required] from a model property.
Many Thanks
You can build your own HtmlHelper extension for this:
public static string RequiredMarkFor<TModel, TValue>(this HtmlHelper html, Expression<Func<TModel, TValue>> expression)
{
if(ModelMetadata.FromLambdaExpression(expression, html.ViewData).IsRequired)
return "*";
else
return string.Empty;
}
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With