使用Razor声明视图的MVC HtmlHelper扩展

我试图在我的App_Code文件夹中为MVC 3 RTM项目创build一个Razor声明助手。

我遇到的问题是MVC HtmlHelper扩展,如ActionLink,不可用。 这是因为编译的帮助器派生自System.Web.WebPages.HelperPage ,虽然它公开了一个Html属性,它的typesSystem.Web.WebPages.HtmlHelper而不是System.Web.Mvc.HtmlHelper

我遇到的那种错误的一个例子是:

'System.Web.Mvc.HtmlHelper'没有包含'ActionLink'的定义,也没有find接受'System.Web.Mvc.HtmlHelper'types的第一个参数的扩展方法'ActionLink'(你是否缺lessusing指令或组件参考?)

我唯一的解决办法是创build我自己的HelperPage并重写Html属性:

 using System.Web.WebPages; public class HelperPage : System.Web.WebPages.HelperPage { // Workaround - exposes the MVC HtmlHelper instead of the normal helper public static new HtmlHelper Html { get { return ((System.Web.Mvc.WebViewPage) WebPageContext.Current.Page).Html; } } } 

然后,我必须在每个助手的顶部写下以下内容:

 @inherits FunnelWeb.Web.App_Code.HelperPage @using System.Web.Mvc @using System.Web.Mvc.Html @helper DoSomething() { @Html.ActionLink("Index", "Home") } 

这是否意味着在MVC 3这很难,或者我做错了什么?

看看Marcind对这个问题的回答 。 你所遇到的是在App_Code文件夹中放置声明视图的限制。

把你的帮手放到App_Code里面,但是有一些限制,影响了某些MVC场景(例如:不能访问标准的MVC Html.helper)

我为WebPages帮助器创build了一个扩展方法,以便我可以访问页面帮助器。

 public static HtmlHelper GetPageHelper(this System.Web.WebPages.Html.HtmlHelper html) { return ((System.Web.Mvc.WebViewPage) WebPageContext.Current.Page).Html; } 

奥马尔在这里得到了正确的答案,但我想添加一些东西(请随意标记奥马尔的回答作为答案)。

我们在v1中意识到这一点,并且无法在产品中获得很好的解决scheme,但David Ebbo(ASP.Net团队的架构师)发布了一个Visual Studio代码生成器的示例,这基本上是对我们正在考虑使这项工作正常进行: http : //blogs.msdn.com/b/davidebb/archive/2010/10/27/turn-your-razor-helpers-into-reusable-libraries的.aspx

试试看,看看你的想法! 让大卫知道你是否有在他的博客发表意见。

类似于@Jakes回答:

 public static class MvcIntrinsics { public static System.Web.Mvc.HtmlHelper Html { get { return ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Html; } } public static System.Web.Mvc.AjaxHelper Ajax { get { return ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Ajax; } } public static System.Web.Mvc.UrlHelper Url { get { return ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Url; } } } 

用法:

 @MvcIntrinsics.Html.Raw("test") 

来源:Dino Esposito – 编程微软ASP.NET MVC

另一种解决scheme:

添加这个在你的剃刀帮手文件之上:

 @functions { public static System.Web.Mvc.HtmlHelper<object> HHtml = ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Html; } 

然后像这样调用它:

 @HHtml.ActionLink("actionname") 

为了search者的利益,当创buildMVC视图作为类库的一部分(用于组件重用)时,我得到了同样的错误。 上面部分提到的解决scheme是在.cshtml文件的顶部添加以下使用语句:

 @using System.Web.Mvc @using System.Web.Mvc.Html 

不需要进一步的工作。

我的方法是简单地将页面作为parameter passing给辅助方法。 所以在你的例子中是这样的:

 @helper DoSomething(WebViewPage page) { @page.Html.ActionLink("Index", "Home") } 

然后在你所需要的剃刀视图中,像这样调用它:

 @YourHelperFilename.DoSomething(this) 

立即执行此操作可以访问您通常具有的HtmlUrl等页面属性(并通过HtmlHelper扩展)。

作为额外的好处(如果你需要的话),你也可以访问实例属性,如页面的ViewData

我知道MVC 3有一些intellisense问题。如果你有在web.config中设置的命名空间,我认为帮助者仍然会工作。

MVC 3 RTM刚刚发布是你使用这个还是一个testing版?