MVC6 TagHelpers 一次性
MVC6 TagHelpers with disposable
在较旧的 MVC HTML Helpers 中,可以使用 IDisposable
来包装内容 - 例如 BeginForm
helper 会自动用结束符 form
标签
<% using (Html.BeginForm()) {%>
*stuff*
<% } %>
MVC6 TagHelpers 支持这种内容包装吗?
例如我想要这个
<widget-box title="My Title">Yay for content!</widget-box>
要扩展为 bootstrap 带有包装 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 github which consumes WidgetBoxTagHelper.cs(将与 Beta/RC/RTM 保持同步,因为我在我的生产应用程序中使用该库)
标签助手必须实现接口 ITagHelper
(正如 @NTaylorMullen 所指出的,TagHelper
class 只是一个方便 class 你可以在实现它时使用)这会强制你使用方法 Process
和 ProcessAsync
,所以你不能依赖于在 Dispose
方法中添加内容。
但是您可以完全控制输出内容,因此您可以 replace/modify 根据需要进行输出。例如,您的小部件标签助手的快速近似值(使用框架的 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>
不要忘记通过将 @addTagHelper
指令添加到 _ViewImports.cshtml 文件来在程序集中注册标签助手。例如,这将在我的应用程序中注册所有助手:
@addTagHelper *, WebApplication2
旧的 beta7 代码
- 在 beta7 中,您必须使用
[TargetElement]
属性。
- TagBuilder class 有一个
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());
}
}
在较旧的 MVC HTML Helpers 中,可以使用 IDisposable
来包装内容 - 例如 BeginForm
helper 会自动用结束符 form
标签
<% using (Html.BeginForm()) {%>
*stuff*
<% } %>
MVC6 TagHelpers 支持这种内容包装吗? 例如我想要这个
<widget-box title="My Title">Yay for content!</widget-box>
要扩展为 bootstrap 带有包装 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 github which consumes WidgetBoxTagHelper.cs(将与 Beta/RC/RTM 保持同步,因为我在我的生产应用程序中使用该库)
标签助手必须实现接口 ITagHelper
(正如 @NTaylorMullen 所指出的,TagHelper
class 只是一个方便 class 你可以在实现它时使用)这会强制你使用方法 Process
和 ProcessAsync
,所以你不能依赖于在 Dispose
方法中添加内容。
但是您可以完全控制输出内容,因此您可以 replace/modify 根据需要进行输出。例如,您的小部件标签助手的快速近似值(使用框架的 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>
不要忘记通过将 @addTagHelper
指令添加到 _ViewImports.cshtml 文件来在程序集中注册标签助手。例如,这将在我的应用程序中注册所有助手:
@addTagHelper *, WebApplication2
旧的 beta7 代码
- 在 beta7 中,您必须使用
[TargetElement]
属性。 - TagBuilder class 有一个
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());
}
}