我试图在我的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中这么难,或者我做错了什么?
答案 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)
立即执行此操作后,您可以访问常用的Html
或Url
等页面属性(通过HtmlHelper
扩展程序)。
作为额外的好处(如果您需要),您还可以访问实例属性,例如页面ViewData
。
答案 7 :(得分:0)
我知道MVC 3存在一些智能感知问题。我认为如果你在web.config中设置了命名空间,帮助程序仍然可以工作。
MVC 3 RTM刚刚被重新发布你使用这个还是测试版?
答案 8 :(得分:0)
看起来ASP.NET MVC已在VS 2013中修复了此问题。请参阅此帖子http://aspnet.uservoice.com/forums/41201-asp-net-mvc/suggestions/3670180-support-helper-extensionmethod-this-htmlhelper-ht