Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,86 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Web.Mvc;
using Microsoft.Internal.Web.Utils;
namespace System.Web.WebPages.Html
{
public partial class HtmlHelper
{
public IHtmlString CheckBox(string name)
{
return CheckBox(name, htmlAttributes: (IDictionary<string, object>)null);
}
public IHtmlString CheckBox(string name, object htmlAttributes)
{
return CheckBox(name, TypeHelper.ObjectToDictionary(htmlAttributes));
}
public IHtmlString CheckBox(string name, IDictionary<string, object> htmlAttributes)
{
if (String.IsNullOrEmpty(name))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "name");
}
return BuildCheckBox(name, null, htmlAttributes);
}
public IHtmlString CheckBox(string name, bool isChecked)
{
return CheckBox(name, isChecked, (IDictionary<string, object>)null);
}
public IHtmlString CheckBox(string name, bool isChecked, object htmlAttributes)
{
return CheckBox(name, isChecked, TypeHelper.ObjectToDictionary(htmlAttributes));
}
public IHtmlString CheckBox(string name, bool isChecked, IDictionary<string, object> htmlAttributes)
{
if (String.IsNullOrEmpty(name))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "name");
}
return BuildCheckBox(name, isChecked, htmlAttributes);
}
private IHtmlString BuildCheckBox(string name, bool? isChecked, IDictionary<string, object> attributes)
{
TagBuilder builder = new TagBuilder("input");
builder.MergeAttribute("type", "checkbox", replaceExisting: true);
builder.GenerateId(name);
builder.MergeAttributes(attributes, replaceExisting: true);
builder.MergeAttribute("name", name, replaceExisting: true);
if (UnobtrusiveJavaScriptEnabled)
{
var validationAttributes = _validationHelper.GetUnobtrusiveValidationAttributes(name);
builder.MergeAttributes(validationAttributes, replaceExisting: false);
}
var model = ModelState[name];
if (model != null && model.Value != null)
{
bool modelValue = (bool)ConvertTo(model.Value, typeof(bool));
isChecked = isChecked ?? modelValue;
}
if (isChecked.HasValue)
{
if (isChecked.Value == true)
{
builder.MergeAttribute("checked", "checked", replaceExisting: true);
}
else
{
builder.Attributes.Remove("checked");
}
}
AddErrorClass(builder, name);
return builder.ToHtmlString(TagRenderMode.SelfClosing);
}
}
}

View File

@@ -0,0 +1,178 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Data.Linq;
using System.Diagnostics.CodeAnalysis;
using System.Web.Mvc;
using Microsoft.Internal.Web.Utils;
namespace System.Web.WebPages.Html
{
public partial class HtmlHelper
{
private enum InputType
{
Text,
Password,
Hidden
}
public IHtmlString TextBox(string name)
{
if (String.IsNullOrEmpty(name))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "name");
}
return BuildInputField(name, InputType.Text, value: null, isExplicitValue: false,
attributes: (IDictionary<string, object>)null);
}
public IHtmlString TextBox(string name, object value)
{
return TextBox(name, value, htmlAttributes: (IDictionary<string, object>)null);
}
public IHtmlString TextBox(string name, object value, object htmlAttributes)
{
return TextBox(name, value, TypeHelper.ObjectToDictionary(htmlAttributes));
}
public IHtmlString TextBox(string name, object value, IDictionary<string, object> htmlAttributes)
{
if (String.IsNullOrEmpty(name))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "name");
}
return BuildInputField(name, InputType.Text, value, isExplicitValue: true, attributes: htmlAttributes);
}
public IHtmlString Hidden(string name)
{
if (String.IsNullOrEmpty(name))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "name");
}
return BuildInputField(name, InputType.Hidden, value: null, isExplicitValue: false,
attributes: (IDictionary<string, object>)null);
}
public IHtmlString Hidden(string name, object value)
{
return Hidden(name, value, htmlAttributes: (IDictionary<string, object>)null);
}
public IHtmlString Hidden(string name, object value, object htmlAttributes)
{
return Hidden(name, value, TypeHelper.ObjectToDictionary(htmlAttributes));
}
public IHtmlString Hidden(string name, object value, IDictionary<string, object> htmlAttributes)
{
if (String.IsNullOrEmpty(name))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "name");
}
return BuildInputField(name, InputType.Hidden, GetHiddenFieldValue(value), isExplicitValue: true,
attributes: htmlAttributes);
}
private static object GetHiddenFieldValue(object value)
{
Binary binaryValue = value as Binary;
if (binaryValue != null)
{
value = binaryValue.ToArray();
}
byte[] byteArrayValue = value as byte[];
if (byteArrayValue != null)
{
value = Convert.ToBase64String(byteArrayValue);
}
return value;
}
public IHtmlString Password(string name)
{
if (String.IsNullOrEmpty(name))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "name");
}
return BuildInputField(name, InputType.Password, null, isExplicitValue: false,
attributes: (IDictionary<string, object>)null);
}
public IHtmlString Password(string name, object value)
{
return Password(name, value, htmlAttributes: (IDictionary<string, object>)null);
}
public IHtmlString Password(string name, object value, object htmlAttributes)
{
return Password(name, value, TypeHelper.ObjectToDictionary(htmlAttributes));
}
public IHtmlString Password(string name, object value, IDictionary<string, object> htmlAttributes)
{
if (String.IsNullOrEmpty(name))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "name");
}
return BuildInputField(name, InputType.Password, value, isExplicitValue: true, attributes: htmlAttributes);
}
private IHtmlString BuildInputField(string name, InputType type, object value, bool isExplicitValue,
IDictionary<string, object> attributes)
{
TagBuilder tagBuilder = new TagBuilder("input");
// Implicit parameters
tagBuilder.MergeAttribute("type", GetInputTypeString(type));
tagBuilder.GenerateId(name);
// Overwrite implicit
tagBuilder.MergeAttributes(attributes, replaceExisting: true);
if (UnobtrusiveJavaScriptEnabled)
{
// Add validation attributes
var validationAttributes = _validationHelper.GetUnobtrusiveValidationAttributes(name);
tagBuilder.MergeAttributes(validationAttributes, replaceExisting: false);
}
// Function arguments
tagBuilder.MergeAttribute("name", name, replaceExisting: true);
var modelState = ModelState[name];
if ((type != InputType.Password) && modelState != null)
{
// Don't use model values for passwords
value = value ?? modelState.Value ?? String.Empty;
}
if ((type != InputType.Password) || ((type == InputType.Password) && (value != null)))
{
// Review: Do we really need to be this pedantic about sticking to mvc?
tagBuilder.MergeAttribute("value", (string)ConvertTo(value, typeof(string)), replaceExisting: isExplicitValue);
}
AddErrorClass(tagBuilder, name);
return tagBuilder.ToHtmlString(TagRenderMode.SelfClosing);
}
[SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "Input types are specified in lower case")]
private static string GetInputTypeString(InputType inputType)
{
if (!Enum.IsDefined(typeof(InputType), inputType))
{
inputType = InputType.Text;
}
return inputType.ToString().ToLowerInvariant();
}
}
}

