ASP.NET MVC:Razor中的自定义Html Helpers

使用Razor时,我遇到了Html Helpers的困难。 所述帮助者在MVC 2中使用web表单视图引擎工作良好。 但不是在剃刀。 我在运行时得到的错误是:

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) 

展开显示详细的编译器输出显示:

 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' 

这表明剃刀不喜欢我的帮手,IncrementalMenu,返回void(在MVC 2 Web表单引擎视图中工作正常)。

编译时我没有错误,尽pipe代码行(@ Html.IncrementalMenu(…))用下面的消息红色下划线:

 Cannot implicitly convert type 'void' to 'object' 

IncrementalMenu位于Wingspan.Web.Mvc命名空间中。 签名如下:

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

如果我知道什么是错的

PS:

MenuBlock参数只是一个枚举,用于标识菜单应该如何呈现。 不要因为这是好事而留意这一点。

你可以这样打电话给你的帮手:

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

WebForms语法

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

你只需调用你的方法,并且返回值(如果有的话)被忽略。

这样的代码需要一个返回值,并将返回值写入htmlstream:

 @Html.YourHelper() 

Webforms语法:

 <%: Html.YourHelper() %> 

同样,如果结果值!= IHtmlString:

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

附录:

您可以通过@ Html.RenderPartial获得相同的或类似的错误。 在这种情况下,这是由于RenderPartial直接呈现给Response,所以不是一个string,需要在“Razor代码块”内编码:

 @{ Html.RenderPartial(...); } 

我怀疑这是微软在ASP.NET MVC中包含新的Html.Partial的原因之一。 由于Html.Partial返回一个string,所以可以这样写:

 @Html.Partial 

看起来好多了 鉴于剃刀的一个宣布的目标是容易在眼睛,这很可能是真实的。

这也使我至less感觉更舒适。 我知道返回一个string是什么,我一直这样做。 但是,每当我想到“回复”就需要更多的脑循环。

它符合旧的谚语,最终微软在第3版中获得他们的产品。EG,Access 97。

这是一个令人郁闷的明喻。 因为它们在版本4中搞砸了,即Access 2000 …

您的HTML帮助程序应该返回代表html的MvcHtmlString,以便正确使用Razor(以及不是WebFormsViewEngine的其他视图引擎)

 public static MvcHtmlString Label(this HtmlHelper html, string expression) { return MvcHtmlString.Create("<label>" + expression + "</label>"); }