6

The following sample:

@Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })

appears to be using the second overload of the LabelFor method where the second parameter, htmlAttributes, is documented as

An object that contains the Html attributes for the element

What does the term "HTML attributes" mean and what is the syntax that can be used for this object?

2 Answers 2

11

HTML elements can have attributes. For example:

<div class="some-css-class" data-foo="bar" />

Here the div's attributes are class and data-foo.

Razor's various HTML helper functions that accept an htmlAttributes argument translate the provided object to attributes.

You can utilize this using an anonymous type where its properties are translated to attributes names, and their values to the respective attribute's value.

For example:

new
{
    @class = "some-css-class",
    data_foo = "bar"
}

This will translate to the attributes shown above.

Underscores in property names get translated to dashes (How to specify data attributes in razor, e.g., data-externalid="23151" on @this.Html.CheckBoxFor(...)), and the @ before @class is required because class is a reserved keyword that can't be used without escaping it with an @ (How can I add a class attribute to an HTML element generated by MVC's HTML Helpers?).

There's also an overload accepting IDictionary<string, object> htmlAttributes, so you could instead pass a dictionary as well:

new Dictionary<string, object>
{
    { "class", "some-css-class" },
    { "data-foo", "bar" }
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks. Why is there an @ before class?
Just to add to this, @class is prefixed with the @ because class is a reserved word in C#.
Because it's a reserved keyword that can't be used as a property name unless escaped with an @.
@ is an escape character in Razor. It is required in this situation because class is a reserved word in C# so it needs to be escaped.
0

I tried to dynamically set the htmlAttributes based on a ViewModel property. However when using an anonymous type the compiler can't resolve it if you are using different html attributes for each option. Naming the object 'Object' gives compiler errors on tagged properties like @class: "Object does not contain a definition for class'

Converting the object to a dictionary solves this issue.:

@Html.DropDownListFor(
    expression: model => model.BrandId,
    selectList: listItems,
    optionLabel: "Select an item",
    htmlAttributes: Model.IsNew
         ? new Dictionary<string, object> { { "class", "form-control input-xlarge" }, { "onchange", "doStuff()" } }
         : new Dictionary<string, object> { { "class", "form-control input-xlarge" }, { "disabled", "disabled" } } )

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.