ASP.NET MVC LabelFor overload for a required asterisk

ASP.NET MVC 25 November 2011 | 1 Comment

Today I was pondering an easy way to put a required red asterisk next to a label generated by ASP.NET MVC. My first thought was, ah ha! I can add it to the call like:

@Html.LabelFor(x => x.EmailAddress, "EmailAddress <span class="red">*</span>")

This obviously (if you remember) results in being encoded so the Html output on the page is:

EmailAddress <span class="red">*</span>

Time for a more elegant approach. I also wanted an overload to LabelFor to put some HTML attributes such as a class. Lets combine these two into an overload:

public static class HtmlLabelExtensions
{
    public static MvcHtmlString LabelFor(this HtmlHelper html, Expression> expression, object htmlAttributes, bool required = false)
    {
        return LabelFor(html, expression, new RouteValueDictionary(htmlAttributes), required);
    }
    public static MvcHtmlString LabelFor(this HtmlHelper html, Expression> expression, IDictionary htmlAttributes, bool required)
    {
        var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
        string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
        string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();
        if (String.IsNullOrEmpty(labelText))
        {
            return MvcHtmlString.Empty;
        }

        var tag = new TagBuilder("label");
        tag.MergeAttributes(htmlAttributes);
        tag.Attributes.Add("for", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName));

        if (required)
        {
            tag.InnerHtml = String.Format("{0} *", labelText);
        }
        else
        {
            tag.SetInnerText(labelText);
        }

        return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
    }
}

This extension now means we can call @Html.LabelFor like:

@Html.LabelFor(x => x.Name, new { @class="special-label" }, required: true)

And our HTML output is what we wanted. I’m not really sure why Html.LabelFor doesn’t have the HtmlAttributes overload to start with.

One Response on “ASP.NET MVC LabelFor overload for a required asterisk”

  1. Vladimir says:

    Hi, Phil!

    Thanks for post.

    I think ‘required’-property is redundant since by default required property is marked by the mvc-attribute [Required] and we can check it by ‘metadata.IsRequired’.

Leave a Reply