static void

ASP MVC HtmlHelpers

Inline HtmlHelpers

@helper RazorInlineHelper(IEnumerable<string> names)
{
    <ul>
        @foreach (var name in names)
        {
            <li>@name</li>
        }
    </ul>
}

External HtmlHelpers

See Simple Paging

To be in scope, add a using or in the Views/web.config
(NB: in Views and Area/Views, not the parent website)
add <system.web.webPages.razor>
   <pages [...]>
      <namespaces>
         <add namespace="MvcApplication1.HtmlHelpers"/>

Built-in Helpers

Strong typed helpers

The Html.XFor(lamda) functions are strongly typed versions of the Html.X("name") helpers. They use Data Annotations

Adding attributes:

@Html.TextBoxFor(x => x.Name, new { @class = "long" })
 

.net naming doesn't match html attribute naming so...

Note it doesn't work with @Html.EditorFor - you have to use the specific input type like @Html.TextBoxFor.

From MVC 5.1 (January 2014) you can use nested anonymous objects for Html.EditorFor(). If you change between TextFor and EditorFor, it won't work.

@Html.EditorFor(model => model.RequestDate, 
   new { htmlAttributes = new { @class = "form-control", type="date" } })
@Html.TextBoxFor(model => model.RequestDate, 
   new { @class = "form-control", type = "date" } )

If you're using the HTML5 date input, you need to use yymmdd format, so easiest is to add data annotations. You'll need ApplyFormatInEditMode so it can bind the posted value too.

[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? RequestDate { getset; }
View HtmlHelpers use the POSTed values by preference (not the Model). Setting a model.Property in a postback does nothing. To make it work, do this:

ModelState.Remove("HasBeenPosted"); //so the model value isn't overridden
model.HasBeenPosted = true;

Urls

Radio Buttons

Because they have the same name/id, Html.LabelFor doesn't work. You could rename the id with attributes (

@foreach (var value in Enum.GetValues(typeof(ComputerLanguage)))
{
    <label>@Html.RadioButtonFor(m => m.ComputerLanguage, value) @value</label>
}

For the untyped helper, the third parameter indicates if it is checked.

 @Html.RadioButton("ComputerLanguage", "CSharp", true)

DropDownList

To render HTML Selects, you can use Html.DropDownList(name, SelectList)/Html.DropDownListFor(m => m.Propety, SelectList)
A SelectList (and MultiSelectList) can be constructed with an IEnumerable of SelectListItems.
A simple string list (selected item is set automatically here)

@Html.DropDownListFor(m => m.Language,
    new SelectList(new[] { "EN", "FR", "DE", "ES", "IT", "NL" }))

DropDownListFor entity relations

Entities don't work as well as simple types. The SelectLists are often put on the viewmodel rather than built in the view. If you get a dropdown of System.Web.Mvc.SelectListItem, it's because the SelectList is doing reflection on the SelectListItems you're putting in (you need to name the text/value properties, or just use an IEnumerable of SelectListItems).

@Html.DropDownListFor(m => m.Category,
    new SelectList(ViewBag.Categories,
                   dataTextField: "CategoryName",
                   dataValueField: "Id",
                   selectedValue: Model.Category.Id),
    "--Please select--")

But this setting the selected item is a little tricky. The easiest way is simply have an Id property (model.CategoryId) and not use the entity relationship.
Controller (or ViewModel):

ViewBag.CategoryList = categories.Select(x => new SelectListItem {Text = x.CategoryName, Value = x.Id.ToString()});

View:

@Html.DropDownListFor(m => m.CategoryId,
        (IEnumerable<SelectListItem>)ViewBag.CategoryList,
        "--Please select--")

Dropdownlist for Enum

Prior to MVC 5.1, it renders a textbox. After 5.1 (Jan 2014) there is a proper @Html.EnumDropDownListFor

You can get a simple dropdown with an Enum.GetValues:

@Html.DropDownListFor(model => model.State, new SelectList(Enum.GetValues(typeof(Domain.States))))

For more flexible use, prior to MVC 5.1:

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Mvc.Html;
 
namespace MvcApplication1
{
    public static class CustomHtmlHelpers
    {
        /// <summary>
        /// Dropdowns for enums. @Html.EnumDropDownListFor(m =&gt; m.Sex)
        /// </summary>
        public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper,
            Expression<Func<TModel, TEnum>> expression)
        {
            var metadata =
                ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
 
            var nonNullableType = metadata.ModelType;
            var underlyingType = Nullable.GetUnderlyingType(nonNullableType);
            if (underlyingType != null)
            {
                nonNullableType = underlyingType;
            }
 
            var items = (from value in
                            Enum.GetValues(nonNullableType).Cast<TEnum>()
                        select new SelectListItem
                        {
                            Text = value.ToString(), //could look for [Description] attribute
                            Value = value.ToString(), //default binder can use string
                            Selected = value.Equals(metadata.Model)
                        }).ToList();
 
            if (metadata.IsNullableValueType)
            {
                var empty = new SelectListItem { Text = string.Empty, Value = string.Empty };
                items.Insert(0, empty);
            }
 
            return htmlHelper.DropDownListFor(expression, items);
        }
    }
 
    public static MvcHtmlString EnumRadioListFor<TModel, TEnum>(
        this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TEnum>> expression)
    {
        var metadata =
            ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        var nonNullableType = metadata.ModelType;
        var underlyingType = Nullable.GetUnderlyingType(nonNullableType);
        if (underlyingType != null)
        {
            nonNullableType = underlyingType;
        }
 
        var names = Enum.GetNames(nonNullableType);
        var sb = new StringBuilder();
        //respect the hierarchy
        var prefix = htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix;
        if (string.IsNullOrWhiteSpace(prefix))
            prefix = null;
        else
            prefix += "_";
        foreach (var name in names)
        {
            //id is format "propertyName_enum".
            var id = string.Format("{0}{1}_{2}",
                            prefix,
                            metadata.PropertyName,
                            name);
            //use the standard template and turn it into a string
            var radio = htmlHelper.RadioButtonFor(expression, name, new { id })
                .ToHtmlString();
            sb.AppendFormat("<label for=\"{0}\">{1}</label> {2}",
                            id,
                        HttpUtility.HtmlEncode(name),
                            radio);
        }
        return MvcHtmlString.Create(sb.ToString());
    }

}