为 Razor 调整自定义 Html Helper(它使用 HtmlTextWriter 因此返回 void)

2023-12-02

问题

我有一个为 WebFormViewEngine 视图编写的非常漂亮的菜单 Html 帮助器。该引擎允许您的助手返回 void,但仍然能够使用:

@Html.Theseus

这对我的助手来说非常有用,因为它可以使用 HtmlTextWriter 渲染菜单,直接渲染到输出流。

然而,在 Razor 视图中,Html 帮助程序应返回一个值(通常是 MvcHtmlString),该值将添加到输出中。小差异,大后果。

正如 GvS 向我指出的那样,有一种解决方法(请参阅ASP.NET MVC 2 到 MVC 3:Razor 中的自定义 Html 帮助程序) 如下:

如果助手返回 void,则执行以下操作:

@{Html.Theseus;}

(本质上,您只是调用该方法,而不是渲染到视图中)。

虽然仍然很简洁,但这与@Html.Theseus 不太一样。所以...

我的代码很复杂,但工作得很好,所以我不愿意进行重大编辑,即用另一个编写器替换 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();
          }
    }

用 TagBuilder 重新编写不会很有趣。就目前情况而言,它呈现任何类型的菜单,包括我的 4guysfromrolla 文章中描述的“增量导航”:使用 ASP.NET 实现增量导航

选项:

我想我可以返回一个空的 MvcHtmlString,但这几乎是黑客的定义......

唯一的选择是日落时分,使用 TagBuilder 重写帮助器来构建每个标签,将其添加到 StringBuilder,然后构建下一个标签,等等,然后使用 StringBuilder 实例创建 MvcHtmlString。真的很难看,除非我能做类似的事情......

问题:

有没有办法:

停止 HtmlTextWriter 渲染到流,而是像 StringBuilder 一样使用它,在我用来创建 MvcHtmlString (或 HtmlString)的过程结束时?

听起来不太可能,即使在我写的时候……

PS:

HtmlTextWriter 的伟大之处在于您可以构建大量标签,而不是像使用 TagBuilder 那样一个接一个地构建它们。


与您收到的回复相反其他问题Razor 不要求您返回 HtmlString。您的代码现在的问题是您正在编写directly到响应流。 Razor 执行由内而外的操作,这意味着您可能会弄乱响应顺序(请参阅类似的问题).

所以在你的情况下你可能会这样做(虽然我还没有测试过):

public static void Theseus(this HtmlHelper html)
{
    var writer = new HtmlTextWriter(html.ViewContext.Writer);
    ...
}

Edit(跟进解决您的意见):

Html Helpers 完全能够直接返回 HtmlString 或返回 void 并写入上下文编写器。例如,两者Html.Partial and Html.RenderPartial在 Razor 中工作正常。我认为你感到困惑的是syntax需要调用一个版本而不是另一个版本。

例如,考虑一个 Aspx 视图:

<%: Html.Partial("Name") %>
<% Html.RenderPartial("Name") %>

您以不同的方式调用每个方法。如果你颠倒过来,事情就行不通了。在 Razor 中也是如此:

@Html.Partial("Name")
@{ Html.RenderPartial("Name"); }

现在碰巧的是,与 Aspx 相比,Razor 中使用 void 助手的语法要冗长得多。然而,两者都工作得很好。除非你的意思是“问题是 html 助手无法返回 void”。

顺便说一句,如果您确实想使用以下语法调用您的助手:@Html.Theseus()你可以这样做:

public static IHtmlString Theseus(this HtmlHelper html)
{
    var writer = new HtmlTextWriter(html.ViewContext.Writer);
    ...
    return new HtmlString("");
}

但这有点像黑客。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为 Razor 调整自定义 Html Helper(它使用 HtmlTextWriter 因此返回 void) 的相关文章