View File

@@ -0,0 +1,119 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Web.Mvc;
using System.Web.WebPages.Resources;
namespace System.Web.WebPages.Html
{
public partial class HtmlHelper
{
private void AddErrorClass(TagBuilder tagBuilder, string name)
{
if (!ModelState.IsValidField(name))
{
tagBuilder.AddCssClass(ValidationInputCssClassName);
}
}
private static object ConvertTo(object value, Type type)
{
Debug.Assert(type != null);
return UnwrapPossibleArrayType(value, type, CultureInfo.InvariantCulture);
}
private static object UnwrapPossibleArrayType(object value, Type destinationType, CultureInfo culture)
{
if (value == null || destinationType.IsInstanceOfType(value))
{
return value;
}
// array conversion results in four cases, as below
Array valueAsArray = value as Array;
if (destinationType.IsArray)
{
Type destinationElementType = destinationType.GetElementType();
if (valueAsArray != null)
{
// case 1: both destination + source type are arrays, so convert each element
IList converted = Array.CreateInstance(destinationElementType, valueAsArray.Length);
for (int i = 0; i < valueAsArray.Length; i++)
{
converted[i] = ConvertSimpleType(valueAsArray.GetValue(i), destinationElementType, culture);
}
return converted;
}
else
{
// case 2: destination type is array but source is single element, so wrap element in array + convert
object element = ConvertSimpleType(value, destinationElementType, culture);
IList converted = Array.CreateInstance(destinationElementType, 1);
converted[0] = element;
return converted;
}
}
else if (valueAsArray != null)
{
// case 3: destination type is single element but source is array, so extract first element + convert
if (valueAsArray.Length > 0)
{
value = valueAsArray.GetValue(0);
return ConvertSimpleType(value, destinationType, culture);
}
else
{
// case 3(a): source is empty array, so can't perform conversion
return null;
}
}
// case 4: both destination + source type are single elements, so convert
return ConvertSimpleType(value, destinationType, culture);
}
private static object ConvertSimpleType(object value, Type destinationType, CultureInfo culture)
{
if (value == null || destinationType.IsInstanceOfType(value))
{
return value;
}
// if this is a user-input value but the user didn't type anything, return no value
string valueAsString = value as string;
if (valueAsString != null && valueAsString.Trim().Length == 0)
{
return null;
}
TypeConverter converter = TypeDescriptor.GetConverter(destinationType);
bool canConvertFrom = converter.CanConvertFrom(value.GetType());
if (!canConvertFrom)
{
converter = TypeDescriptor.GetConverter(value.GetType());
}
if (!(canConvertFrom || converter.CanConvertTo(destinationType)))
{
string message = String.Format(CultureInfo.CurrentCulture, WebPageResources.HtmlHelper_NoConverterExists,
value.GetType().FullName, destinationType.FullName);
throw new InvalidOperationException(message);
}
try
{
object convertedValue = (canConvertFrom)
? converter.ConvertFrom(context: null, culture: culture, value: value)
: converter.ConvertTo(context: null, culture: culture, value: value, destinationType: destinationType);
return convertedValue;
}
catch (Exception ex)
{
string message = String.Format(CultureInfo.CurrentUICulture, WebPageResources.HtmlHelper_ConversionThrew,
value.GetType().FullName, destinationType.FullName);
throw new InvalidOperationException(message, ex);
}
}
}
}

View File

@@ -0,0 +1,51 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Web.Mvc;
using Microsoft.Internal.Web.Utils;
namespace System.Web.WebPages.Html
{
public partial class HtmlHelper
{
public IHtmlString Label(string labelText)
{
return Label(labelText, null, (IDictionary<string, object>)null);
}
public IHtmlString Label(string labelText, string labelFor)
{
return Label(labelText, labelFor, (IDictionary<string, object>)null);
}
public IHtmlString Label(string labelText, object attributes)
{
return Label(labelText, null, TypeHelper.ObjectToDictionary(attributes));
}
public IHtmlString Label(string labelText, string labelFor, object attributes)
{
return Label(labelText, labelFor, TypeHelper.ObjectToDictionary(attributes));
}
public IHtmlString Label(string labelText, string labelFor, IDictionary<string, object> attributes)
{
if (String.IsNullOrEmpty(labelText))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "labelText");
}
labelFor = labelFor ?? labelText;
TagBuilder tag = new TagBuilder("label") { InnerHtml = Encode(labelText) };
if (!String.IsNullOrEmpty(labelFor))
{
tag.MergeAttribute("for", labelFor);
}
tag.MergeAttributes(attributes, false);
return tag.ToHtmlString(TagRenderMode.Normal);
}
}
}

