Asp.net-mvc – ASP.NET MVC: Custom Html Helpers in Razor

asp.net-mvcasp.net-mvc-3razor

I am having difficulty with Html Helpers when used with Razor. Said helpers worked fine in MVC 2 with the web form view engine. But not in razor. The error I get at runtime is:

Compiler Error Message: CS1502: The best overloaded method match for 'System.Web.WebPages.WebPageExecutingBase.Write(System.Web.WebPages.HelperResult)' has some invalid arguments

Source Error:


Line 1:  @using Wingspan.Web.Mvc;
Line 2:  @Html.IncrementalMenu(MenuBlock.Site)

Expanding the Show Detailed Compiler Output reveals:

d:\...\Views\Shared\MenuTop.cshtml(2,1): error CS1502: The best overloaded method match for 'System.Web.WebPages.WebPageExecutingBase.Write(System.Web.WebPages.HelperResult)' has some invalid arguments
d:\...\Views\Shared\MenuTop.cshtml(2,7): error CS1503: Argument 1: cannot convert from 'void' to 'System.Web.WebPages.HelperResult'

That indicates to me that razor doesn't like my helper, IncrementalMenu, returning void (which works fine in MVC 2 web form engine views).

I get no errors at Compile time, although the line of code (@Html.IncrementalMenu(…)) is red underlined with the following message:

Cannot implicitly convert type 'void' to 'object'

IncrementalMenu is in the Wingspan.Web.Mvc namespace. It's signature is as follows:

public static void IncrementalMenu(this HtmlHelper html, MenuBlock menuBlock)
{
    // Uses an HtmlTextWriter to render a menu from the sitemap
}

I'm blowed if I know what is wrong…

PS:

The MenuBlock parameter is just an enum that identifies how the menu should render. Don't fixate on this as that is fine.

Best Answer

You can call your helper like this:

@{ Html.IncrementalMenu(MenuBlock.Site); }

WebForms syntax

<% Html.IncrementalMenu(MenuBlock.Site); %>

You just call your method, and the return value (if there is any) is ignored.

Code like this expects a return value, and writes the return value to the html stream:

@Html.YourHelper()

Webforms syntax:

<%: Html.YourHelper() %>

The same, if result value != IHtmlString:

<%= Server.HtmlEncode(Html.YourHelper()) %>