如何将HTML片段(作为委托?)传递给声明性Razor Helper?

时间:2011-08-12 13:35:22

标签: asp.net asp.net-mvc razor razor-declarative-helpers

我一直在编写一些声明Razor Helpers(使用@helper语法)与Umbraco 4.7一起使用,它现在支持Razor视图引擎(尽管我认为这同样适用于WebMatrix或ASP) .NET MVC)。他们都很好。但是,我想让它们更灵活,以便我可以将一个HTML片段传递给它们,这些片段可以“包裹”在输出周围(但只有在有输出时)。例如,我有一个帮助器(这里简化得很多)可以从一些参数生成HTML链接:

@helper HtmlLink(string url, string text = null, string title = null, 
string cssClass = null, bool newWindow = false)
{
    if (!String.IsNullOrEmpty(url))
    {
        System.Web.Mvc.TagBuilder linkTag = new System.Web.Mvc.TagBuilder("a");

        linkTag.Attributes.Add("href", url);
        linkTag.SetInnerText(text ?? url);

        if (!String.IsNullOrEmpty(title))
        {
            linkTag.Attributes.Add("title", title);
        }

        if (!String.IsNullOrEmpty(cssClass))
        {
            linkTag.Attributes.Add("class", cssClass);
        }

        if (newWindow)
        {
            linkTag.Attributes.Add("rel", "external");
        }

        @Html.Raw(linkTag.ToString())
    }
}

调用@LinkHelper.HtmlLink("http://www.google.com/", "Google")会生成HTML输出<a href="http://www.google.com/">Google</a>

但是,如果我可以选择传入一个HTML片段,只要URL有值,那么它将包含在生成的超链接HTML中。我基本上希望能够做到这样的事情:

@LinkHelper.HtmlLink("http://www.google.com/", "Google", @<li>@link</li>)

获取输出

<li><a href="http://www.google.com/">Google</a></li>

@LinkHelper.HtmlLink("", "", @<li>@link</li>)

并且根本没有输出。

我在Phil Haacked的博客中读到了关于Templated Razor Delegates的内容,但是无法理解如何在这种背景下使用它们 - 如果确实有可能的话。我感觉到我错过了什么或者叫错了树。

2 个答案:

答案 0 :(得分:1)

我认为问题出在@link上。模板化的剃刀代表使用“魔术”参数@item获取数据。尝试使用模板中的@link替换@item

另外,发布执行模板的代码 - 您的HtmlLink方法需要Func<dynamic, object>

答案 1 :(得分:1)

如果其他人正在寻找这个......我把以下哪些内容组合在一起。它适用于空字符串,如果委托为空(基于我下面的非常详尽的测试。)

正如Jakub所说,关键是使用魔术@item参数。

@helper HtmlLink(string url, string text = null, 
    Func<IHtmlString, HelperResult> formatterFunction = null,  
    string title = null, string cssClass = null, bool newWindow = false)
{
    if (!String.IsNullOrEmpty(url))
    {
        System.Web.Mvc.TagBuilder linkTag = new System.Web.Mvc.TagBuilder("a");

        linkTag.Attributes.Add("href", url);
        linkTag.SetInnerText(text ?? url);

        if (!String.IsNullOrEmpty(title))
        {
            linkTag.Attributes.Add("title", title);
        }

        if (!String.IsNullOrEmpty(cssClass))
        {
            linkTag.Attributes.Add("class", cssClass);
        }

        if (newWindow)
        {
            linkTag.Attributes.Add("rel", "external");
        }

        // This is the part using the delegate
        if (formatterFunction == null)
        {
            @Html.Raw(linkTag.ToString())
        }
        else
        {
            @formatterFunction(Html.Raw(linkTag.ToString()))
        } 
    }
}

@HtmlLink("http://www.google.com", "Google")
@HtmlLink("http://www.google.com", "Google", @<b>@item</b>)
@HtmlLink("http://www.google.com", "Google", @<text><i>@item</i><br/></text>) @* <br/> fails otherwise *@
@HtmlLink("http://www.google.com", "Google", @<b>@item</b>)
@HtmlLink("", "", @<b>@item</b>)