View File

@@ -0,0 +1,95 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Web.Mvc;
using Microsoft.Internal.Web.Utils;
namespace System.Web.WebPages.Html
{
public partial class HtmlHelper
{
public IHtmlString RadioButton(string name, object value)
{
return RadioButton(name, value, htmlAttributes: (IDictionary<string, object>)null);
}
public IHtmlString RadioButton(string name, object value, object htmlAttributes)
{
return RadioButton(name, value, TypeHelper.ObjectToDictionary(htmlAttributes));
}
public IHtmlString RadioButton(string name, object value, IDictionary<string, object> htmlAttributes)
{
if (String.IsNullOrEmpty(name))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "name");
}
return BuildRadioButton(name, value, isChecked: null, attributes: htmlAttributes);
}
public IHtmlString RadioButton(string name, object value, bool isChecked)
{
return RadioButton(name, value, isChecked, htmlAttributes: (IDictionary<string, object>)null);
}
public IHtmlString RadioButton(string name, object value, bool isChecked, object htmlAttributes)
{
return RadioButton(name, value, isChecked, TypeHelper.ObjectToDictionary(htmlAttributes));
}
public IHtmlString RadioButton(string name, object value, bool isChecked, IDictionary<string, object> htmlAttributes)
{
if (name == null)
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "name");
}
return BuildRadioButton(name, value, isChecked, htmlAttributes);
}
private IHtmlString BuildRadioButton(string name, object value, bool? isChecked, IDictionary<string, object> attributes)
{
string valueString = ConvertTo(value, typeof(string)) as string;
TagBuilder builder = new TagBuilder("input");
builder.MergeAttribute("type", "radio", true);
builder.GenerateId(name);
builder.MergeAttributes(attributes, replaceExisting: true);
builder.MergeAttribute("value", valueString, replaceExisting: true);
builder.MergeAttribute("name", name, replaceExisting: true);
if (UnobtrusiveJavaScriptEnabled)
{
// Add validation attributes
var validationAttributes = _validationHelper.GetUnobtrusiveValidationAttributes(name);
builder.MergeAttributes(validationAttributes, replaceExisting: false);
}
var modelState = ModelState[name];
string modelValue = null;
if (modelState != null)
{
modelValue = ConvertTo(modelState.Value, typeof(string)) as string;
isChecked = isChecked ?? String.Equals(modelValue, valueString, StringComparison.OrdinalIgnoreCase);
}
if (isChecked.HasValue)
{
// Overrides attribute values
if (isChecked.Value)
{
builder.MergeAttribute("checked", "checked", true);
}
else
{
builder.Attributes.Remove("checked");
}
}
AddErrorClass(builder, name);
return builder.ToHtmlString(TagRenderMode.SelfClosing);
}
}
}

View File

