在较旧的 MVC HTML Helpers 中,可以使用 IDisposable 来包装内容 - 例如 BeginForm 助手会自动用关闭的 *stuff* 标签包装 form

<% using (Html.BeginForm()) {%>
   *stuff*
<% } %>

MVC6 TagHelpers 是否支持这种内容包装?
例如我想要这个
<widget-box title="My Title">Yay for content!</widget-box>

要扩展为带有包装 div 的引导小部件框:
<div class="widget-box">
    <div class="widget-header">
        <h4 class="widget-title">My Title</h4>
    </div>
    <div class="widget-body">
        <div class="widget-main">
            Yay for content!
        </div>
    </div>
</div>

TagHelpers 可以做到这一点吗?

解决方案 :我已将@DanielJG 的答案烘焙到消耗 working demo on githubWidgetBoxTagHelper.cs(将与 Beta/RC/RTM 保持同步,因为我在我的生产应用程序中使用了 lib)

最佳答案

标签助手必须实现 ITagHelper 接口(interface)(正如 @NTaylorMullen 所指出的,TagHelper 类只是您在实现它时可以使用的便利类),这迫使您使用 ProcessProcessAsync 方法,因此您不能依赖于添加内容在 Dispose 方法中。

但是,您可以完全控制输出内容,因此您可以根据需要替换/修改它。例如,快速近似您的小部件标签助手( 使用框架 的 1.0 版本):

[HtmlTargetElement("widget-box")]
public class WidgetTagHelper : TagHelper
{
    public string Title { get; set; }

    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        var outerTag = new TagBuilder("div");
        outerTag.Attributes.Add("class", output.TagName);
        output.MergeAttributes(outerTag);
        output.TagName = outerTag.TagName;

        //Create the header
        var header = new TagBuilder("div");
        header.Attributes.Add("class", "widget-header");
        header.InnerHtml.Append(this.Title);
        output.PreContent.SetHtmlContent(header);

        //Create the body and replace original tag helper content
        var body = new TagBuilder("div");
        body.Attributes.Add("class", "widget-body");
        var originalContents = await output.GetChildContentAsync();
        body.InnerHtml.Append(originalContents.GetContent());
        output.Content.SetHtmlContent(body);
    }
}

在您的 Razor 中,您将拥有:
<widget-box title="My Title">Yay for content!</widget-box>

这将呈现为:
<div class="widget-box">
    <div class="widget-header">My Title</div>
    <div class="widget-body">Yay for content!</div>
</div>

不要忘记通过向 _ViewImports.cshtml 文件添加 @addTagHelper 指令来在程序集中注册标签助手。例如,这将在我的应用程序中注册所有帮助程序:
@addTagHelper *, WebApplication2

旧 beta7 代码
  • 在 beta7 中,您必须使用 [TargetElement] 属性。
  • TagBuilder 类有一个 SetInnerText 方法,可用于将其上下文设置为文本。

  • 代码如下:
    [TargetElement("widget-box")]
    public class WidgetTagHelper : TagHelper
    {
        private IHtmlEncoder encoder;
        public WidgetTagHelper(IHtmlEncoder encoder)
        {
            this.encoder = encoder;
        }
    
        public string Title { get; set; }
    
        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            var outerTag = new TagBuilder("div");
            outerTag.Attributes.Add("class", output.TagName);
            output.MergeAttributes(outerTag);
            output.TagName = outerTag.TagName;
    
            //Create the header
            var header = new TagBuilder("div");
            header.Attributes.Add("class", "widget-header");
            header.SetInnerText(this.Title);
            output.PreContent.SetContent(header);
    
            //Create the body and replace original tag helper content
            var body = new TagBuilder("div");
            body.Attributes.Add("class", "widget-body");
            var originalContents = await context.GetChildContentAsync();
            using (var writer = new StringWriter())
            {
                body.TagRenderMode = TagRenderMode.StartTag;
                body.WriteTo(writer, encoder);
                originalContents.WriteTo(writer, encoder);
                body.TagRenderMode = TagRenderMode.EndTag;
                body.WriteTo(writer, encoder);
                output.Content.SetContent(writer.ToString());
            }
        }
    }
    

    旧 beta5 代码
  • 标签助手中有一个 InnerHtml 属性。
  • 标签助手中有一个 ToHtmlString 方法,用于将它们呈现为 html。

  • 代码如下:
    [TargetElement("widget-box")]
    public class WidgetTagHelper: TagHelper
    {
        public string Title { get; set; }
    
        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            var outerTag = new TagBuilder("div");
            outerTag.Attributes.Add("class", output.TagName);
            output.MergeAttributes(outerTag);
            output.TagName = outerTag.TagName;
    
            //Create the header
            var header = new TagBuilder("div");
            header.Attributes.Add("class", "widget-header");
            header.InnerHtml = this.Title;
            output.PreContent.SetContent(header.ToHtmlString(TagRenderMode.Normal).ToString());
    
            //Create the body and replace original tag helper content
            var body = new TagBuilder("div");
            body.Attributes.Add("class", "widget-body");
            var originalContents = await context.GetChildContentAsync();
            body.InnerHtml = originalContents.GetContent();
            output.Content.SetContent(body.ToHtmlString(TagRenderMode.Normal).ToString());
        }
    }
    

    关于asp.net-core-mvc - MVC6 TagHelpers 一次性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31553298/

    10-13 01:59