问题
我有一个非常漂亮的菜单HTML助手为WebFormViewEngine视图编写。此引擎允许您的助手返回void,并且仍然可以使用:
@Html.Theseus
这对我的助手来说很好,因为它可以使用htmltextwriter呈现菜单,直接呈现到输出流。
然而,在Razor视图中,HTML助手将返回一个值(通常是mvchtmlstring),这是添加到输出中的值。差别小,后果大。
有一种方法可以解决这个问题,正如GVS向我指出的(见
ASP.NET MVC 2 to MVC 3: Custom Html Helpers in Razor
)如下:
如果助手返回void,则执行以下操作:
@{Html.Theseus;}
(本质上,您只是调用方法,而不是渲染到视图中)。
虽然仍然很整洁,但这与@html.thesus不太一样。所以…
我的代码很复杂,但工作得很好,所以我不愿意进行主要的编辑,即用另一个编写器替换htmltextwriter。代码片段如下:
writer.AddAttribute(HtmlTextWriterAttribute.Href, n.Url);
writer.AddAttribute(HtmlTextWriterAttribute.Title, n.Description);
writer.RenderBeginTag(HtmlTextWriterTag.A);
writer.WriteEncodedText(n.Title);
writer.RenderEndTag();
// Recursion, if any
// Snip off the recursion at this level if specified by depth
// Use a negative value for depth if you want to render the entire sitemap from the starting node
if ((currentDepth < depth) || (depth < 0))
{
if (hasChildNodes)
{
// Recursive building starts here
// Open new ul tag for the child nodes
// "<ul class='ChildNodesContainer {0} Level{1}'>";
writer.AddAttribute(HtmlTextWriterAttribute.Class, "Level" + currentDepth.ToString());
writer.RenderBeginTag(HtmlTextWriterTag.Ul);
// BuildMenuLevel calls itself here to
// recursively traverse the sitemap hierarchy,
// building the menu as I go.
// Note: this is where I increase the currentDepth variable!
BuildChildMenu(currentDepth + 1, depth, n, writer);
// Close ul tag for the child nodes
writer.RenderEndTag();
}
}
与TagBuilders一起重新编写不会很有趣。现在,它呈现任何类型的菜单,包括“增量导航”,如我的4guysfromrolla文章中所述:
Implementing Incremental Navigation with ASP.NET
选项:
我想我可以返回一个空的mvchtmlstring,但这几乎是黑客的定义…
唯一的选择是进入日落,使用TagBuilder重写助手来构建每个标记,将其添加到StringBuilder,然后构建下一个标记,等等,然后使用StringBuilder实例来创建mvchtmlstring。真的很难看,除非我能做些像…
问题:
有没有办法:
停止呈现到流中的htmltextwriter,而是像使用StringBuilder一样使用它,在我用于创建mvchtmlstring(或htmlstring)的进程结束时使用它?
听起来不太可能,即使我在写…
PS:
关于htmltextWriter,最大的好处是可以构建大量的标记,而不是像使用标记生成器那样一个接一个地构建它们。