@@ -0,0 +1,290 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Microsoft.Internal.Web.Utils;
namespace System.Web.WebPages.Html
{
public partial class HtmlHelper
{
public IHtmlString ListBox(string name, IEnumerable<SelectListItem> selectList)
{
return ListBox(name, defaultOption: null, selectList: selectList, htmlAttributes: (IDictionary<string, object>)null);
}
public IHtmlString ListBox(string name, string defaultOption, IEnumerable<SelectListItem> selectList)
{
return ListBox(name, defaultOption: defaultOption, selectList: selectList, selectedValues: null,
htmlAttributes: (IDictionary<string, object>)null);
}
public IHtmlString ListBox(string name, IEnumerable<SelectListItem> selectList, object htmlAttributes)
{
return ListBox(name, defaultOption: null, selectList: selectList, selectedValues: null, htmlAttributes: htmlAttributes);
}
public IHtmlString ListBox(string name, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes)
{
return ListBox(name, defaultOption: null, selectList: selectList, selectedValues: null, htmlAttributes: htmlAttributes);
}
public IHtmlString ListBox(string name, string defaultOption, IEnumerable<SelectListItem> selectList,
IDictionary<string, object> htmlAttributes)
{
return ListBox(name, defaultOption, selectList, selectedValues: null, htmlAttributes: htmlAttributes);
}
public IHtmlString ListBox(string name, string defaultOption, IEnumerable<SelectListItem> selectList, object htmlAttributes)
{
return ListBox(name, defaultOption: defaultOption, selectList: selectList, selectedValues: null, htmlAttributes: htmlAttributes);
}
public IHtmlString ListBox(string name, string defaultOption, IEnumerable<SelectListItem> selectList, object selectedValues,
IDictionary<string, object> htmlAttributes)
{
if (String.IsNullOrEmpty(name))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "name");
}
return BuildListBox(name, defaultOption: defaultOption, selectList: selectList,
selectedValues: selectedValues, size: null, allowMultiple: false, htmlAttributes: htmlAttributes);
}
public IHtmlString ListBox(string name, string defaultOption, IEnumerable<SelectListItem> selectList, object selectedValues,
object htmlAttributes)
{
return ListBox(name, defaultOption: defaultOption, selectList: selectList,
selectedValues: selectedValues, htmlAttributes: TypeHelper.ObjectToDictionary(htmlAttributes));
}
public IHtmlString ListBox(string name, IEnumerable<SelectListItem> selectList,
object selectedValues, int size, bool allowMultiple)
{
return ListBox(name, defaultOption: null, selectList: selectList, selectedValues: selectedValues, size: size,
allowMultiple: allowMultiple, htmlAttributes: (IDictionary<string, object>)null);
}
public IHtmlString ListBox(string name, string defaultOption, IEnumerable<SelectListItem> selectList,
object selectedValues, int size, bool allowMultiple)
{
return ListBox(name, defaultOption: defaultOption, selectList: selectList, selectedValues: selectedValues,
size: size, allowMultiple: allowMultiple, htmlAttributes: (IDictionary<string, object>)null);
}
public IHtmlString ListBox(string name, string defaultOption, IEnumerable<SelectListItem> selectList,
object selectedValues, int size, bool allowMultiple, IDictionary<string, object> htmlAttributes)
{
if (String.IsNullOrEmpty(name))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "name");
}
return BuildListBox(name, defaultOption, selectList, selectedValues, size, allowMultiple, htmlAttributes);
}
public IHtmlString ListBox(string name, string defaultOption, IEnumerable<SelectListItem> selectList,
object selectedValues, int size, bool allowMultiple, object htmlAttributes)
{
return ListBox(name, defaultOption, selectList, selectedValues, size, allowMultiple, TypeHelper.ObjectToDictionary(htmlAttributes));
}
private IHtmlString BuildListBox(string name, string defaultOption, IEnumerable<SelectListItem> selectList,
object selectedValues, int? size, bool allowMultiple, IDictionary<string, object> htmlAttributes)
{
var modelState = ModelState[name];
if (modelState != null)
{
selectedValues = selectedValues ?? ModelState[name].Value;
}
if (selectedValues != null)
{
IEnumerable values = (allowMultiple) ? ConvertTo(selectedValues, typeof(string[])) as string[]
: new[] { ConvertTo(selectedValues, typeof(string)) };
HashSet<string> selectedValueSet = new HashSet<string>(from object value in values
select Convert.ToString(value, CultureInfo.CurrentCulture),
StringComparer.OrdinalIgnoreCase);
List<SelectListItem> newSelectList = new List<SelectListItem>();
bool previousSelected = false;
foreach (SelectListItem item in selectList)
{
bool selected = false;
// If the user's specified allowed multiple to be false
// only pick up the first item that was selected.
if (allowMultiple || !previousSelected)
{
selected = item.Selected || selectedValueSet.Contains(item.Value ?? item.Text);
}
previousSelected = previousSelected | selected;
newSelectList.Add(new SelectListItem(item) { Selected = selected });
}
selectList = newSelectList;
}
TagBuilder tagBuilder = new TagBuilder("select")
{
InnerHtml = BuildListOptions(selectList, defaultOption)
};
if (UnobtrusiveJavaScriptEnabled)
{
// Add validation attributes
var validationAttributes = _validationHelper.GetUnobtrusiveValidationAttributes(name);
tagBuilder.MergeAttributes(validationAttributes, replaceExisting: false);
}
tagBuilder.GenerateId(name);
tagBuilder.MergeAttributes(htmlAttributes);
tagBuilder.MergeAttribute("name", name, replaceExisting: true);
if (size.HasValue)
{
tagBuilder.MergeAttribute("size", size.ToString(), true);
}
if (allowMultiple)
{
tagBuilder.MergeAttribute("multiple", "multiple");
}
else if (tagBuilder.Attributes.ContainsKey("multiple"))
{
tagBuilder.Attributes.Remove("multiple");
}
// If there are any errors for a named field, we add the css attribute.
AddErrorClass(tagBuilder, name);
return tagBuilder.ToHtmlString(TagRenderMode.Normal);
}
public IHtmlString DropDownList(string name, IEnumerable<SelectListItem> selectList)
{
return DropDownList(name, defaultOption: null, selectList: selectList, htmlAttributes: (IDictionary<string, object>)null);
}
public IHtmlString DropDownList(string name, IEnumerable<SelectListItem> selectList, object htmlAttributes)
{
return DropDownList(name, defaultOption: null, selectList: selectList, selectedValue: null, htmlAttributes: htmlAttributes);
}
public IHtmlString DropDownList(string name, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes)
{
return DropDownList(name, defaultOption: null, selectList: selectList, selectedValue: null, htmlAttributes: htmlAttributes);
}
public IHtmlString DropDownList(string name, string defaultOption, IEnumerable<SelectListItem> selectList)
{
return DropDownList(name, defaultOption, selectList, selectedValue: null, htmlAttributes: (IDictionary<string, object>)null);
}
public IHtmlString DropDownList(string name, string defaultOption, IEnumerable<SelectListItem> selectList,
IDictionary<string, object> htmlAttributes)
{
return DropDownList(name, defaultOption, selectList, selectedValue: null, htmlAttributes: htmlAttributes);
}
public IHtmlString DropDownList(string name, string defaultOption, IEnumerable<SelectListItem> selectList, object htmlAttributes)
{
return DropDownList(name, defaultOption: defaultOption, selectList: selectList, selectedValue: null, htmlAttributes: htmlAttributes);
}
public IHtmlString DropDownList(string name, string defaultOption, IEnumerable<SelectListItem> selectList, object selectedValue,
IDictionary<string, object> htmlAttributes)
{
if (String.IsNullOrEmpty(name))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "name");
}
return BuildDropDownList(name, defaultOption, selectList, selectedValue, htmlAttributes: htmlAttributes);
}
public IHtmlString DropDownList(string name, string defaultOption, IEnumerable<SelectListItem> selectList, object selectedValue,
object htmlAttributes)
{
return DropDownList(name, defaultOption, selectList, selectedValue, TypeHelper.ObjectToDictionary(htmlAttributes));
}
private IHtmlString BuildDropDownList(string name, string defaultOption, IEnumerable<SelectListItem> selectList,
object selectedValue, IDictionary<string, object> htmlAttributes)
{
var modelState = ModelState[name];
if (modelState != null)
{
selectedValue = selectedValue ?? ModelState[name].Value;
}
selectedValue = ConvertTo(selectedValue, typeof(string));
if (selectedValue != null)
{
var newSelectList = new List<SelectListItem>(from item in selectList
select new SelectListItem(item));
var comparer = StringComparer.InvariantCultureIgnoreCase;
var selectedItem = newSelectList.FirstOrDefault(item => item.Selected || comparer.Equals(item.Value ?? item.Text, selectedValue));
if (selectedItem != default(SelectListItem))
{
selectedItem.Selected = true;
selectList = newSelectList;
}
}
TagBuilder tagBuilder = new TagBuilder("select")
{
InnerHtml = BuildListOptions(selectList, defaultOption)
};
tagBuilder.MergeAttributes(htmlAttributes);
tagBuilder.MergeAttribute("name", name, replaceExisting: true);
tagBuilder.GenerateId(name);
if (UnobtrusiveJavaScriptEnabled)
{
var validationAttributes = _validationHelper.GetUnobtrusiveValidationAttributes(name);
tagBuilder.MergeAttributes(validationAttributes, replaceExisting: false);
}
// If there are any errors for a named field, we add the css attribute.
AddErrorClass(tagBuilder, name);
return tagBuilder.ToHtmlString(TagRenderMode.Normal);
}
private static string BuildListOptions(IEnumerable<SelectListItem> selectList, string optionText)
{
StringBuilder builder = new StringBuilder().AppendLine();
if (optionText != null)
{
builder.AppendLine(ListItemToOption(new SelectListItem { Text = optionText, Value = String.Empty }));
}
if (selectList != null)
{
foreach (var item in selectList)
{
builder.AppendLine(ListItemToOption(item));
}
}
return builder.ToString();
}
private static string ListItemToOption(SelectListItem item)
{
TagBuilder builder = new TagBuilder("option")
{
InnerHtml = HttpUtility.HtmlEncode(item.Text)
};
if (item.Value != null)
{
builder.Attributes["value"] = item.Value;
}
if (item.Selected)
{
builder.Attributes["selected"] = "selected";
}
return builder.ToString(TagRenderMode.Normal);
}
}
}

