asp.net-mvc – 为Razor调整自定义Html助手(它使用HtmlTextWrite
问题
我为WebFormViewEngine视图编写了一个非常漂亮的菜单Html帮助器.这个引擎允许你的助手返回void,仍然可以使用: @Html.Theseus 这对我的助手很有用,因为它可以使用HtmlTextWriter渲染菜单,直接渲染到输出流. 但是,在Razor视图中,Html助手应该返回一个值(通常是MvcHtmlString),这是添加到输出中的值.差异小,后果大. 有一种解决方法,正如GvS(见ASP.NET MVC 2 to MVC 3: Custom Html Helpers in Razor)所指出的那样: 如果帮助程序返回void,请执行以下操作: @{Html.Theseus;} (基本上,您只是调用方法,而不是渲染到视图中). 虽然仍然很整洁,但这与@ Html.seus不完全相同.所以… 我的代码很复杂,但效果很好,所以不愿意进行主要编辑,即用另一个编写器替换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文章中描述的“增量导航”: 选项: 我想我可以返回一个空的MvcHtmlString,但这几乎是一个黑客的定义…… 唯一的选择是进入夕阳并使用TagBuilder重写帮助程序来构建每个标记,将其添加到StringBuilder,然后构建下一个标记等,然后使用StringBuilder实例创建MvcHtmlString.严重丑陋,除非我能做点什么…… 问题: 有办法: 停止HtmlTextWriter渲染到流,而是像StringBuilder一样使用它,在我用来创建MvcHtmlString(或HtmlString)的过程结束时? 听起来不太可能,即使我写的…… PS: 关于HtmlTextWriter的好处是你可以构建大量的标签,而不是像TagBuilder一样逐个构建它们. 解决方法
与您收到的
other question Razor的回复相反,您不需要返回HtmlString.您的代码现在的问题是您直接写入响应流. Razor内部执行内容,这意味着您可以搞砸响应顺序(参见
similar question).
所以在你的情况下你可能会这样做(虽然我还没有测试过): public static void Theseus(this HtmlHelper html) { var writer = new HtmlTextWriter(html.ViewContext.Writer); ... } 编辑(跟进以解决您的意见): Html Helpers完全能够直接返回HtmlString或void并写入上下文编写器.例如,Html.Partial和Html.RenderPartial在Razor中都能正常工作.我认为你困惑的是调用一个版本而不是另一个版本所需的语法. 例如,考虑一个Aspx视图: <%: Html.Partial("Name") %> <% Html.RenderPartial("Name") %> 您以不同方式调用每种方法如果你翻转东西,事情将无法奏效.同样在Razor中: @Html.Partial("Name") @{ Html.RenderPartial("Name"); } 现在只是碰巧使用void helper的语法在Razor中比Aspx更冗长.但是,两者都工作得很好.除非你的意思是“问题在于html助手无法返回void”. 顺便说一句,如果你真的想用这个语法调用你的助手:@ Html.Theseus()你可以这样做: public static IHtmlString Theseus(this HtmlHelper html) { var writer = new HtmlTextWriter(html.ViewContext.Writer); ... return new HtmlString(""); } 但这有点像黑客. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- ASP.NET MVC 4 AJAX提交表单不工作
- asp.net-mvc – 在自定义编辑器中只包含一次脚本
- asp.net-mvc – datetime.parse用西班牙语进行游
- 哪个是在ASP.NET中使用字符串的最佳实践(C#)
- 使用System.Net.Mail中的SMTP发送邮件(带附件)
- asp.net – 通过Visual Basic从网站检索数据
- asp.net-mvc – ValidateInput(false)和AllowHtm
- ASP.NET MVC,ActionFilters,静态类和传递数据
- C# 快速高效率复制对象另一种方式 表达式树
- asp.net – “此操作需要IIS集成管道模式