mvc - 使用Razor声明性视图中的MVC HtmlHelper扩展
我试图在我的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个解决方案
42 votes
看一看Marcind对这个问题的回答。 您遇到的是将声明性视图放在App_Code文件夹中的限制。
将助手放在App_Code中可以正常工作 但有一定的局限性 影响某些MVC场景(for 示例:无法访问标准MVCHTML。佣工)
Omar answered -06-08T01:22:47Z
38 votes
我为WebPages助手创建了一个扩展方法,以便我可以访问页面助手。
public static HtmlHelper GetPageHelper(this System.Web.WebPages.Html.HtmlHelper html)
{
return ((System.Web.Mvc.WebViewPage) WebPageContext.Current.Page).Html;
}
Jake Hoffner answered -06-08T01:23:12Z
11 votes
奥马尔在这里得到了正确的答案,但我想补充一些东西(请随意将奥马尔的回答标记为答案)。
我们在v1中意识到了这一点并且无法在产品中得到很好的解决方案,但David Ebbo(团队的架构师)发布了一个Visual Studio代码生成器示例,它基本上是第一次探索 我们正在寻求使这项工作正常运行的想法:[/b/davidebb/archive//10/27/turn-your-razor-helpers-into-reusable-libraries.aspx]
尝试一下,看看你的想法! 让大卫知道你是否通过在他的博客上发表评论。
Andrew Stanton-Nurse answered -06-08T01:23:53Z
9 votes
与@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 MVC
Greg Gum answered -06-08T01:24:27Z
7 votes
替代解决方案:
在你的razor-helper文件上添加它:
@functions {
public static System.Web.Mvc.HtmlHelper HHtml = ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Html;
}
然后像这样称呼它:
@HHtml.ActionLink("actionname")
Alex answered -06-08T01:25:01Z
4 votes
为了搜索者的利益,我在创建MVC视图作为类库的一部分(用于组件重用)时遇到了同样的错误。 上面部分提到的解决方案是在.cshtml文件的顶部添加以下using语句:
@using System.Web.Mvc
@using System.Web.Mvc.Html
无需进一步的工作。
HockeyJ answered -06-08T01:25:35Z
3 votes
我的方法是简单地将页面作为参数传递给辅助方法。 所以在你的例子中它将是:
@helper DoSomething(WebViewPage page)
{
@page.Html.ActionLink("Index", "Home")
}
然后在您需要的Razor视图中调用它,如下所示:
@YourHelperFilename.DoSomething(this)
立即执行此操作可以访问您通常拥有的页面属性,如ViewData或Url(以及HtmlHelper扩展名)。
作为额外的好处(如果您需要),您还可以访问实例属性,例如页面ViewData。
Dejan answered -06-08T01:26:22Z
0 votes
我知道MVC 3存在一些智能感知问题。我认为如果你在web.config中设置了命名空间,帮助程序仍然可以工作。
MVC 3 RTM刚刚发布,你使用这个还是测试版?
Lee Smith answered -06-08T01:26:55Z
0 votes
看起来 MVC已经在VS 中解决了这个问题。请参阅这篇文章[/forums/41201-asp-net-mvc/suggestions/3670180-support-helper-extensionmethod-this-htmlhelper-HT]
Omar answered -06-08T01:27:22Z