Add remaining HTML input helpers

- add `CheckBox[For]()`, `Hidden[For]()`, `Password[For]()`, and
  `RadioButton[For]()`
- also make `FormatValue()` visible to users, as it is in legacy MVC
- and spread the boxes out a bit in MyView 😺
This commit is contained in:
dougbu 2014-04-08 19:50:06 -07:00
parent b1fd5cc689
commit f0a97772f5
7 changed files with 572 additions and 11 deletions

View File

@ -79,6 +79,7 @@ namespace MvcSample.Web
Alive = true,
Age = 13,
GPA = 13.37M,
Password = "Secure string",
Dependent = new User()
{
Name = "Dependents name",

View File

@ -12,5 +12,6 @@ namespace MvcSample.Web.Models
public decimal GPA { get; set; }
public User Dependent { get; set; }
public bool Alive { get; set; }
public string Password { get; set; }
}
}

View File

@ -141,6 +141,7 @@
<div style="float: left; border: thick solid lightskyblue; margin-bottom: 10px; margin-top: -180px; padding-right: 10px">
@using (Html.BeginForm(controllerName: "Home", actionName: "Hello", method: FormMethod.Post))
{
@Html.HiddenFor(m => m.Age)
<table>
<tr>
<td>
@ -160,13 +161,44 @@
</tr>
<tr>
<td>
<input type="submit" value="Save" class="btn btn-default" />
<label class="control-label col-md-2">Model.Alive</label>
</td>
<td>
@Html.CheckBox("Alive")
or
@Html.RadioButton("Alive", value: false) False
@Html.RadioButton("Alive", value: true) True
</td>
</tr>
<tr>
<td>
<label class="control-label col-md-2">Model.Dependent.Alive</label>
</td>
<td>
@Html.CheckBoxFor(m => m.Dependent.Alive)
or
@Html.RadioButtonFor(m => m.Dependent.Alive, value: false) False
@Html.RadioButtonFor(m => m.Dependent.Alive, value: true) True
</td>
</tr>
<tr>
<td>
<label class="control-label col-md-2">Model.Password</label>
</td>
<td>
@Html.PasswordFor(m => m.Password, htmlAttributes: new { @class = "form-control" })
</td>
</tr>
<tr>
<td>
<input type="submit" value="Save" class="btn btn-default" style="margin-left: 10px" />
</td>
<td></td>
</tr>
</table>
}
@{ Html.BeginForm(method: FormMethod.Post, htmlAttributes: new { someAttribute = "some value", }); }
@Html.Hidden("Anon.Id")
<table>
<tr>
<td>
@ -211,7 +243,15 @@
</tr>
<tr>
<td>
<input type="submit" value="Save" class="btn btn-default" />
<label class="control-label col-md-2">Password</label>
</td>
<td>
@Html.Password("Password", "some string")
</td>
</tr>
<tr>
<td>
<input type="submit" value="Save" class="btn btn-default" style="margin-left: 10px" />
</td>
<td></td>
</tr>
@ -273,7 +313,7 @@
</tr>
</table>
</div>
<div style="float: left; border: 5px solid green;">
<div style="float: left; border: 5px solid green; margin-left: 10px; margin-bottom: 10px; ">
<table>
<tr>
<td>

View File

