// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Text.Encodings.Web; using Microsoft.AspNetCore.Html; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.ViewEngines; using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal; namespace Microsoft.AspNetCore.Mvc.ViewFeatures { public class HtmlHelper : HtmlHelper, IHtmlHelper { private readonly ExpressionTextCache _expressionTextCache; /// /// Initializes a new instance of the class. /// public HtmlHelper( IHtmlGenerator htmlGenerator, ICompositeViewEngine viewEngine, IModelMetadataProvider metadataProvider, IViewBufferScope bufferScope, HtmlEncoder htmlEncoder, UrlEncoder urlEncoder, ExpressionTextCache expressionTextCache) : base( htmlGenerator, viewEngine, metadataProvider, bufferScope, htmlEncoder, urlEncoder) { if (expressionTextCache == null) { throw new ArgumentNullException(nameof(expressionTextCache)); } _expressionTextCache = expressionTextCache; } /// public new ViewDataDictionary ViewData { get; private set; } public override void Contextualize(ViewContext viewContext) { if (viewContext == null) { throw new ArgumentNullException(nameof(viewContext)); } if (viewContext.ViewData == null) { throw new ArgumentException(Resources.FormatPropertyOfTypeCannotBeNull( nameof(ViewContext.ViewData), typeof(ViewContext)), nameof(viewContext)); } ViewData = viewContext.ViewData as ViewDataDictionary; if (ViewData == null) { // viewContext may contain a base ViewDataDictionary instance. So complain about that type, not TModel. throw new ArgumentException(Resources.FormatArgumentPropertyUnexpectedType( nameof(ViewContext.ViewData), viewContext.ViewData.GetType().FullName, typeof(ViewDataDictionary).FullName), nameof(viewContext)); } base.Contextualize(viewContext); } /// public IHtmlContent CheckBoxFor( Expression> expression, object htmlAttributes) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } var modelExplorer = GetModelExplorer(expression); return GenerateCheckBox( modelExplorer, GetExpressionName(expression), isChecked: null, htmlAttributes: htmlAttributes); } /// public IHtmlContent DropDownListFor( Expression> expression, IEnumerable selectList, string optionLabel, object htmlAttributes) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } var modelExplorer = GetModelExplorer(expression); return GenerateDropDown( modelExplorer, GetExpressionName(expression), selectList, optionLabel, htmlAttributes); } /// public IHtmlContent DisplayFor( Expression> expression, string templateName, string htmlFieldName, object additionalViewData) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } var modelExplorer = GetModelExplorer(expression); return GenerateDisplay( modelExplorer, htmlFieldName ?? GetExpressionName(expression), templateName, additionalViewData); } /// public string DisplayNameFor(Expression> expression) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } var modelExplorer = GetModelExplorer(expression); return GenerateDisplayName(modelExplorer, GetExpressionName(expression)); } /// public string DisplayNameForInnerType( Expression> expression) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } var modelExplorer = ExpressionMetadataProvider.FromLambdaExpression( expression, new ViewDataDictionary(ViewData, model: null), MetadataProvider); var expressionText = ExpressionHelper.GetExpressionText(expression, _expressionTextCache); if (modelExplorer == null) { throw new InvalidOperationException(Resources.FormatHtmlHelper_NullModelMetadata(expressionText)); } return GenerateDisplayName(modelExplorer, expressionText); } /// public string DisplayTextFor(Expression> expression) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } return GenerateDisplayText(GetModelExplorer(expression)); } /// public IHtmlContent EditorFor( Expression> expression, string templateName, string htmlFieldName, object additionalViewData) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } var modelExplorer = GetModelExplorer(expression); return GenerateEditor( modelExplorer, htmlFieldName ?? GetExpressionName(expression), templateName, additionalViewData); } /// public IHtmlContent HiddenFor( Expression> expression, object htmlAttributes) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } var modelExplorer = GetModelExplorer(expression); return GenerateHidden( modelExplorer, GetExpressionName(expression), modelExplorer.Model, useViewData: false, htmlAttributes: htmlAttributes); } /// public string IdFor(Expression> expression) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } return GenerateId(GetExpressionName(expression)); } /// public IHtmlContent LabelFor( Expression> expression, string labelText, object htmlAttributes) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } var modelExplorer = GetModelExplorer(expression); return GenerateLabel(modelExplorer, GetExpressionName(expression), labelText, htmlAttributes); } /// public IHtmlContent ListBoxFor( Expression> expression, IEnumerable selectList, object htmlAttributes) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } var modelExplorer = GetModelExplorer(expression); var name = GetExpressionName(expression); return GenerateListBox(modelExplorer, name, selectList, htmlAttributes); } /// public string NameFor(Expression> expression) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } var expressionName = GetExpressionName(expression); return Name(expressionName); } /// public IHtmlContent PasswordFor( Expression> expression, object htmlAttributes) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } var modelExplorer = GetModelExplorer(expression); return GeneratePassword( modelExplorer, GetExpressionName(expression), value: null, htmlAttributes: htmlAttributes); } /// public IHtmlContent RadioButtonFor( Expression> expression, object value, object htmlAttributes) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } if (value == null) { throw new ArgumentNullException(nameof(value)); } var modelExplorer = GetModelExplorer(expression); return GenerateRadioButton( modelExplorer, GetExpressionName(expression), value, isChecked: null, htmlAttributes: htmlAttributes); } /// public IHtmlContent TextAreaFor( Expression> expression, int rows, int columns, object htmlAttributes) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } var modelExplorer = GetModelExplorer(expression); return GenerateTextArea(modelExplorer, GetExpressionName(expression), rows, columns, htmlAttributes); } /// public IHtmlContent TextBoxFor( Expression> expression, string format, object htmlAttributes) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } var modelExplorer = GetModelExplorer(expression); return GenerateTextBox( modelExplorer, GetExpressionName(expression), modelExplorer.Model, format, htmlAttributes); } protected string GetExpressionName(Expression> expression) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } return ExpressionHelper.GetExpressionText(expression, _expressionTextCache); } protected ModelExplorer GetModelExplorer(Expression> expression) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } var modelExplorer = ExpressionMetadataProvider.FromLambdaExpression(expression, ViewData, MetadataProvider); if (modelExplorer == null) { var expressionName = GetExpressionName(expression); throw new InvalidOperationException(Resources.FormatHtmlHelper_NullModelMetadata(expressionName)); } return modelExplorer; } /// public IHtmlContent ValidationMessageFor( Expression> expression, string message, object htmlAttributes, string tag) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } var modelExplorer = GetModelExplorer(expression); return GenerateValidationMessage( modelExplorer, GetExpressionName(expression), message, tag, htmlAttributes); } /// public string ValueFor(Expression> expression, string format) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } var modelExplorer = GetModelExplorer(expression); return GenerateValue(GetExpressionName(expression), modelExplorer.Model, format, useViewData: false); } } }