【问题标题】:How to use HtmlHelper extensions in helper views如何在帮助视图中使用 HtmlHelper 扩展
【发布时间】:2015-04-04 02:32:22
【问题描述】:

我想创建一个 Razor 助手来减少我需要编写的代码量。我在我的项目中添加了一个 App_Code 文件夹并添加了一个名为 MyHelpers.cshtml 的文件,其中包含以下内容(用于说明的简单示例)...

@using System.Web.Mvc
@using System.Web.Mvc.Html
@helper HomeLink() {
  @Html.ActionLink("Home", "Index", "Home")
}

但是,这会产生一个编译器异常,表示 Html.ActionLink 没有采用三个字符串的重载。 ActionLink 代码是从可以正常工作的 Razor 页面复制的。在我自己的帮助器中尝试使用任何其他标准帮助器时,我遇到了类似的问题。

如果我尝试使用 Telerik 的 KendoUI 的 MVC 包装器,这些包装器像 @Html.Kendo.ComboBox 一样被引用...然后我在 Html 下看到一条红线,并显示一条消息“无法转换实例类型 System.Web.WebPages .Html.HtmlHelper 到 System.Web.Mvc.HtmlHelper"

根据这篇博文末尾的说明,这是 MVC3 的一个已知问题,但应该会在下一个版本中添加...

http://weblogs.asp.net/scottgu/asp-net-mvc-3-and-the-helper-syntax-within-razor

根据这个 UserVoice 页面,该问题实际上已在 VS2013 中修复...

http://aspnet.uservoice.com/forums/41201-asp-net-mvc/suggestions/3670180-support-helper-extensionmethod-this-htmlhelper-ht

我在一个全新的 MVC5 项目中使用 VS2013 Update 4,但它似乎不起作用。我已经尝试了很多我在这里找到的解决方法,但都没有帮助。

有人有什么想法吗?

【问题讨论】:

  • 我的猜测是,您不能直接在助手内部调用助手,请参阅此帖子以获取可能的解决方案:stackoverflow.com/questions/10522049/…
  • 嗯,看起来像个 hack,但它可能会起作用。我不明白的是,微软说他们解决了这个问题(参见我帖子中的 UserVoice 链接),所以它应该可以工作而不必做这样的事情。无论如何,我会试一试,看看它是否有效。谢谢

标签: asp.net-mvc razor


【解决方案1】:

呃。视野中的助手是可憎的。微软甚至不应该创造这种可能性。执行此类操作的真正方法是创建扩展或使用部分。

扩展

public static class HtmlHelperExtensions
{
    public static MvcHtmlString HomeLink(this HtmlHelper helper, string linkText = "Home")
    {
        return helper.ActionLink(linkText, "Index", "Home");
    }
}

那么,在你看来:

@Html.HomeLink()

或者

@Html.HomeLink("This is my awesome Home link.")

部分

Views\Shared\_HomeLink.cshtml:

@Html.ActionLink("Home", "Index", "Home")

那么在你看来:

@Html.Partial("_HomeLink")

此方法允许覆盖。例如,假设您希望主页链接在商店部分的视图中转到您网站的商店部分的“主页”,您可以添加一个新的局部视图,Views\Store\_HomeLink.cshtml

@Html.ActionLink("Home", "Index", "Store")

对于Views\Store 中的任何视图,此视图将优先于Views\Shared 中的视图。

但是,对于这样的事情,任何一种方法都真的是大材小用。不要过度追求干燥。您可以使用行号作为粗略指南。如果您的抽象与您正在抽象的代码一样多行,那么您应该非常认真地考虑一下它是否值得。抽象的代码可能会改变吗?它有复杂的逻辑吗?像调用Html.ActionLink 这样的事情非常简单,而且通过抽象化它不太可能提供任何真正的投资回报率。

测试是查看此问题的另一种方式,因为 DRY 的目的实际上是减少需要测试的代码量。从这个角度来看,Html.ActionLink 已经经过 Microsoft 的彻底测试。除了直接破坏方法签名(Intellisense 会立即警告您)之外,您无法真正破解它。但是,通过创建帮助程序、部分程序等,您现在引入了复杂性。这是可能因多种原因而失败的新代码。如果您的抽象引入了原本不需要的复杂性和新测试。然后,再一次,你应该退后一步,真正考虑一下是否值得。

【讨论】:

  • 太好了,谢谢。我已经使用了视图内助手,因为它看起来更简单,但是刚刚使用扩展方法进行了尝试,实际上对于我想要的代码类型来说并没有那么难。我仍然认为,如果您主要返回 HTML,则基于 Razor 的方式会更容易,但可能是我对扩展方法的探索还不够。
  • 就我的示例而言,我确实指出我展示的示例非常简单。我不会为这样的事情创建一个助手。我只是不想将此问题与包含我正在使用的所有额外(并且与此问题无关)代码的示例混淆。
  • @AvrohomYisroel:视图内助手的关键问题是它们违反了 MVC 的核心原则之一。视图应该尽可能地没有逻辑。目标是拥有一个非常直接的 UI 层,您可以将其交给没有编程经验的人在必要时进行更改。这样一来,纯前端开发人员可以熟练掌握 JavaScript,但不熟悉 C#,他们可以处理他们需要处理的部分,而您的后端开发人员则可以处理他们的部分。
  • 感谢您的评论。我同意你关于保持观点逻辑清晰的观点。我将帮助程序视为一种代码,而不是视图,但我想我这样做的方式实际上只是一个迷你视图,所以可能不是你说的最好的方式。
猜你喜欢
  • 2011-06-10
  • 1970-01-01
  • 2010-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多