@ -1,12 +1,12 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.IO;
using System.Net;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.Mvc.Core;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering.Expressions;
@ -50,8 +50,6 @@ namespace Microsoft.AspNet.Mvc.Rendering
public string IdAttributeDotReplacement { get; set; }
public HttpContext HttpContext { get; private set; }
public ViewContext ViewContext
{
get
@ -182,6 +180,11 @@ namespace Microsoft.AspNet.Mvc.Rendering
mvcForm.EndForm();
}
public HtmlString CheckBox(string name, bool? isChecked, object htmlAttributes)
{
return GenerateCheckBox(metadata: null, name: name, isChecked: isChecked, htmlAttributes: htmlAttributes);
}
public string Encode(string value)
{
return (!string.IsNullOrEmpty(value)) ? WebUtility.HtmlEncode(value) : string.Empty;
@ -225,6 +228,12 @@ namespace Microsoft.AspNet.Mvc.Rendering
additionalViewData);
}
public HtmlString Hidden(string name, object value, object htmlAttributes)
{
return GenerateHidden(metadata: null, name: name, value: value, useViewData: (value == null),
htmlAttributes: htmlAttributes);
}
public virtual HtmlString Name(string name)
{
var fullName = ViewData.TemplateInfo.GetFullHtmlFieldName(name);
@ -287,6 +296,17 @@ namespace Microsoft.AspNet.Mvc.Rendering
await viewEngineResult.View.RenderAsync(newViewContext);
}
public HtmlString Password(string name, object value, object htmlAttributes)
{
return GeneratePassword(metadata: null, name: name, value: value, htmlAttributes: htmlAttributes);
}
public HtmlString RadioButton(string name, object value, bool? isChecked, object htmlAttributes)
{
return GenerateRadioButton(metadata: null, name: name, value: value, isChecked: isChecked,
htmlAttributes: htmlAttributes);
}
public virtual HtmlString ValidationSummary(bool excludePropertyErrors, string message, IDictionary<string, object> htmlAttributes)
{
var formContext = ViewContext.ClientValidationEnabled ? ViewContext.FormContext : null;
@ -417,6 +437,16 @@ namespace Microsoft.AspNet.Mvc.Rendering
return new MvcForm(ViewContext);
}
protected bool EvalBoolean(string key)
{
return Convert.ToBoolean(ViewData.Eval(key), CultureInfo.InvariantCulture);
}
protected string EvalString(string key)
{
return Convert.ToString(ViewData.Eval(key), CultureInfo.CurrentCulture);
}
protected string EvalString(string key, string format)
{
return Convert.ToString(ViewData.Eval(key, format), CultureInfo.CurrentCulture);
@ -447,6 +477,54 @@ namespace Microsoft.AspNet.Mvc.Rendering
return new Dictionary<string, object>();
}
protected virtual HtmlString GenerateCheckBox(ModelMetadata metadata, string name, bool? isChecked,
object htmlAttributes)
{
if (metadata != null)
{
// CheckBoxFor() case. That API does not support passing isChecked directly.
Contract.Assert(!isChecked.HasValue);
if (metadata.Model != null)
{
bool modelChecked;
if (Boolean.TryParse(metadata.Model.ToString(), out modelChecked))
{
isChecked = modelChecked;
}
}
}
// Only need a dictionary if htmlAttributes is non-null. TagBuilder.MergeAttributes() is fine with null.
IDictionary<string, object> htmlAttributeDictionary = null;
if (htmlAttributes != null)
{
htmlAttributeDictionary = htmlAttributes as IDictionary<string, object>;
if (htmlAttributeDictionary == null)
{
htmlAttributeDictionary = AnonymousObjectToHtmlAttributes(htmlAttributes);
}
}
var explicitValue = isChecked.HasValue;
if (explicitValue && htmlAttributeDictionary != null)
{
// Explicit value must override dictionary
htmlAttributeDictionary.Remove("checked");
}
return GenerateInput(InputType.CheckBox,
metadata,
name,
value: "true",
useViewData: !explicitValue,
isChecked: isChecked ?? false,
setId: true,
isExplicitValue: false,
format: null,
htmlAttributes: htmlAttributeDictionary);
}
/// <summary>
/// Writes an opening <form> tag to the response. When the user submits the form,
/// the request will be processed by an action method.
@ -496,6 +574,38 @@ namespace Microsoft.AspNet.Mvc.Rendering
return theForm;
}
protected virtual HtmlString GenerateHidden(ModelMetadata metadata, string name, object value, bool useViewData,
object htmlAttributes)
{
// Only need a dictionary if htmlAttributes is non-null. TagBuilder.MergeAttributes() is fine with null.
IDictionary<string, object> htmlAttributeDictionary = null;
if (htmlAttributes != null)
{
htmlAttributeDictionary = htmlAttributes as IDictionary<string, object>;
if (htmlAttributeDictionary == null)
{
htmlAttributeDictionary = AnonymousObjectToHtmlAttributes(htmlAttributes);
}
}
var byteArrayValue = value as byte[];
if (byteArrayValue != null)
{
value = Convert.ToBase64String(byteArrayValue);
}
return GenerateInput(InputType.Hidden,
metadata,
name,
value,
useViewData,
isChecked: false,
setId: true,
isExplicitValue: true,
format: null,
htmlAttributes: htmlAttributeDictionary);
}
protected virtual HtmlString GenerateLink(
[NotNull] string linkText,
[NotNull] string url,
@ -512,6 +622,99 @@ namespace Microsoft.AspNet.Mvc.Rendering
return tagBuilder.ToHtmlString(TagRenderMode.Normal);
}
protected virtual HtmlString GeneratePassword(ModelMetadata metadata, string name, object value,
object htmlAttributes)
{
// Only need a dictionary if htmlAttributes is non-null. TagBuilder.MergeAttributes() is fine with null.
IDictionary<string, object> htmlAttributeDictionary = null;
if (htmlAttributes != null)
{
htmlAttributeDictionary = htmlAttributes as IDictionary<string, object>;
if (htmlAttributeDictionary == null)
{
htmlAttributeDictionary = AnonymousObjectToHtmlAttributes(htmlAttributes);
}
}
return GenerateInput(InputType.Password,
metadata,
name,
value,
useViewData: false,
isChecked: false,
setId: true,
isExplicitValue: true,
format: null,
htmlAttributes: htmlAttributeDictionary);
}
protected virtual HtmlString GenerateRadioButton(ModelMetadata metadata, string name, object value,
bool? isChecked, object htmlAttributes)
{
// Only need a dictionary if htmlAttributes is non-null. TagBuilder.MergeAttributes() is fine with null.
IDictionary<string, object> htmlAttributeDictionary = null;
if (htmlAttributes != null)
{
htmlAttributeDictionary = htmlAttributes as IDictionary<string, object>;
if (htmlAttributeDictionary == null)
{
htmlAttributeDictionary = AnonymousObjectToHtmlAttributes(htmlAttributes);
}
}
if (metadata == null)
{
// RadioButton() case. Do not override checked attribute if isChecked is implicit.
if (!isChecked.HasValue &&
(htmlAttributeDictionary == null || !htmlAttributeDictionary.ContainsKey("checked")))
{
// Note value may be null if isChecked is non-null.
if (value == null)
{
throw new ArgumentNullException("value");
}
// isChecked not provided nor found in the given attributes; fall back to view data.
var valueString = Convert.ToString(value, CultureInfo.CurrentCulture);
isChecked = !string.IsNullOrEmpty(name) &&
string.Equals(EvalString(name), valueString, StringComparison.OrdinalIgnoreCase);
}
}
else
{
// RadioButtonFor() case. That API does not support passing isChecked directly.
Contract.Assert(!isChecked.HasValue);
if (value == null)
{
// Need a value to determine isChecked.
throw new ArgumentNullException("value");
}
var model = metadata.Model;
var valueString = Convert.ToString(value, CultureInfo.CurrentCulture);
isChecked = model != null &&
string.Equals(model.ToString(), valueString, StringComparison.OrdinalIgnoreCase);
}
var explicitValue = isChecked.HasValue;
if (explicitValue && htmlAttributeDictionary != null)
{
// Explicit value must override dictionary
htmlAttributeDictionary.Remove("checked");
}
return GenerateInput(InputType.Radio,
metadata,
name,
value,
useViewData: false,
isChecked: isChecked ?? false,
setId: true,
isExplicitValue: true,
format: null,
htmlAttributes: htmlAttributeDictionary);
}
protected virtual HtmlString GenerateTextBox(ModelMetadata metadata, string name, object value, string format,
IDictionary<string, object> htmlAttributes)
{
@ -531,8 +734,9 @@ namespace Microsoft.AspNet.Mvc.Rendering
object value, bool useViewData, bool isChecked, bool setId, bool isExplicitValue, string format,
IDictionary<string, object> htmlAttributes)
{
// Not valid to use TextBoxForModel() in a top-level view; would end up with an unnamed input elements.
// But we support the *ForModel() methods in any lower-level template, once HtmlFieldPrefix is non-empty.
// Not valid to use TextBoxForModel() and so on in a top-level view; would end up with an unnamed input
// elements. But we support the *ForModel() methods in any lower-level template, once HtmlFieldPrefix is
// non-empty.
var fullName = ViewData.TemplateInfo.GetFullHtmlFieldName(name);
if (string.IsNullOrEmpty(fullName))
{
@ -545,8 +749,51 @@ namespace Microsoft.AspNet.Mvc.Rendering
tagBuilder.MergeAttribute("name", fullName, replaceExisting: true);
var valueParameter = FormatValue(value, format);
var usedModelState = false;
switch (inputType)
{
case InputType.CheckBox:
var modelStateWasChecked = GetModelStateValue(fullName, typeof(bool)) as bool?;
if (modelStateWasChecked.HasValue)
{
isChecked = modelStateWasChecked.Value;
usedModelState = true;
}
goto case InputType.Radio;
case InputType.Radio:
if (!usedModelState)
{
var modelStateValue = GetModelStateValue(fullName, typeof(string)) as string;
if (modelStateValue != null)
{
isChecked = string.Equals(modelStateValue, valueParameter, StringComparison.Ordinal);
usedModelState = true;
}
}
if (!usedModelState && useViewData)
{
isChecked = EvalBoolean(fullName);
}
if (isChecked)
{
tagBuilder.MergeAttribute("checked", "checked");
}
tagBuilder.MergeAttribute("value", valueParameter, isExplicitValue);
break;
case InputType.Password:
if (value != null)
{
tagBuilder.MergeAttribute("value", valueParameter, isExplicitValue);
}
break;
case InputType.Text:
default:
var attributeValue = (string)GetModelStateValue(fullName, typeof(string));
@ -573,6 +820,23 @@ namespace Microsoft.AspNet.Mvc.Rendering
tagBuilder.MergeAttributes(GetValidationAttributes(name, metadata));
if (inputType == InputType.CheckBox)
{
// Generate an additional <input type="hidden".../> for checkboxes. This
// addresses scenarios where unchecked checkboxes are not sent in the request.
// Sending a hidden input makes it possible to know that the checkbox was present
// on the page when the request was submitted.
var inputItemBuilder = new StringBuilder();
inputItemBuilder.Append(tagBuilder.ToString(TagRenderMode.SelfClosing));
var hiddenInput = new TagBuilder("input");
hiddenInput.MergeAttribute("type", GetInputTypeString(InputType.Hidden));
hiddenInput.MergeAttribute("name", fullName);
hiddenInput.MergeAttribute("value", "false");
inputItemBuilder.Append(hiddenInput.ToString(TagRenderMode.SelfClosing));
return new HtmlString(inputItemBuilder.ToString());
}
return tagBuilder.ToHtmlString(TagRenderMode.SelfClosing);
}
@ -611,7 +875,6 @@ namespace Microsoft.AspNet.Mvc.Rendering
return new HtmlString(Encode(resolvedValue));
}
private static string GetInputTypeString(InputType inputType)
{
switch (inputType)

View File

@ -47,7 +47,16 @@ namespace Microsoft.AspNet.Mvc.Rendering
base.Contextualize(viewContext);
}
/// <inheritdoc />
public HtmlString CheckBoxFor([NotNull] Expression<Func<TModel, bool>> expression,
object htmlAttributes)
{
var metadata = GetModelMetadata(expression);
return GenerateCheckBox(metadata, GetExpressionName(expression), isChecked: null,
htmlAttributes: htmlAttributes);
}
/// <inheritdoc />
public HtmlString DisplayFor<TValue>([NotNull] Expression<Func<TModel, TValue>> expression,
string templateName,
string htmlFieldName,
@ -63,6 +72,15 @@ namespace Microsoft.AspNet.Mvc.Rendering
additionalViewData);
}
/// <inheritdoc />
public HtmlString HiddenFor<TProperty>([NotNull] Expression<Func<TModel, TProperty>> expression,
object htmlAttributes)
{
var metadata = GetModelMetadata(expression);
return GenerateHidden(metadata, GetExpressionName(expression), metadata.Model, useViewData: false,
htmlAttributes: htmlAttributes);
}
/// <inheritdoc />
public HtmlString NameFor<TProperty>([NotNull] Expression<Func<TModel, TProperty>> expression)
{
@ -70,6 +88,24 @@ namespace Microsoft.AspNet.Mvc.Rendering
return Name(expressionName);
}
/// <inheritdoc />
public HtmlString PasswordFor<TProperty>([NotNull] Expression<Func<TModel, TProperty>> expression,
object htmlAttributes)
{
var metadata = GetModelMetadata(expression);
return GeneratePassword(metadata, GetExpressionName(expression), value: null,
htmlAttributes: htmlAttributes);
}
/// <inheritdoc />
public HtmlString RadioButtonFor<TProperty>([NotNull] Expression<Func<TModel, TProperty>> expression,
object value, object htmlAttributes)
{
var metadata = GetModelMetadata(expression);
return GenerateRadioButton(metadata, GetExpressionName(expression), value, isChecked: null,
htmlAttributes: htmlAttributes);
}
/// <inheritdoc />
public HtmlString TextBoxFor<TProperty>([NotNull] Expression<Func<TModel, TProperty>> expression,
string format, IDictionary<string, object> htmlAttributes)
@ -95,10 +131,12 @@ namespace Microsoft.AspNet.Mvc.Rendering
return metadata;
}
/// <inheritdoc />
public HtmlString ValueFor<TProperty>(Expression<Func<TModel, TProperty>> expression, string format)
{
var metadata = GetModelMetadata(expression);
return GenerateValue(ExpressionHelper.GetExpressionText(expression), metadata.Model, format, useViewData: false);
return GenerateValue(ExpressionHelper.GetExpressionText(expression), metadata.Model, format,
useViewData: false);
}
}
}

