Помощники встроенных тегов Asp.Net MVC Core не будут обрабатывать атрибуты, предоставленные пользовательскими тегами - PullRequest
0 голосов
/ 04 декабря 2018

Из-за скуки написания одних и тех же шаблонных форм я подумал, что лучше написать помощник по тегам, который будет производить атрибуты, которые можно обрабатывать из помощников бирок.Но, несмотря на то, что мне удалось получить помощника по тегам перед началом работы до помощников по тегам формы, помощники по тегам формы не будут обрабатывать те, которые я создаю.

Вот cshtml:

@model City

@{
    Layout = "_Layout";
    ViewData["Title"] = "Create City";
}

<form method="post" asp-action="Create">
    @foreach (string propName in BaseModel.GetProperties<City>()) {
        <formgroup for="@propName" />
    }

    <div class="form-group">
        <label asp-for="Name">Name:</label>
        <input class="form-control" asp-for="Name" />
    </div>
    <div class="form-group">
        <label asp-for="Country">Country:</label>
        <input class="form-control" asp-for="Country" />
    </div>
    <div class="form-group">
        <label asp-for="Population">Population:</label>
        <input class="form-control" asp-for="Population" />
    </div>
    <button type="submit" class="btn btn-primary">Create</button>
    <a class="btn btn-secondary" asp-controller="Home" asp-action="Index">Cancel</a>
</form>

Вот вывод:

<form method="post" action="/City/Create">
        <div class="form-group"><label asp-for="Name"></label><input asp-for="Name" class="form-control"></div>
        <div class="form-group"><label asp-for="Country"></label><input asp-for="Country" class="form-control"></div>
        <div class="form-group"><label asp-for="Population"></label><input asp-for="Population" class="form-control"></div>

    <div class="form-group">
        <label for="Name">Name:</label>
        <input class="form-control" type="text" id="Name" name="Name" value="">
    </div>
    <div class="form-group">
        <label for="Country">Country:</label>
        <input class="form-control" type="text" id="Country" name="Country" value="">
    </div>
    <div class="form-group">
        <label for="Population">Population:</label>
        <input class="form-control" type="number" data-val="true" data-val-required="The Population field is required." id="Population" name="Population" value="">
    </div>
    <button type="submit" class="btn btn-primary">Create</button>
    <a class="btn btn-secondary" href="/">Cancel</a>
    <input name="__RequestVerificationToken" type="hidden" value="CfDJ8M_6usK6CRRNkwluTiTW8uaAAfhMcU9tAxyCT7z55zQKmpUwpi_lfSDIN4FrlMo9cE3Ka9zgX4WdpXHUdlBFVGsLIw7h_cR3FjJb6Vjqnjm8mQmtKTey_9l188p9E2sKgiksO_OB6K9-F1D7SP2lX0g"></form>

Вот мой помощник тегов:

using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;

namespace ViewComponents.Infrastructure.TagHelpers {
    [HtmlTargetElement("formgroup", Attributes = "for", TagStructure = TagStructure.NormalOrSelfClosing)]
    public class FormGroupTagHelper : TagHelper {

        /// <inheritdoc />
        public override int Order => -2000;

        [HtmlAttributeNotBound]
        [ViewContext]
        public ViewContext ViewContext { get; set; }

        protected IHtmlGenerator Generator { get; }

        public string For { get; set; }

        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));
            }

            // So that other tag helpers are processed after me...
            var childContent = await output.GetChildContentAsync();

            // Starting up...
            // Replace the tag name, include the form-group bootstrap class.

            output.TagName = "div";
            output.TagMode = TagMode.StartTagAndEndTag;
            output.Attributes.Add("class", "form-group");

            PropertyInfo propInfo = ViewContext.ViewData.ModelMetadata.ModelType.GetTypeInfo().GetDeclaredProperty(For);
            output.Content.AppendHtml(GenerateLabel(new Dictionary<string, string> { ["asp-for"] = propInfo.Name }));
            output.Content.AppendHtml(GenerateInput(new Dictionary<string, string> { ["asp-for"] = propInfo.Name, ["class"] = "form-control" }));
        }

        public static IHtmlContent GenerateLabel(IReadOnlyDictionary<string, string> attrDict) {
            TagBuilder tBuilder = new TagBuilder("label");
            foreach (var kvp in attrDict)
                tBuilder.Attributes.Add(kvp);
            return tBuilder;
        }

        public static IHtmlContent GenerateInput(IReadOnlyDictionary<string, string> attrDict) {
            TagBuilder tBuilder = new TagBuilder("input");
            foreach (var kvp in attrDict)
                tBuilder.Attributes.Add(kvp);
            return tBuilder;
        }
    }
}

Любая помощь будет оценена.Хорошего вам дня!

1 Ответ

0 голосов
/ 04 декабря 2018

Помощники тегов не обрабатываются в определенном порядке, поэтому вы не можете рассчитывать на то, что один сможет что-то сделать на основе вывода другого.Каждый помощник по тегам должен быть спроектирован так, чтобы он работал независимо от других, поэтому, если вам нужно визуализировать HTML-код, вам придется самостоятельно обрабатывать это в своем помощнике по тегам.Однако, поскольку вы пытаетесь с помощью одного тега генерировать любое поле формы, это будет тяжелая работа.Это в основном выходит за рамки того, для чего предназначен помощник по тегам.

...