MVC6 TagHelpers与一次性 [英] MVC6 TagHelpers with disposable
问题描述
在较早的MVC HTML帮助器中,可以使用IDisposable
来包装内容-例如,BeginForm
帮助器将使用结束的form
标记自动包装*stuff*
In the older MVC HTML Helpers, one could use IDisposable
to wrap content - for example the BeginForm
helper would automatically wrap *stuff*
with a closing form
tag
<% using (Html.BeginForm()) {%>
*stuff*
<% } %>
MVC6 TagHelpers支持这种内容包装吗? 例如,我想要
Is this wrapping of content supported with MVC6 TagHelpers? For example I would like this
<widget-box title="My Title">Yay for content!</widget-box>
将其扩展为带有包装div的引导小部件框:
to be expanded into a bootstrap widget-box with wrapping 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是否可能?
Is this possible with TagHelpers?
解决方案:我已经将@DanielJG的答案烘焙到在github上的工作演示中使用 WidgetBoxTagHelper.cs (将保持与Beta/RC/RTM保持同步,就像在生产应用程序中使用lib一样)
Solution: I have baked @DanielJG's answer into a working demo on github which consumes WidgetBoxTagHelper.cs (will stay current with Beta/RC/RTM as am using the lib in my production app)
推荐答案
标记助手必须实现接口ITagHelper
(如 @NTaylorMullen 所指出的那样,TagHelper
类只是一种方便类(实现时可以使用的类),这迫使您使用方法Process
和ProcessAsync
,因此您不必依赖在Dispose
方法中添加内容.
Tag helpers have to implement the interface ITagHelper
(as pointed by @NTaylorMullen, the TagHelper
class is just a convenience class you can use when implementing it) which forces you to use the methods Process
and ProcessAsync
, so you cannot rely on adding contents in a Dispose
method.
但是,您可以完全控制输出内容,因此可以根据需要替换/修改它.例如,快速了解您的小部件标签帮助程序(使用框架的1.0版本):
However you have full control over the output content so you can replace/modify it as you need. For example, a quick approximation to your widget tag helper (Using the 1.0 version of the framework):
[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);
}
}
在剃须刀中,您将拥有:
In your razor you will have:
<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
指令,从而在程序集中注册标签帮助器.例如,这将在我的应用程序中注册所有助手:
Don´t forget to register the tag helpers in your assembly by adding a @addTagHelper
directive to the _ViewImports.cshtml file. For example this will register all helpers in my application:
@addTagHelper *, WebApplication2
旧的beta7代码
- 在beta7中,您必须使用
[TargetElement]
属性. - TagBuilder类具有一个
SetInnerText
方法,您可以使用该方法将其上下文设置为文本.
- In beta7 you had to use the
[TargetElement]
attribute. - The TagBuilder class had a
SetInnerText
method you could use to set its context as text.
代码如下:
[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.
- There was an
InnerHtml
property in the tag helpers. - There was a
ToHtmlString
method in the tag helpers used to render them as 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());
}
}
这篇关于MVC6 TagHelpers与一次性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!