随机推荐

  • 需要在java中以某种方式识别本地机器

    我试图找出应用程序正在运行的本地计算机的名称 或唯一标识特定计算机的其他方式 我一直在用这个 String hostname java net InetAddress getLocalHost getHostName 效果很好 但我碰巧在分
  • 无法使用 AWS Glue 中的 cx_oracle 连接 Oracle 数据库

    我正在尝试使用 cx oracle 从 AWSglue 连接 Oracle 数据库 但收到此错误消息 数据库错误 DPI 1047 无法找到 64 位 Oracle 客户端库 libclntsh so 无法打开共享对象文件 没有这样的文件或
  • 在不同的 Activity 或 Fragment 之间共享数据的正确方法是什么?

    我需要一个应该具有 UI 工作流程的应用程序 其中用户应该能够浏览应用程序的特定部分 可以是 ListView 或 GridView 并且他可以点击某个项目以显示该特定项目的详细信息 现在 如果用户向右滑动 即ViewPager 视图分页器
  • 更改 lubridate 函数以从星期一而不是星期日开始

    dates lt NULL date lt as Date 01 01 2014 d m Y dates lt data frame date as Date character cal day in year num numeric ca
  • 将大文本文件添加到资产文件夹

    我正在开发一个 Android 2 2 应用程序 我想向 Android 项目添加一些大文本文件 4 5MB 或更多 首先我不知道是否可以将此类大文件添加到资产文件夹中 但是 如果可以的话 是否可以压缩它们 如何压缩文件 并解压 还有其他更
  • 如何从 WebAPI 传递 pdf 并从 MVC 控制器读取 pdf?

    我有一个 Web API 服务 应该返回 PDF 然后我尝试调用该 WebAPI 方法来读取 PDF 这是我的 API 方法 HttpPost Route GetTestPDF public HttpResponseMessage Test
  • Git 推送问题

    我有一个从 github 上新克隆的存储库 地址是git github com JoshClose CsvHelper git如果你想尝试一下 我正在使用 tortoisegit 但如果需要的话 我会使用命令行来解决这个问题 我可能需要稍微
  • 如何动态改变webView的高度?

    我目前正在使用webView来显示新闻 在新闻下面我打算放一些按钮 所以我需要获取webView的高度 以便在所有下载后根据webView的高度改变按钮的位置 在其他那么 如何动态改变webView的高度呢 try this void we
  • ref($variable) 何时返回“IO”?

    这是文档的相关摘录ref功能 返回的值取决于引用所引用的事物的类型 内置类型包括 SCALAR ARRAY HASH CODE REF GLOB LVALUE FORMAT IO VSTRING Regexp 基于此 我想象调用ref在文件
  • Google Cloud Kubernetes Ingress 静态 IP 地址未反映且与设置不同

    我正在尝试在 Google Cloud 上使用 GKE 部署完整的 Web 应用程序 后端为 Nodejs 前端为 Angular 然后为其启用 SSL 我创建了一个全局 IP 地址 随后在列表中看到了它 gcloud 计算地址创建 mat
  • WCF工作流服务REST接口[重复]

    这个问题在这里已经有答案了 可能的重复 WF4 WCF 中的 RESTful 工作流服务端点 我正在尝试使 Windows Workflow Services 4 0 使用 REST 接口 我有一个非常简单的工作流服务 名为 Service
  • 加载谷歌地图时,Safari v5 隐藏 div

    我在 Mac 上使用 Safari v5 时遇到问题 当我的 Google Map Api 加载到页面中时 它隐藏了我的一些其他 div 它们是绝对定位的 在地图加载之前 页面会正确呈现 如果我有一个没有地图的页面 则不会发生问题 例子 w
  • 如何在运行时设置 JTextField 的宽度?

    有人可以帮我如何设置 a 的宽度吗JTextField在运行时 我希望在运行时调整我的文本字段的大小 它将询问用户长度 然后输入将更改文本字段的宽度 if selectedComponent instanceof javax swing J
  • 我正在尝试获取唯一的 CPU ID

    我使用下面的代码来获取唯一的 CPU ID 我在网上找到了使用此代码的各种示例 然而 一个偶然的机会 我碰巧拥有两台华硕笔记本电脑 一个是四核 i5 另一个是重型 i7 八核 两者都是 64 位机器 令我大吃一惊的是 它们都产生相同的 唯一
  • 如何在Powershell中解压文件?

    我有一个 zip文件 需要使用 Powershell 解压其全部内容 我正在这样做 但它似乎不起作用 shell New Object ComObject shell application zip shell NameSpace C a
  • 如何无限期删除 PouchDB 数据库以释放空间?

    如何删除 PouchDB 中的数据库以再次释放磁盘空间 删除仅设置参数 deleted 并保留记录的数据 但是 如何才能以真正删除记录并节省一些空间的方式删除记录呢 因为我想时不时地重置数据库 这样它就不会变得太大 听起来您正在寻找压实 它
  • 如何在asp.net中显示警告框

    我有一个带有提交按钮的注册页面 我想在 用户单击提交按钮 时显示一个警报框 然后 用户输入的数据被插入到数据库中 int i obj IU SubscriberMaster 0 txtFirstname Text txtLastname T
  • Python删除输入行

    我想在 python 3 中有一个输入循环 其中输入的信息会自动从终端删除 f eks 3秒后 我知道 r 的功能可以返回行 但在输入后很难自动换行 while True inputStr input Add the hidden word
  • 如何使用案例删除mysql中的重复项

    现在我正在使用类似的方法来删除 mysql 表中的重复项 delete t2 from my table1 as t1 my table1 as t2 where t1 TestCase t2 TestCase and t2 id gt t
  • 为 Razor 调整自定义 Html Helper(它使用 HtmlTextWriter 因此返回 void)

    问题 我有一个为 WebFormViewEngine 视图编写的非常漂亮的菜单 Html 帮助器 该引擎允许您的助手返回 void 但仍然能够使用 Html Theseus 这对我的助手来说非常有用 因为它可以使用 HtmlTextWrit