Как создать собственный редактор с привязкой модели с помощью Tag Helper

Я использовал следующий код в нескольких представлениях:

<input asp-for="@Model.Tags" class="form-control" data-provider="tagseditor" />
<!-- some additional code will be added in future -->

и я хотел бы взять этот код и создать из него повторно используемый TagHelper (или, альтернативно, ViewComponent), поэтому я буду использовать его следующим образом:

<tags-editor for="@Model.Tags" />

Однако я не могу передать ModelExpression из моего пользовательского помощника тега в базовый InputTagHelper.

Я собираюсь:

ArgumentException: имя поля HTML не может быть пустым или пустым. Вместо этого используйте методы Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper.Editor или Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper`1.EditorFor с непустым значением аргумента htmlFieldName. Имя параметра: выражение

На этой строке: _htmlHelper.PartialAsync

<!-- Views/Shared/TagHelpers/TagsEditor -->
@model ModelExpression
<input asp-for="@Model" class="form-control" data-provider="tagseditor" />
[HtmlTargetElement("tags-editor", Attributes = "for", TagStructure = TagStructure.WithoutEndTag)]
public class TagsEditorTagHelper : TagHelper
{
    private HtmlHelper _htmlHelper;
    private HtmlEncoder _htmlEncoder;

    public TagsEditorTagHelper(IHtmlHelper htmlHelper, HtmlEncoder htmlEncoder)
    {
        _htmlHelper = htmlHelper as HtmlHelper;
        _htmlEncoder = htmlEncoder;
    }


    [HtmlAttributeName("for")]
    public ModelExpression For { get; set; }

    [ViewContext]
    public ViewContext ViewContext
    {
        set => _htmlHelper.Contextualize(value);
    }


    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        output.TagName = null;

        //exception thrown here:
        var partial = await _htmlHelper.PartialAsync("TagHelpers/TagsEditor", For);

        var writer = new StringWriter();
        partial.WriteTo(writer, _htmlEncoder);

        output.Content.SetHtmlContent(writer.ToString());
    }
}

1 ответ

Суть проблемы заключается в том, что ModelExpression это не модель сама по себе. Вам придется позвонить его Model имущество.

Итак, по вашему частичному мнению:

<!-- Views/Shared/TagHelpers/TagsEditor -->
@model ModelExpression
<input asp-for="@Model.Model" class="form-control" data-provider="tagseditor" />

Тогда вы не можете установить имя выходного тега на ноль, потому что это сгенерирует <null></null> тег по вашему мнению. Я предлагаю вам изменить его на "div" или любой другой контейнер, который вам подходит.

Наконец, поскольку входной тег самозакрывающийся, вам нужно изменить режим выходного тега на TagMode.StartTagAndEndTag заставить генерировать <div></div> вместо просто <div/>,

Все сказали, ProcessAsync метод становится:

public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
    output.TagName = "div";
    output.TagMode = TagMode.StartTagAndEndTag;

    var partial = await _htmlHelper.PartialAsync("TagHelpers/TagsEditor", For);
    var writer = new StringWriter();
    partial.WriteTo(writer, _htmlEncoder);

    output.Content.SetHtmlContent(writer.ToString());
}
Другие вопросы по тегам