代码之家  ›  专栏  ›  技术社区  ›  awrigley

ASP.NET MVC:Razor中的自定义Html帮助程序

  •  63
  • awrigley  · 技术社区  · 14 年前

    与Razor一起使用时,我很难使用Html帮助程序。所说的助手在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'
    

    这表明razor不喜欢我的助手IncrementalMenu,返回void(这在MVC 2 web表单引擎视图中工作得很好)。

    虽然代码行(@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
    }
    

    如果我知道哪里不对劲,我会大发雷霆。。。

    附言:

    MenuBlock参数只是一个枚举,用于标识菜单应如何呈现。别把注意力集中在这上面,因为那很好。

    3 回复  |  直到 12 年前
        1
  •  85
  •   GvS    14 年前

    你可以这样称呼你的助手:

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

    WebForms语法

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

    只需调用方法,返回值(如果有)就会被忽略。

    这样的代码需要返回值,并将返回值写入html流:

    @Html.YourHelper()
    

    Webforms语法:

    <%: Html.YourHelper() %>
    

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

    <%= Server.HtmlEncode(Html.YourHelper()) %>
    
        2
  •  49
  •   awrigley    14 年前

    附录:

    您可以使用@Html.RenderPartial获得相同或类似的错误。在这种情况下,这是因为RenderPartial直接呈现给响应,所以不是字符串,需要在“Razor代码块”中进行编码:

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

    我怀疑这是微软将新的Html.Partial包含在ASP.NET MVC中的原因之一。由于Html.Partial确实返回字符串,因此可以编写:

    @Html.Partial
    

    看起来好多了。考虑到Razor宣称的目标之一是让眼睛看起来更容易,这很可能是真的。

    这也让我,至少,感觉更舒服。我知道返回字符串是什么,我总是这样做。但每次我想“恢复反应”需要更多的脑循环。

    这也符合一句老话:微软终于在第三版中实现了他们的产品。例如,97号通道。

    这是一个令人沮丧的比喻。因为他们在版本4中搞砸了,也就是说,Access 2000。。。

        3
  •  22
  •   Atanas Korchev    14 年前

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

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