I was trying to create a Razor declarative helper in my App_Code folder for an MVC 3 RTM project.
The problem I ran into was that the MVC HtmlHelper extensions, like ActionLink, aren't available. This is because the compiled helpers derive from System.Web.WebPages.HelperPage
, and though it exposes an Html
property, its of type System.Web.WebPages.HtmlHelper
rather than System.Web.Mvc.HtmlHelper
.
An example of the kind of error I was getting is:
'System.Web.Mvc.HtmlHelper' does not contain a definition for 'ActionLink' and no extension method 'ActionLink' accepting a first argument of type 'System.Web.Mvc.HtmlHelper' could be found (are you missing a using directive or an assembly reference?)
My only solution has been to create my own HelperPage and override the Html property:
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; }
}
}
I then have to write the following at the top of every helper:
@inherits FunnelWeb.Web.App_Code.HelperPage
@using System.Web.Mvc
@using System.Web.Mvc.Html
@helper DoSomething()
{
@Html.ActionLink("Index", "Home")
}
Is it meant to be this hard in MVC 3, or am I doing something wrong?
Looks like the ASP.NET MVC has fixed this issue in VS 2013. See this post http://aspnet.uservoice.com/forums/41201-asp-net-mvc/suggestions/3670180-support-helper-extensionmethod-this-htmlhelper-ht
My approach to this is to simply pass the page as a parameter to the helper method. So in your example it would be:
Then in your Razor view where you need it call it like this:
Doing this immediately gives you access to page properties like
Html
orUrl
that you usually have (and through that theHtmlHelper
extensions).As an additional benefit (if you require this), you also get access to instance properties such as the page's
ViewData
.Take a look at
Marcind
's answer to this question. What you're experiencing is a limitation of putting declarative views in theApp_Code
folder.