如何将lambda传递给Razor辅助方法?

时间:2013-01-14 22:54:27

标签: c# asp.net-mvc razor lambda html-helper

我有一个剃须刀助手方法需要接受一个Func<>,它会返回一些要打印出来的HTML内容。这就是我最初的所作所为:

@helper node(string title, Func<HelperResult> descriptions)
{
    ....
    <div>@descriptions()</div>
    ....
}

@node("title", 
              new Func<HelperResult>(() => 
              {
                 return new HelperResult(
                     @<text>
                     <span>"desc1"</span>
                     <span>"desc2"</span>
                     </text>);
              }))

不幸的是,我的文字永远不会打印出来。也没有错误。

所以我学习了内联助手,并将调用方法更改为:

@node("title",                     
              @<text>
              <span>"desc1"</span>
              <span>"desc2"</span>
              </text>)

但是现在我收到编译错误

  

“委托'System.Func'没有   取1个参数“。

但我没有传递任何论点。

因此,如果我将其更改为Func<object,HelperResult>,然后使用@descriptions(null)调用它,则会收到以下错误:

  

“不能将lambda表达式用作动态参数   调度操作,而不先将其转发给委托或   表达式树类型“

我确定我在某处出了问题,但我不确定它是什么。

编辑:我想我可能已经解决了这个问题,但它引入了一些其他问题。

我做的是在传递给动态方法之前施放lambda。我想这就是错误试图说的:

@node("title",                     
              ((Func<dynamic, HelperResult>)(@<text>
              <span>"desc1"</span>
              <span>"desc2"</span>
              </text>))

这样可以正常打印出span标签。不幸的是,在调用Func时我必须传入一个无用的参数。

现在我遇到的问题是我的真正功能不仅仅是写一些跨度。它更像是这样:

@node("title",                     
              ((Func<dynamic, HelperResult>)(@<text>
              <span>@Helpers.Format(resource.Description,"item")</span>
              </text>))

其中@Helpers.Format是另一个助手,资源是页面模型中的(动态)变量。

当然现在代码运行但没有打印出来(在<span>标签内)。我在我的Format辅助函数中放了一个断点,它命中它并且所有参数都被正确设置,所以我不确定它为什么输出不正确。同样,如果我只是改为                   resource.Description 然后什么都没有输出。

由于它在此上下文之外运行良好,我想知道Razor的内联助手不会捕获外部变量吗?

2 个答案:

答案 0 :(得分:9)

实际上HelperResult是微软宁愿你没有使用的东西,正如文档所证明的那样:

  

public class HelperResult:名称空间中的IHtmlString   System.Web.WebPages

     

摘要:此类型/成员支持.NET Framework基础结构   并不打算直接在您的代码中使用。

您的问题的一个可能的解决方案可能是将您的描述函数包装在另一个帮助器中,然后将该帮助程序作为method group传递给您的节点帮助程序,如下所示:

@helper Node(string title, Func<HelperResult> descriptions)
{
    <div>@descriptions()</div>
}

@helper Description() {
    <span>desc1</span>
    <span>desc2</span>
}

@Node("title", Description)

在任何情况下,你的第一个想法都不行,因为Func类型的参数实际上等于无参数函数,在这种情况下你需要像这样编写lambda表达式:

myFunction( () => doSomething)

所以你的函数调用应该是:

@node("title", () =>                    
              @<text>
              <span>"desc1"</span>
              <span>"desc2"</span>
              </text>)

由于这些帮助者的未来是a bit dubious,我会考虑切换到HtmlHelpers获取html的小片段或Partials更大的块。

答案 1 :(得分:2)

@Test(new Func<object, HelperResult>[]{@<text>hello</text>})

@Test(new Func<object, HelperResult>[]{@<text>hello</text>,@<text>world</text>})


@helper Test(params Func<object, HelperResult>[] results)
{
    foreach (var result in results)   
    {
        @result(null);
    }
}