在razor函数调用中嵌入HTML输出?

时间:2012-12-12 09:26:32

标签: asp.net-mvc razor

我正在查看this页面,其中包含以下razor扩展名:

public static void Repeat<T>(this HtmlHelper html, IEnumerable<T> items, Action<T> render, Action separator)

以下是该页面的用法示例:

<% Html.Repeat(Model.Products, p => { %> 
    <div><%= p.Id%></div>
    <div><%= p.Name%></div>
<%}, () => { %> 
    <br /> <%-- separator --%>
<% }); %>

我无法弄清楚如何将上述代码段转换为razor代码,如何在函数调用代码块中嵌入Html输出?

我试过了:

@Html.Repeat(
  items: Model.Nodes,
  render: node => @: <a href='@node.Title'>@node.Url<a />
, separator: () => @:|
)

但我得到以下例外:

  

CS0201:只能将赋值,调用,递增,递减,等待和新对象表达式用作语句

我更新了Repeat函数,如下所示,现在我的剃刀代码如下所示:

@{
  Html.Repeat(
    items: Model.Nodes,
    template: @<text><a href="@item.Url">@item.Title</a></text>,
    separator:  @<text> | </text>);
}

但实际上没有任何项目被渲染。

3 个答案:

答案 0 :(得分:1)

以下扩展方法允许您使用helper方法直接返回HelperResult,以便在调用时不需要使用括号:

public static class HtmlHelperRepeatExtensions
{
    public static HelperResult Repeat<T>(
        this HtmlHelper html,
        IEnumerable<T> items,
        Func<T, HelperResult> render,
        Func<dynamic, HelperResult> separator
    )
    {
        return new HelperResult(writer =>
        {
            bool first = true;
            foreach (var item in items)
            {
                if (first)
                    first = false;
                else
                    separator(item).WriteTo(writer);
                render(item).WriteTo(writer);
            }
        });
    }
}

然后在你的视图中:

@Html.Repeat(
    new[] { 5, 10, 20 }, 
    @<text>
        @if (item == Model.Search.PageSize)
        {
            <span>@item</span>
        }
        else
        {
            <a href="@Url.SetParameters(new { pagesize = item, page = 1 })">
                @item
            </a>
        }
    </text>,
    @<text>|</text>
)

请注意,我从以下链接中获取了上述代码。有关详细信息,请参阅以下帖子。

Translate to razor Syntax from MVC 2.0 code

答案 1 :(得分:0)

试试这个:

@Html.Repeat(
  items: Model.Nodes,
  render: node => ((Func<dynamic, object>)(@<a href='@node.Title'>@node.Url<a />)).Invoke(node),
  separator: node => ((Func<dynamic, object>)(@<text>|</text>)).Invoke(node)
)

答案 2 :(得分:0)

看起来像Html.Repeat扩展返回类型是void。 aspx引擎渲染器处理它的方式不同。所以扩展方法几乎没有变化。

 @Html.Repeat(p.Categories, cat => {
                    return "<a href=" + Url.SetFacet("cat", cat) + ">" + cat + "</a>";
                 }, ",")

方法定义

    public static MvcHtmlString Repeat<T>(this HtmlHelper html, IEnumerable<T> items, Func<T, string> content, string separator)
    {
        if (items == null)
            items = Enumerable.Empty<T>();
        return MvcHtmlString.Create(string.Join(separator, items.Select(content).ToArray()));
    }