View File

@@ -0,0 +1,121 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Globalization;
using System.Web.Mvc;
using Microsoft.Internal.Web.Utils;
namespace System.Web.WebPages.Html
{
public partial class HtmlHelper
{
// Values from mvc
private const int TextAreaRows = 2;
private const int TextAreaColumns = 20;
private static readonly IDictionary<string, object> _implicitRowsAndColumns = new Dictionary<string, object>
{
{ "rows", TextAreaRows.ToString(CultureInfo.InvariantCulture) },
{ "cols", TextAreaColumns.ToString(CultureInfo.InvariantCulture) },
};
private static IDictionary<string, object> GetRowsAndColumnsDictionary(int rows, int columns)
{
Dictionary<string, object> result = new Dictionary<string, object>();
if (rows > 0)
{
result.Add("rows", rows.ToString(CultureInfo.InvariantCulture));
}
if (columns > 0)
{
result.Add("cols", columns.ToString(CultureInfo.InvariantCulture));
}
return result;
}
public IHtmlString TextArea(string name)
{
return TextArea(name, value: null, htmlAttributes: (IDictionary<string, object>)null);
}
public IHtmlString TextArea(string name, object htmlAttributes)
{
return TextArea(name, value: null, htmlAttributes: TypeHelper.ObjectToDictionary(htmlAttributes));
}
public IHtmlString TextArea(string name, IDictionary<string, object> htmlAttributes)
{
return TextArea(name, value: null, htmlAttributes: htmlAttributes);
}
public IHtmlString TextArea(string name, string value)
{
return TextArea(name, value, (IDictionary<string, object>)null);
}
public IHtmlString TextArea(string name, string value, object htmlAttributes)
{
return TextArea(name, value, TypeHelper.ObjectToDictionary(htmlAttributes));
}
public IHtmlString TextArea(string name, string value, IDictionary<string, object> htmlAttributes)
{
if (String.IsNullOrEmpty(name))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "name");
}
return BuildTextArea(name, value, _implicitRowsAndColumns, htmlAttributes);
}
public IHtmlString TextArea(string name, string value, int rows, int columns,
object htmlAttributes)
{
return TextArea(name, value, rows, columns, TypeHelper.ObjectToDictionary(htmlAttributes));
}
public IHtmlString TextArea(string name, string value, int rows, int columns,
IDictionary<string, object> htmlAttributes)
{
if (String.IsNullOrEmpty(name))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "name");
}
return BuildTextArea(name, value, GetRowsAndColumnsDictionary(rows, columns), htmlAttributes);
}
private IHtmlString BuildTextArea(string name, string value, IDictionary<string, object> rowsAndColumnsDictionary,
IDictionary<string, object> htmlAttributes)
{
TagBuilder tagBuilder = new TagBuilder("textarea");
if (UnobtrusiveJavaScriptEnabled)
{
// Add validation attributes
var validationAttributes = _validationHelper.GetUnobtrusiveValidationAttributes(name);
tagBuilder.MergeAttributes(validationAttributes, replaceExisting: false);
}
// Add user specified htmlAttributes
tagBuilder.MergeAttributes(htmlAttributes);
tagBuilder.MergeAttributes(rowsAndColumnsDictionary, rowsAndColumnsDictionary != _implicitRowsAndColumns);
// Value becomes the inner html of the textarea element
var modelState = ModelState[name];
if (modelState != null)
{
value = value ?? Convert.ToString(ModelState[name].Value, CultureInfo.CurrentCulture);
}
tagBuilder.InnerHtml = Encode(value);
//Assign name and id
tagBuilder.MergeAttribute("name", name);
tagBuilder.GenerateId(name);
AddErrorClass(tagBuilder, name);
return tagBuilder.ToHtmlString(TagRenderMode.Normal);
}
}
}

