Search code examples
asp.net-mvcrazorrenderingasp.net-mvc-migration

Razor: Cannot render Html.Label helper in a @Section (outputting source only)


I was unable to figure out how to use @class inside Html.LabelFor, so I updated an extension helper for Html.Label with code found on SO.

My LabelExtension.cs file has the following class:

 public static class LabelExtensions
    {
        public static string Label(this HtmlHelper helper,
                                string labelFor,
                                string value,
                                object htmlAttributes)
        {
            TagBuilder labelBuilder = new TagBuilder("label");
            if (!string.IsNullOrEmpty(labelFor))
            {
                labelBuilder.Attributes.Add("for", labelFor);
            }
            labelBuilder.MergeAttributes(new RouteValueDictionary(htmlAttributes));
            labelBuilder.SetInnerText(value);
            return labelBuilder.ToString(TagRenderMode.Normal);
        } 
    }

I originally used the following in a MVC2 .aspx page thusly (which I am converting to .cshtml):

<% Html.BeginForm(); %> <%= Html.Label("txt_name_udq", "Your First Name (required):",
                new {
                @class
                = "mylabelstyle" } )%>
                <br />
                <%= Html.TextBox("txt_name_udq", null, new {
                @class
                = "myinputstyle" } )%>
                <br />
                <%= Html.Label("txt_email_udq", "Your E-Mail Address (required):", new {
                @class
                = "mylabelstyle" } )%>
                <br />
                <%= Html.TextBox("txt_email_udq", null, new {
                @class
                = "myinputstyle" })%>
                <br />
                <% Html.EndForm(); %>

This rendered very well in MVC2 (I left out usings and such for brevity) . However, today while converting to .cshtml (using a _layout.cshtml) I found that the Html.Label is not rendering and instead outputting source. Here is the code:

@section QuoteForm
{
    <div class="entryfull">
        <div class="entryfull_box">
            <div class="entryfull_text">
                <h2>
                    Quote Request
                </h2>
                <ul class="ul-check">
                    <li>Free</li>
                    <li>Confidential</li>
                    <li>Anonymous</li>
                    <li>No Obligation</li>
                </ul>
                @using (Html.BeginForm())
                {
                    @Html.Label("txt_name_udq", "Your First Name (required):", new { @class = "mylabelstyle" })
                    <br />
                    @Html.TextBox("txt_name_udq", null, new { @class = "myinputstyle" })
                    <br />
                    @Html.Label("txt_email_udq", "Your E-Mail Address (required):", new { @class = "mylabelstyle" })
                    <br />
                    @Html.TextBox("txt_email_udq", null, new { @class = "myinputstyle" })
                    <br />
                }
            </div>
        </div>
    </div>
}

The above is just something simple, not final product. I am just trying to get it to render first. Note: 1) I tried various iterations of Html.BeginForm; and 2) I even enclosed it in . Still, its not "working".

Here is what you see on the browser for the label (source outputted in browswer), right above the textbox (which renders):

<label class="mylabelstyle" for="txt_name_udq">Your First Name (required):</label>;

And if you "View Source", here is what you see:

&lt;label class=&quot;mylabelstyle&quot; for=&quot;txt_name_udq&quot;&gt;Your First Name (required):&lt;/label&gt;;

Is this something to do with @section? Or is it that I am trying to use an extension from MVC2?

Thanks in advance for any thoughts/advice.

EDIT: This is the code I reference in the comment that worked in my situation. Thanks for the help.

public static MvcHtmlString Label(this HtmlHelper htmlHelper, string labelFor, string value,
                                      object htmlAttributes)
    {
        var tagBuilder = new TagBuilder("label");
        tagBuilder.MergeAttributes(new RouteValueDictionary(htmlAttributes));
        tagBuilder.MergeAttribute("for", labelFor.Replace(".", tagBuilder.IdAttributeDotReplacement), true);
        tagBuilder.SetInnerText(value);
        return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.Normal));
    }

Solution

  • That is because your helper is returning a string and that is encoded by default. Your helper should return MvcHtmlString and change the return statement to

     return new MvcHtmlString(labelBuilder.ToString(TagRenderMode.Normal));