Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Define markup for [Required] fields in View in ASP.NET MVC 2.0

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

like image 550
Darren Lewis Avatar asked Dec 18 '25 18:12

Darren Lewis


2 Answers

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;
}
like image 163
Gregoire Avatar answered Dec 20 '25 12:12

Gregoire


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 &lt;span class="field-validation-error"&gt;*&lt;&lt; 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;
}
like image 32
Stef Heyenrath Avatar answered Dec 20 '25 12:12

Stef Heyenrath



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!