View File

@@ -0,0 +1,184 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Microsoft.Internal.Web.Utils;
namespace System.Web.WebPages.Html
{
public partial class HtmlHelper
{
public IHtmlString ValidationMessage(string name)
{
return ValidationMessage(name, null, null);
}
public IHtmlString ValidationMessage(string name, string message)
{
return ValidationMessage(name, message, (IDictionary<string, object>)null);
}
public IHtmlString ValidationMessage(string name, object htmlAttributes)
{
return ValidationMessage(name, null, TypeHelper.ObjectToDictionary(htmlAttributes));
}
public IHtmlString ValidationMessage(string name, IDictionary<string, object> htmlAttributes)
{
return ValidationMessage(name, null, htmlAttributes);
}
public IHtmlString ValidationMessage(string name, string message, object htmlAttributes)
{
return ValidationMessage(name, message, TypeHelper.ObjectToDictionary(htmlAttributes));
}
public IHtmlString ValidationMessage(string name, string message, IDictionary<string, object> htmlAttributes)
{
if (String.IsNullOrEmpty(name))
{
throw new ArgumentException(CommonResources.Argument_Cannot_Be_Null_Or_Empty, "name");
}
return BuildValidationMessage(name, message, htmlAttributes);
}
[SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase",
Justification = "Normalization to lowercase is a common requirement for JavaScript and HTML values")]
private IHtmlString BuildValidationMessage(string name, string message, IDictionary<string, object> htmlAttributes)
{
var modelState = ModelState[name];
IEnumerable<string> errors = null;
if (modelState != null)
{
errors = modelState.Errors;
}
bool hasError = errors != null && errors.Any();
if (!hasError && !UnobtrusiveJavaScriptEnabled)
{
// If unobtrusive validation is enabled, we need to generate an empty span with the "val-for" attribute"
return null;
}
else
{
string error = null;
if (hasError)
{
error = message ?? errors.First();
}
TagBuilder tagBuilder = new TagBuilder("span") { InnerHtml = Encode(error) };
tagBuilder.MergeAttributes(htmlAttributes);
if (UnobtrusiveJavaScriptEnabled)
{
bool replaceValidationMessageContents = String.IsNullOrEmpty(message);
tagBuilder.MergeAttribute("data-valmsg-for", name);
tagBuilder.MergeAttribute("data-valmsg-replace", replaceValidationMessageContents.ToString().ToLowerInvariant());
}
tagBuilder.AddCssClass(hasError ? ValidationMessageCssClassName : ValidationMessageValidCssClassName);
return tagBuilder.ToHtmlString(TagRenderMode.Normal);
}
}
public IHtmlString ValidationSummary()
{
return BuildValidationSummary(message: null, excludeFieldErrors: false, htmlAttributes: (IDictionary<string, object>)null);
}
public IHtmlString ValidationSummary(string message)
{
return BuildValidationSummary(message: message, excludeFieldErrors: false, htmlAttributes: (IDictionary<string, object>)null);
}
public IHtmlString ValidationSummary(bool excludeFieldErrors)
{
return ValidationSummary(message: null, excludeFieldErrors: excludeFieldErrors, htmlAttributes: (IDictionary<string, object>)null);
}
public IHtmlString ValidationSummary(object htmlAttributes)
{
return ValidationSummary(message: null, excludeFieldErrors: false, htmlAttributes: htmlAttributes);
}
public IHtmlString ValidationSummary(IDictionary<string, object> htmlAttributes)
{
return ValidationSummary(message: null, excludeFieldErrors: false, htmlAttributes: htmlAttributes);
}
public IHtmlString ValidationSummary(string message, object htmlAttributes)
{
return ValidationSummary(message, excludeFieldErrors: false, htmlAttributes: htmlAttributes);
}
public IHtmlString ValidationSummary(string message, IDictionary<string, object> htmlAttributes)
{
return ValidationSummary(message, excludeFieldErrors: false, htmlAttributes: htmlAttributes);
}
public IHtmlString ValidationSummary(string message, bool excludeFieldErrors, object htmlAttributes)
{
return ValidationSummary(message, excludeFieldErrors, TypeHelper.ObjectToDictionary(htmlAttributes));
}
public IHtmlString ValidationSummary(string message, bool excludeFieldErrors, IDictionary<string, object> htmlAttributes)
{
return BuildValidationSummary(message, excludeFieldErrors, htmlAttributes);
}
private IHtmlString BuildValidationSummary(string message, bool excludeFieldErrors, IDictionary<string, object> htmlAttributes)
{
IEnumerable<string> errors = null;
if (excludeFieldErrors)
{
// Review: Is there a better way to share the form field name between this and ModelStateDictionary?
var formModelState = ModelState[ModelStateDictionary.FormFieldKey];
if (formModelState != null)
{
errors = formModelState.Errors;
}
}
else
{
errors = ModelState.SelectMany(c => c.Value.Errors);
}
bool hasErrors = errors != null && errors.Any();
if (!hasErrors && (!UnobtrusiveJavaScriptEnabled || excludeFieldErrors))
{
// If no errors are found and we do not have unobtrusive validation enabled or if the summary is not meant to display field errors, don't generate the summary.
return null;
}
else
{
TagBuilder tagBuilder = new TagBuilder("div");
tagBuilder.MergeAttributes(htmlAttributes);
tagBuilder.AddCssClass(hasErrors ? ValidationSummaryClass : ValidationSummaryValidClass);
if (UnobtrusiveJavaScriptEnabled && !excludeFieldErrors)
{
tagBuilder.MergeAttribute("data-valmsg-summary", "true");
}
StringBuilder builder = new StringBuilder();
if (message != null)
{
builder.Append("<span>");
builder.Append(Encode(message));
builder.AppendLine("</span>");
}
builder.AppendLine("<ul>");
foreach (var error in errors)
{
builder.Append("<li>");
builder.Append(Encode(error));
builder.AppendLine("</li>");
}
builder.Append("</ul>");
tagBuilder.InnerHtml = builder.ToString();
return tagBuilder.ToHtmlString(TagRenderMode.Normal);
}
}
}
}

