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

时间:2011-01-17 07:18:29

标签: asp.net-mvc asp.net-mvc-3 razor

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

我遇到的问题是MVC HtmlHelper扩展(如ActionLink)不可用。这是因为编译的帮助程序派生自System.Web.WebPages.HelperPage,虽然它公开了Html属性,但其类型为System.Web.WebPages.HtmlHelper而不是System.Web.Mvc.HtmlHelper

我得到的一种错误的例子是:

  

'System.Web.Mvc.HtmlHelper'没有   包含'ActionLink'的定义   没有扩展方法'ActionLink'   接受第一个类型的参数   'System.Web.Mvc.HtmlHelper'可以   发现(你错过了使用   指令或程序集引用?)

我唯一的解决方案是创建自己的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中这么难,或者我做错了什么?

9 个答案:

答案 0 :(得分:42)

请看Marcind's answer这个问题。您遇到的是将声明性视图放在App_Code文件夹中的限制。

  

将您的助手放在App_Code中   但有一定的局限性   影响某些MVC场景(for   示例:无法访问标准MVC   HTML。助手)

答案 1 :(得分:38)

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

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

答案 2 :(得分:11)

奥马尔在这里得到了正确答案,但我想补充一些内容(请随意将奥马尔的回答标记为答案)。

我们在v1中意识到这一点并且无法在产品中得到很好的解决方案,但是David Ebbo(ASP.Net团队的架构师)发布了一个Visual Studio代码生成器示例,它基本上是一个首先探讨我们正在寻找的想法,使其正常运作:http://blogs.msdn.com/b/davidebb/archive/2010/10/27/turn-your-razor-helpers-into-reusable-libraries.aspx

尝试一下,看看你的想法!让大卫知道你是否通过在他的博客上发表评论。

答案 3 :(得分:9)

与@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 - 编程Microsoft ASP.NET MVC

答案 4 :(得分:7)

另一种解决方案:

在你的razor-helper文件上添加它:

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

然后这样称呼:

@HHtml.ActionLink("actionname")

答案 5 :(得分:4)

为了搜索者的利益,在创建MVC视图作为类库(用于组件重用)的一部分时,我遇到了同样的错误。上面部分提到的解决方案是在.cshtml文件的顶部添加以下using语句:

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

无需进一步的工作。

答案 6 :(得分:3)

我的方法是简单地将页面作为参数传递给helper方法。所以在你的例子中它将是:

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

然后在您需要的Razor视图中,将其称为:

@YourHelperFilename.DoSomething(this)

立即执行此操作后,您可以访问常用的HtmlUrl等页面属性(通过HtmlHelper扩展程序)。

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

答案 7 :(得分:0)

我知道MVC 3存在一些智能感知问题。我认为如果你在web.config中设置了命名空间,帮助程序仍然可以工作。

MVC 3 RTM刚刚被重新发布你使用这个还是测试版?

答案 8 :(得分:0)