/// <inheritdoc /> /// <remarks>Does nothing if <see cref="For"/> is <c>null</c>.</remarks> public override void Process(TagHelperContext context, TagHelperOutput output) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (output == null) { throw new ArgumentNullException(nameof(output)); } var tagBuilder = Generator.GenerateTextArea( ViewContext, For.ModelExplorer, For.Name, rows: 0, columns: 0, htmlAttributes: null); if (tagBuilder != null) { // Overwrite current Content to ensure expression result round-trips correctly. output.Content.SetContent(tagBuilder.InnerHtml); output.MergeAttributes(tagBuilder); } }
/// <inheritdoc /> /// <remarks>Does nothing if <see cref="For"/> is <c>null</c>.</remarks> public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (output == null) { throw new ArgumentNullException(nameof(output)); } if (For != null) { var tagBuilder = Generator.GenerateValidationMessage(ViewContext, For.Name, message: null, tag: null, htmlAttributes: null); if (tagBuilder != null) { output.MergeAttributes(tagBuilder); // We check for whitespace to detect scenarios such as: // <span validation-for="Name"> // </span> if (!output.IsContentModified) { var childContent = await output.GetChildContentAsync(); if (childContent.IsWhiteSpace) { // Provide default label text since there was nothing useful in the Razor source. output.Content.SetContent(tagBuilder.InnerHtml); } else { output.Content.SetContent(childContent); } } } } }
public override void Process(TagHelperContext context, TagHelperOutput output) { var tagBuilder = Generator.GenerateSelect( ViewContext, null, optionLabel: AspOptionLabel, expression: AspExpression, selectList: AspItems, currentValues: new string[] { AspCurrent, }, allowMultiple: false, htmlAttributes: null); tagBuilder.AddCssClass( context.AllAttributes.ContainsName("class") == true ? context.AllAttributes["class"].Value.ToString() : string.Empty); if (tagBuilder != null) { output.MergeAttributes(tagBuilder); output.PostContent.Append(tagBuilder.InnerHtml); } }
/// <inheritdoc /> /// <remarks>Does nothing if user provides an <c>href</c> attribute.</remarks> /// <exception cref="InvalidOperationException"> /// Thrown if <c>href</c> attribute is provided and <see cref="Action"/>, <see cref="Controller"/>, /// <see cref="Fragment"/>, <see cref="Host"/>, <see cref="Protocol"/>, or <see cref="Route"/> are /// non-<c>null</c> or if the user provided <c>asp-route-*</c> attributes. Also thrown if <see cref="Route"/> /// and one or both of <see cref="Action"/> and <see cref="Controller"/> are non-<c>null</c>. /// </exception> public override void Process(TagHelperContext context, TagHelperOutput output) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (output == null) { throw new ArgumentNullException(nameof(output)); } // If "href" is already set, it means the user is attempting to use a normal anchor. if (output.Attributes.ContainsName(Href)) { if (Action != null || Controller != null || Route != null || Protocol != null || Host != null || Fragment != null || RouteValues.Count != 0) { // User specified an href and one of the bound attributes; can't determine the href attribute. throw new InvalidOperationException( Resources.FormatAnchorTagHelper_CannotOverrideHref( "<a>", ActionAttributeName, ControllerAttributeName, RouteAttributeName, ProtocolAttributeName, HostAttributeName, FragmentAttributeName, RouteValuesPrefix, Href)); } } else { IDictionary<string, object> routeValues = null; if (_routeValues != null && _routeValues.Count > 0) { // Convert from Dictionary<string, string> to Dictionary<string, object>. routeValues = new Dictionary<string, object>(_routeValues.Count, StringComparer.OrdinalIgnoreCase); foreach (var routeValue in _routeValues) { routeValues.Add(routeValue.Key, routeValue.Value); } } TagBuilder tagBuilder; if (Route == null) { tagBuilder = Generator.GenerateActionLink( ViewContext, linkText: string.Empty, actionName: Action, controllerName: Controller, protocol: Protocol, hostname: Host, fragment: Fragment, routeValues: routeValues, htmlAttributes: null); } else if (Action != null || Controller != null) { // Route and Action or Controller were specified. Can't determine the href attribute. throw new InvalidOperationException( Resources.FormatAnchorTagHelper_CannotDetermineHrefRouteActionOrControllerSpecified( "<a>", RouteAttributeName, ActionAttributeName, ControllerAttributeName, Href)); } else { tagBuilder = Generator.GenerateRouteLink( ViewContext, linkText: string.Empty, routeName: Route, protocol: Protocol, hostName: Host, fragment: Fragment, routeValues: routeValues, htmlAttributes: null); } if (tagBuilder != null) { output.MergeAttributes(tagBuilder); } } }
/// <inheritdoc /> /// <remarks>Does nothing if <see cref="For"/> is <c>null</c>.</remarks> /// <exception cref="InvalidOperationException"> /// Thrown if <see cref="Format"/> is non-<c>null</c> but <see cref="For"/> is <c>null</c>. /// </exception> public override void Process(TagHelperContext context, TagHelperOutput output) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (output == null) { throw new ArgumentNullException(nameof(output)); } // Pass through attributes that are also well-known HTML attributes. Must be done prior to any copying // from a TagBuilder. if (InputTypeName != null) { output.CopyHtmlAttribute("type", context); } if (Value != null) { output.CopyHtmlAttribute(nameof(Value), context); } // Note null or empty For.Name is allowed because TemplateInfo.HtmlFieldPrefix may be sufficient. // IHtmlGenerator will enforce name requirements. var metadata = For.Metadata; var modelExplorer = For.ModelExplorer; if (metadata == null) { throw new InvalidOperationException(Resources.FormatTagHelpers_NoProvidedMetadata( "<input>", ForAttributeName, nameof(IModelMetadataProvider), For.Name)); } string inputType; string inputTypeHint; if (string.IsNullOrEmpty(InputTypeName)) { // Note GetInputType never returns null. inputType = GetInputType(modelExplorer, out inputTypeHint); } else { inputType = InputTypeName.ToLowerInvariant(); inputTypeHint = null; } // inputType may be more specific than default the generator chooses below. if (!output.Attributes.ContainsName("type")) { output.Attributes["type"] = inputType; } TagBuilder tagBuilder; switch (inputType) { case "checkbox": GenerateCheckBox(modelExplorer, output); return; case "hidden": tagBuilder = Generator.GenerateHidden( ViewContext, modelExplorer, For.Name, value: For.Model, useViewData: false, htmlAttributes: null); break; case "password": tagBuilder = Generator.GeneratePassword( ViewContext, modelExplorer, For.Name, value: null, htmlAttributes: null); break; case "radio": tagBuilder = GenerateRadio(modelExplorer); break; default: tagBuilder = GenerateTextBox(modelExplorer, inputTypeHint, inputType); break; } if (tagBuilder != null) { // This TagBuilder contains the one <input/> element of interest. Since this is not the "checkbox" // special-case, output is a self-closing element no longer guaranteed. output.MergeAttributes(tagBuilder); output.Content.AppendHtml(tagBuilder.InnerHtml); } }
/// <inheritdoc /> /// <remarks> /// Does nothing if user provides an <c>action</c> attribute and <see cref="Antiforgery"/> is <c>null</c> or /// <c>false</c>. /// </remarks> /// <exception cref="InvalidOperationException"> /// Thrown if <c>action</c> attribute is provided and <see cref="Action"/> or <see cref="Controller"/> are /// non-<c>null</c> or if the user provided <c>asp-route-*</c> attributes. /// </exception> public override void Process(TagHelperContext context, TagHelperOutput output) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (output == null) { throw new ArgumentNullException(nameof(output)); } var antiforgeryDefault = true; // If "action" is already set, it means the user is attempting to use a normal <form>. if (output.Attributes.ContainsName(HtmlActionAttributeName)) { if (Action != null || Controller != null || Route != null || RouteValues.Count != 0) { // User also specified bound attributes we cannot use. throw new InvalidOperationException( Resources.FormatFormTagHelper_CannotOverrideAction( "<form>", HtmlActionAttributeName, ActionAttributeName, ControllerAttributeName, RouteAttributeName, RouteValuesPrefix)); } // User is using the FormTagHelper like a normal <form> tag. Antiforgery default should be false to // not force the antiforgery token on the user. antiforgeryDefault = false; } else { // Convert from Dictionary<string, string> to Dictionary<string, object>. var routeValues = RouteValues.ToDictionary( kvp => kvp.Key, kvp => (object)kvp.Value, StringComparer.OrdinalIgnoreCase); TagBuilder tagBuilder; if (Route == null) { tagBuilder = Generator.GenerateForm( ViewContext, Action, Controller, routeValues, method: null, htmlAttributes: null); } else if (Action != null || Controller != null) { // Route and Action or Controller were specified. Can't determine the action attribute. throw new InvalidOperationException( Resources.FormatFormTagHelper_CannotDetermineActionWithRouteAndActionOrControllerSpecified( "<form>", RouteAttributeName, ActionAttributeName, ControllerAttributeName, HtmlActionAttributeName)); } else { tagBuilder = Generator.GenerateRouteForm( ViewContext, Route, routeValues, method: null, htmlAttributes: null); } if (tagBuilder != null) { output.MergeAttributes(tagBuilder); output.PostContent.Append(tagBuilder.InnerHtml); } } if (Antiforgery ?? antiforgeryDefault) { var antiforgeryTag = Generator.GenerateAntiforgery(ViewContext); if (antiforgeryTag != null) { output.PostContent.Append(antiforgeryTag); } } }
/// <inheritdoc /> /// <remarks>Does nothing if <see cref="For"/> is <c>null</c>.</remarks> /// <exception cref="InvalidOperationException"> /// Thrown if <see cref="Items"/> is non-<c>null</c> but <see cref="For"/> is <c>null</c>. /// </exception> public override void Process(TagHelperContext context, TagHelperOutput output) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (output == null) { throw new ArgumentNullException(nameof(output)); } // Ensure GenerateSelect() _never_ looks anything up in ViewData. var items = Items ?? Enumerable.Empty<SelectListItem>(); var tagBuilder = Generator.GenerateSelect( ViewContext, For.ModelExplorer, optionLabel: null, expression: For.Name, selectList: items, currentValues: _currentValues, allowMultiple: _allowMultiple, htmlAttributes: null); if (tagBuilder != null) { output.MergeAttributes(tagBuilder); output.PostContent.Append(tagBuilder.InnerHtml); } }
/// <inheritdoc /> /// <remarks>Does nothing if <see cref="ValidationSummary"/> is <see cref="ValidationSummary.None"/>.</remarks> public override void Process(TagHelperContext context, TagHelperOutput output) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (output == null) { throw new ArgumentNullException(nameof(output)); } if (ValidationSummary == ValidationSummary.None) { return; } var tagBuilder = Generator.GenerateValidationSummary( ViewContext, excludePropertyErrors: ValidationSummary == ValidationSummary.ModelOnly, message: null, headerTag: null, htmlAttributes: null); if (tagBuilder != null) { output.MergeAttributes(tagBuilder); output.PostContent.Append(tagBuilder.InnerHtml); } }