View File

@@ -0,0 +1,202 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Web.WebPages.Scope;
namespace System.Web.WebPages.Html
{
public partial class HtmlHelper
{
internal const string DefaultValidationInputErrorCssClass = "input-validation-error";
private const string DefaultValidationInputValidCssClass = "input-validation-valid";
private const string DefaultValidationMessageErrorCssClass = "field-validation-error";
private const string DefaultValidationMessageValidCssClass = "field-validation-valid";
private const string DefaultValidationSummaryErrorCssClass = "validation-summary-errors";
private const string DefaultValidationSummaryValidCssClassName = "validation-summary-valid";
private static readonly object _validationMesssageErrorClassKey = new object();
private static readonly object _validationMessageValidClassKey = new object();
private static readonly object _validationInputErrorClassKey = new object();
private static readonly object _validationInputValidClassKey = new object();
private static readonly object _validationSummaryClassKey = new object();
private static readonly object _validationSummaryValidClassKey = new object();
private static readonly object _unobtrusiveValidationKey = new object();
private static string _idAttributeDotReplacement;
private readonly ValidationHelper _validationHelper;
internal HtmlHelper(ModelStateDictionary modelState, ValidationHelper validationHelper)
{
ModelState = modelState;
_validationHelper = validationHelper;
}
// This property got copied from MVC's HtmlHelper along with TagBuilder.
// It was a global property in MVC so it should not have scoped semantics here either.
public static string IdAttributeDotReplacement
{
get
{
if (String.IsNullOrEmpty(_idAttributeDotReplacement))
{
_idAttributeDotReplacement = "_";
}
return _idAttributeDotReplacement;
}
set { _idAttributeDotReplacement = value; }
}
public static string ValidationInputValidCssClassName
{
get { return ScopeStorage.CurrentScope[_validationInputValidClassKey] as string ?? DefaultValidationInputValidCssClass; }
set
{
if (value == null)
{
throw new ArgumentNullException("value");
}
ScopeStorage.CurrentScope[_validationInputValidClassKey] = value;
}
}
public static string ValidationInputCssClassName
{
get { return ScopeStorage.CurrentScope[_validationInputErrorClassKey] as string ?? DefaultValidationInputErrorCssClass; }
set
{
if (value == null)
{
throw new ArgumentNullException("value");
}
ScopeStorage.CurrentScope[_validationInputErrorClassKey] = value;
}
}
public static string ValidationMessageValidCssClassName
{
get { return ScopeStorage.CurrentScope[_validationMessageValidClassKey] as string ?? DefaultValidationMessageValidCssClass; }
set
{
if (value == null)
{
throw new ArgumentNullException("value");
}
ScopeStorage.CurrentScope[_validationMessageValidClassKey] = value;
}
}
public static string ValidationMessageCssClassName
{
get { return ScopeStorage.CurrentScope[_validationMesssageErrorClassKey] as string ?? DefaultValidationMessageErrorCssClass; }
set
{
if (value == null)
{
throw new ArgumentNullException("value");
}
ScopeStorage.CurrentScope[_validationMesssageErrorClassKey] = value;
}
}
public static string ValidationSummaryClass
{
get { return ScopeStorage.CurrentScope[_validationSummaryClassKey] as string ?? DefaultValidationSummaryErrorCssClass; }
set
{
if (value == null)
{
throw new ArgumentNullException("value");
}
ScopeStorage.CurrentScope[_validationSummaryClassKey] = value;
}
}
public static string ValidationSummaryValidClass
{
get { return ScopeStorage.CurrentScope[_validationSummaryValidClassKey] as string ?? DefaultValidationSummaryValidCssClassName; }
set
{
if (value == null)
{
throw new ArgumentNullException("value");
}
ScopeStorage.CurrentScope[_validationSummaryValidClassKey] = value;
}
}
public static bool UnobtrusiveJavaScriptEnabled
{
get
{
bool? value = (bool?)ScopeStorage.CurrentScope[_unobtrusiveValidationKey];
return value ?? true;
}
set { ScopeStorage.CurrentScope[_unobtrusiveValidationKey] = value; }
}
private ModelStateDictionary ModelState { get; set; }
public string AttributeEncode(object value)
{
return AttributeEncode(Convert.ToString(value, CultureInfo.InvariantCulture));
}
[SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
Justification = "For consistency, all helpers are instance methods.")]
public string AttributeEncode(string value)
{
if (String.IsNullOrEmpty(value))
{
return String.Empty;
}
else
{
return HttpUtility.HtmlAttributeEncode(value);
}
}
public string Encode(object value)
{
return Encode(Convert.ToString(value, CultureInfo.InvariantCulture));
}
[SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
Justification = "For consistency, all helpers are instance methods.")]
public string Encode(string value)
{
if (String.IsNullOrEmpty(value))
{
return String.Empty;
}
else
{
return HttpUtility.HtmlEncode(value);
}
}
/// <summary>
/// Wraps HTML markup in an IHtmlString, which will enable HTML markup to be
/// rendered to the output without getting HTML encoded.
/// </summary>
/// <param name="value">HTML markup string.</param>
/// <returns>An IHtmlString that represents HTML markup.</returns>
[SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
Justification = "For consistency, all helpers are instance methods.")]
public IHtmlString Raw(string value)
{
return new HtmlString(value);
}
/// <summary>
/// Wraps HTML markup from the string representation of an object in an IHtmlString,
/// which will enable HTML markup to be rendered to the output without getting HTML encoded.
/// </summary>
/// <param name="value">object with string representation as HTML markup</param>
/// <returns>An IHtmlString that represents HTML markup.</returns>
[SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
Justification = "For consistency, all helpers are instance methods.")]
public IHtmlString Raw(object value)
{
return new HtmlString(value == null ? null : value.ToString());
}
}
}

