Asp.net mvc 如何在助手视图中使用HtmlHelper扩展

Asp.net mvc 如何在助手视图中使用HtmlHelper扩展,asp.net-mvc,razor,Asp.net Mvc,Razor,我想创建一个Razor助手来减少需要编写的代码量。我在我的项目中添加了一个App_代码文件夹,并添加了一个名为MyHelpers.cshtml的文件,其中包含以下内容(为了说明起见,这是一个简单的示例) 但是,这会产生一个编译器异常,表示Html.ActionLink没有包含三个字符串的重载。ActionLink代码是从一个运行良好的Razor页面复制的。在我自己的助手中尝试使用任何其他标准助手时,我都会遇到类似的问题 如果我尝试为Telerik的KendoUI使用MVC包装器,它被引用为@Ht

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

但是,这会产生一个编译器异常,表示Html.ActionLink没有包含三个字符串的重载。ActionLink代码是从一个运行良好的Razor页面复制的。在我自己的助手中尝试使用任何其他标准助手时,我都会遇到类似的问题

如果我尝试为Telerik的KendoUI使用MVC包装器,它被引用为@Html.Kendo.ComboBox。。。然后我在Html下面得到一条红线,并显示一条消息“无法将实例类型System.Web.WebPages.Html.HtmlHelper转换为System.Web.Mvc.HtmlHelper”

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

根据这个用户语音页面,这个问题实际上在VS2013中得到了解决

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


有人有什么想法吗?

啊。在我看来,帮手是令人憎恶的。微软甚至不应该创造这种可能性。这样做的真正方法是创建扩展或使用分部

扩展

public static class HtmlHelperExtensions
{
    public static MvcHtmlString HomeLink(this HtmlHelper helper, string linkText = "Home")
    {
        return helper.ActionLink(linkText, "Index", "Home");
    }
}
那么,在你看来:

@Html.HomeLink()
@Html.Partial("_HomeLink")

部分

Views\Shared\\u HomeLink.cshtml
中:

@Html.ActionLink("Home", "Index", "Home")
@Html.ActionLink("Home", "Index", "Store")
那么在你看来,

@Html.HomeLink()
@Html.Partial("_HomeLink")
此方法允许重写。例如,假设您希望home链接转到站点store部分的“主页”以查看store部分中的视图,您可以添加一个新的部分视图,
views\store\\u HomeLink.cshtml

@Html.ActionLink("Home", "Index", "Home")
@Html.ActionLink("Home", "Index", "Store")
对于
Views\Store
中的任何视图,此视图将优先于
Views\Shared
中的视图

然而,对于这样的事情,任何一种方法都是过分的。不要过分追求干燥。您可以使用行号作为粗略的参考。如果您的抽象占用的行数与您正在抽象的代码一样多,那么您应该认真考虑是否值得花时间。抽象代码可能会更改吗?它有复杂的逻辑吗?类似于调用
Html.ActionLink
的操作非常简单,而且通过抽象它不太可能提供任何真正的ROI


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

我的猜测是,你不能直接在helpers中呼叫helpers,请参阅此帖子以获得一个可能的解决方案:嗯,看起来像一个黑客,但它可能会起作用。我不明白的是,微软说他们已经解决了这个问题(请参阅我文章中的UserVoice链接),所以它应该可以工作,而不必做这样的事情。无论如何,我会试试看它是否有效。太好了,谢谢。我使用了in-view帮助程序,因为它看起来更简单,但刚刚用扩展方法尝试了它,对于我想要的代码类型来说,它实际上并不难。我仍然认为,如果返回的主要是HTML,那么基于Razor的方法会更容易,但可能是因为我对扩展方法的探索不够。我不会费心为类似的东西创建一个助手。我只是不想把这个问题与一个包含了我正在使用的所有额外(与这个问题无关)代码的示例混淆。@avrohmyisroel:in-view helpers的关键问题是它们违反了MVC的一个核心原则。视图应该尽可能没有逻辑。我们的目标是拥有一个非常直接的UI层,您可以将它交给没有编程经验的人,以便在必要时进行更改。这使得纯前端开发人员能够熟练使用JavaScript,但不需要太多的C#,他们可以处理他们需要处理的部分,而后端开发人员可以处理他们的部分。谢谢您的评论。我同意你关于保持观点逻辑清晰的观点。我把helpers看作是一段代码,而不是一个视图,但我想我这样做的方式实际上只是一个迷你视图,所以可能不是你说的最好的方式。