View File

@ -1,12 +1,92 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
namespace Microsoft.AspNet.Mvc.Rendering
{
public static class HtmlHelperInputExtensions
{
public static HtmlString CheckBox<TModel>([NotNull] this IHtmlHelper<TModel> htmlHelper, string name)
{
return htmlHelper.CheckBox(name, isChecked: null, htmlAttributes: null);
}
public static HtmlString CheckBox<TModel>([NotNull] this IHtmlHelper<TModel> htmlHelper, string name,
bool isChecked)
{
return htmlHelper.CheckBox(name, isChecked, htmlAttributes: null);
}
public static HtmlString CheckBox<TModel>([NotNull] this IHtmlHelper<TModel> htmlHelper, string name,
object htmlAttributes)
{
return htmlHelper.CheckBox(name, isChecked: null, htmlAttributes: htmlAttributes);
}
public static HtmlString CheckBoxFor<TModel>([NotNull] this IHtmlHelper<TModel> htmlHelper,
[NotNull] Expression<Func<TModel, bool>> expression)
{
return htmlHelper.CheckBoxFor(expression, htmlAttributes: null);
}
public static HtmlString Hidden<TModel>([NotNull] this IHtmlHelper<TModel> htmlHelper, string name)
{
return htmlHelper.Hidden(name, value: null, htmlAttributes: null);
}
public static HtmlString Hidden<TModel>([NotNull] this IHtmlHelper<TModel> htmlHelper, string name,
object value)
{
return htmlHelper.Hidden(name, value, htmlAttributes: null);
}
public static HtmlString HiddenFor<TModel, TProperty>([NotNull] this IHtmlHelper<TModel> htmlHelper,
[NotNull] Expression<Func<TModel, TProperty>> expression)
{
return htmlHelper.HiddenFor(expression, htmlAttributes: null);
}
public static HtmlString Password<TModel>([NotNull] this IHtmlHelper<TModel> htmlHelper, string name)
{
return htmlHelper.Password(name, value: null, htmlAttributes: null);
}
public static HtmlString Password<TModel>([NotNull] this IHtmlHelper<TModel> htmlHelper, string name,
object value)
{
return htmlHelper.Password(name, value, htmlAttributes: null);
}
public static HtmlString PasswordFor<TModel, TProperty>([NotNull] this IHtmlHelper<TModel> htmlHelper,
[NotNull] Expression<Func<TModel, TProperty>> expression)
{
return htmlHelper.PasswordFor(expression, htmlAttributes: null);
}
public static HtmlString RadioButton<TModel>([NotNull] this IHtmlHelper<TModel> htmlHelper, string name,
object value)
{
return htmlHelper.RadioButton(name, value, isChecked: null, htmlAttributes: null);
}
public static HtmlString RadioButton<TModel>([NotNull] this IHtmlHelper<TModel> htmlHelper, string name,
object value, object htmlAttributes)
{
return htmlHelper.RadioButton(name, value, isChecked: null, htmlAttributes: htmlAttributes);
}
public static HtmlString RadioButton<TModel>([NotNull] this IHtmlHelper<TModel> htmlHelper, string name,
object value, bool isChecked)
{
return htmlHelper.RadioButton(name, value, isChecked, htmlAttributes: null);
}
public static HtmlString RadioButtonFor<TModel, TProperty>([NotNull] this IHtmlHelper<TModel> htmlHelper,
[NotNull] Expression<Func<TModel, TProperty>> expression, object value)
{
return htmlHelper.RadioButtonFor(expression, value, htmlAttributes: null);
}
public static HtmlString TextBox<TModel>([NotNull] this IHtmlHelper<TModel> htmlHelper, string name)
{
return TextBox(htmlHelper, name, value: null);

View File

@ -86,6 +86,37 @@ namespace Microsoft.AspNet.Mvc.Rendering
/// </summary>
void EndForm();
/// <summary>
/// Render an input element of type "checkbox" with value "true" and an input element of type "hidden" with
/// value "false".
/// </summary>
/// <param name="name">
/// Rendered element's name. Also use this name to find value in submitted data or view data. Use view data
/// only if value is not in submitted data and <paramref name="value"/> is <c>null</c>.
/// </param>
/// <param name="isChecked">
/// If <c>true</c>, checkbox is initially checked. Ignore if named value is found in submitted data. Finally
/// fall back to an existing "checked" value in <paramref name="htmlAttributes"/>.
/// </param>
/// <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.
/// Alternatively, an <see cref="IDictionary{string, object}"/> instance containing the HTML attributes.
/// </param>
/// <returns>New <see cref="HtmlString"/> containing the rendered HTML.</returns>
HtmlString CheckBox(string name, bool? isChecked, object htmlAttributes);
/// <summary>
/// Render an input element of type "checkbox" with value "true" and an input element of type "hidden" with
/// value "false".
/// </summary>
/// <param name="expression">
/// An expression that identifies the object that contains the properties to render.
/// </param>
/// <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.
/// Alternatively, an <see cref="IDictionary{string, object}"/> instance containing the HTML attributes.
/// </param>
/// <returns>New <see cref="HtmlString"/> containing the rendered HTML.</returns>
HtmlString CheckBoxFor([NotNull] Expression<Func<TModel, bool>> expression, object htmlAttributes);
/// <summary>
/// Returns HTML markup for each property in the object that is represented by the expression, using the specified
/// template, HTML field ID, and additional view data.
@ -158,6 +189,14 @@ namespace Microsoft.AspNet.Mvc.Rendering
/// <returns>The HTML-encoded string.</returns>
string Encode(string value);
/// <summary>
/// Formats the value.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="format">The format string.</param>
/// <returns>The formatted value.</returns>
string FormatValue(object value, string format);
/// <summary>
/// Creates an HTML element ID using the specified element name.
/// </summary>
@ -165,6 +204,35 @@ namespace Microsoft.AspNet.Mvc.Rendering
/// <returns>The ID of the HTML element.</returns>
string GenerateIdFromName(string name);
/// <summary>
/// Render an input element of type "hidden".
/// </summary>
/// <param name="name">
/// Rendered element's name. Also use this name to find value in submitted data or view data. Use view data
/// only if value is not in submitted data and <paramref name="value"/> is <c>null</c>.
/// </param>
/// <param name="value">
/// If non-<c>null</c>, value to include in the element. Ignore if named value is found in submitted data.
/// </param>
/// <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.
/// Alternatively, an <see cref="IDictionary{string, object}"/> instance containing the HTML attributes.
/// </param>
/// <returns>New <see cref="HtmlString"/> containing the rendered HTML.</returns>
HtmlString Hidden(string name, object value, object htmlAttributes);
/// <summary>
/// Render an input element of type "hidden".
/// </summary>
/// <param name="expression">
/// An expression that identifies the object that contains the properties to render.
/// </param>
/// <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.
/// Alternatively, an <see cref="IDictionary{string, object}"/> instance containing the HTML attributes.
/// </param>
/// <returns>New <see cref="HtmlString"/> containing the rendered HTML.</returns>
HtmlString HiddenFor<TProperty>([NotNull] Expression<Func<TModel, TProperty>> expression,
object htmlAttributes);
/// <summary>
/// Gets the full HTML field name for the given expression <paramref name="name"/>.
/// </summary>
@ -180,6 +248,76 @@ namespace Microsoft.AspNet.Mvc.Rendering
/// <returns>An <see cref="HtmlString"/> that represents HTML markup.</returns>
HtmlString NameFor<TProperty>([NotNull] Expression<Func<TModel, TProperty>> expression);
/// <summary>
/// Render an input element of type "password".
/// </summary>
/// <param name="name">
/// Rendered element's name. Also use this name to find value in view data. Use view data
/// only if value is not in submitted data and <paramref name="value"/> is <c>null</c>.
/// </param>
/// <param name="value">
/// If non-<c>null</c>, value to include in the element.
/// </param>
/// <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.
/// Alternatively, an <see cref="IDictionary{string, object}"/> instance containing the HTML attributes.
/// </param>
/// <returns>New <see cref="HtmlString"/> containing the rendered HTML.</returns>
HtmlString Password(string name, object value, object htmlAttributes);
/// <summary>
/// Render an input element of type "password".
/// </summary>
/// <param name="expression">
/// An expression that identifies the object that contains the properties to render.
/// </param>
/// <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.
/// Alternatively, an <see cref="IDictionary{string, object}"/> instance containing the HTML attributes.
/// </param>
/// <returns>New <see cref="HtmlString"/> containing the rendered HTML.</returns>
HtmlString PasswordFor<TProperty>([NotNull] Expression<Func<TModel, TProperty>> expression,
object htmlAttributes);
/// <summary>
/// Render an input element of type "radio".
/// </summary>
/// <param name="name">
/// Rendered element's name. Also use this name to find value in submitted data or view data. Use view data
/// only if value is not in submitted data and <paramref name="value"/> is <c>null</c>.
/// </param>
/// <param name="value">
/// If non-<c>null</c>, value to include in the element. May be <c>null</c> only if
/// <paramref name="isChecked"/> is also <c>null</c>. Also compared to value in submitted data or view data to
/// determine <paramref name="isChecked"/> if that parameter is <c>null</c>. Ignore if named value is found in
/// submitted data.
/// </param>
/// <param name="isChecked">
/// If <c>true</c>, radio button is initially selected. Ignore if named value is found in submitted data. Fall
/// back to comparing <paramref name="value"/> with view data if this parameter is <c>null</c>. Finally
/// fall back to an existing "checked" value in <paramref name="htmlAttributes"/>.
/// </param>
/// <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.
/// Alternatively, an <see cref="IDictionary{string, object}"/> instance containing the HTML attributes.
/// </param>
/// <returns>New <see cref="HtmlString"/> containing the rendered HTML.</returns>
HtmlString RadioButton(string name, object value, bool? isChecked, object htmlAttributes);
/// <summary>
/// Render an input element of type "radio".
/// </summary>
/// <param name="expression">
/// An expression that identifies the object that contains the properties to render.
/// </param>
/// <param name="value">
/// If non-<c>null</c>, value to compare with current expression value to determine whether radio button is
/// checked.
/// </param>
/// <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.
/// Alternatively, an <see cref="IDictionary{string, object}"/> instance containing the HTML attributes.
/// </param>
/// <returns>New <see cref="HtmlString"/> containing the rendered HTML.</returns>
HtmlString RadioButtonFor<TProperty>([NotNull] Expression<Func<TModel, TProperty>> expression, object value,
object htmlAttributes);
/// <summary>
/// Wraps HTML markup in an <see cref="HtmlString"/>, which will enable HTML markup to be
/// rendered to the output without getting HTML encoded.