View File

@@ -0,0 +1,18 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
namespace System.Web.WebPages.Html
{
public class ModelState
{
private List<string> _errors = new List<string>();
public IList<string> Errors
{
get { return _errors; }
}
public object Value { get; set; }
}
}

View File

@@ -0,0 +1,185 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace System.Web.WebPages.Html
{
// Most of the code for this class is copied from MVC 2.0
public class ModelStateDictionary : IDictionary<string, ModelState>
{
internal const string FormFieldKey = "_FORM";
private readonly Dictionary<string, ModelState> _innerDictionary = new Dictionary<string, ModelState>(StringComparer.OrdinalIgnoreCase);
public ModelStateDictionary()
{
}
public ModelStateDictionary(ModelStateDictionary dictionary)
{
if (dictionary == null)
{
throw new ArgumentNullException("dictionary");
}
foreach (var entry in dictionary)
{
_innerDictionary.Add(entry.Key, entry.Value);
}
}
public int Count
{
get { return _innerDictionary.Count; }
}
public bool IsReadOnly
{
get { return ((IDictionary<string, ModelState>)_innerDictionary).IsReadOnly; }
}
public bool IsValid
{
get { return !Values.SelectMany(modelState => modelState.Errors).Any(); }
}
public ICollection<string> Keys
{
get { return _innerDictionary.Keys; }
}
public ICollection<ModelState> Values
{
get { return _innerDictionary.Values; }
}
public ModelState this[string key]
{
get
{
ModelState value;
_innerDictionary.TryGetValue(key, out value);
return value;
}
set { _innerDictionary[key] = value; }
}
public void Add(KeyValuePair<string, ModelState> item)
{
((IDictionary<string, ModelState>)_innerDictionary).Add(item);
}
public void Add(string key, ModelState value)
{
_innerDictionary.Add(key, value);
}
public void AddError(string key, string errorMessage)
{
GetModelStateForKey(key).Errors.Add(errorMessage);
}
public void AddFormError(string errorMessage)
{
GetModelStateForKey(FormFieldKey).Errors.Add(errorMessage);
}
public void Clear()
{
_innerDictionary.Clear();
}
public bool Contains(KeyValuePair<string, ModelState> item)
{
return ((IDictionary<string, ModelState>)_innerDictionary).Contains(item);
}
public bool ContainsKey(string key)
{
return _innerDictionary.ContainsKey(key);
}
public void CopyTo(KeyValuePair<string, ModelState>[] array, int arrayIndex)
{
((IDictionary<string, ModelState>)_innerDictionary).CopyTo(array, arrayIndex);
}
public IEnumerator<KeyValuePair<string, ModelState>> GetEnumerator()
{
return _innerDictionary.GetEnumerator();
}
private ModelState GetModelStateForKey(string key)
{
if (key == null)
{
throw new ArgumentNullException("key");
}
ModelState modelState;
if (!TryGetValue(key, out modelState))
{
modelState = new ModelState();
_innerDictionary[key] = modelState;
}
return modelState;
}
public bool IsValidField(string key)
{
if (key == null)
{
throw new ArgumentNullException("key");
}
// if the key is not found in the dictionary, we just say that it's valid (since there are no errors)
ModelState modelState = this[key];
return (modelState == null) || !modelState.Errors.Any();
}
public void Merge(ModelStateDictionary dictionary)
{
if (dictionary == null)
{
return;
}
foreach (var entry in dictionary)
{
this[entry.Key] = entry.Value;
}
}
public bool Remove(KeyValuePair<string, ModelState> item)
{
return ((IDictionary<string, ModelState>)_innerDictionary).Remove(item);
}
public bool Remove(string key)
{
return _innerDictionary.Remove(key);
}
public bool TryGetValue(string key, out ModelState value)
{
return _innerDictionary.TryGetValue(key, out value);
}
public void SetModelValue(string key, object value)
{
ModelState state = GetModelStateForKey(key);
state.Value = value;
}
#region IEnumerable Members
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)_innerDictionary).GetEnumerator();
}
#endregion
}
}

View File

@@ -0,0 +1,24 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
namespace System.Web.WebPages.Html
{
public class SelectListItem
{
public SelectListItem()
{
}
public SelectListItem(SelectListItem item)
{
Text = item.Text;
Value = item.Value;
Selected = item.Selected;
}
public string Text { get; set; }
public string Value { get; set; }
public bool Selected { get; set; }
}
}