MVC6 TagHelpers一次性使用

时间:2015-07-22 03:23:38

标签: asp.net-core-mvc tag-helpers

在较旧的MVC HTML帮助程序中,可以使用IDisposable来包装内容 - 例如BeginForm帮助程序会自动换*stuff*并关闭form标记

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

MVC6 TagHelpers是否支持此内容包装? 例如,我想要这个

<widget-box title="My Title">Yay for content!</widget-box>

将扩展为包含divs的引导小部件框:

<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 github消费WidgetBoxTagHelper.cs(将继续使用Beta / RC / RTM,因为我正在使用我的制作应用程序中的lib)

1 个答案:

答案 0 :(得分:6)

标记助手必须实现接口ITagHelper(正如 @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);
    }
}

在你的剃刀中,你将拥有:

<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

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

OLD 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());
    }
}
相关问题