ASP.Net MVC3 - 将剃刀标记作为参数传递

时间:2012-02-06 09:08:41

标签: c# asp.net asp.net-mvc-3 .net-4.0 razor

我有一个名为EditableArea的帮助器,它为用户提供了一个运行时可编辑的div(通过JS)。 EditableArea帮助程序检查数据库中是否存在具有指定ID的可编辑区域(与MVC的Area无关),如果是,则呈现该区域的HTML,否则它将显示指定为帮助程序参数的默认标记:

@Html.EditableArea(someId, "<p>Click to edit contents</p>")

一切正常,但我想更改它,以便默认标记不是作为字符串指定,而是使用razor语法,如:

@using (Html.EditableArea(someId))
{
    <p>Click to edit contents</p>
}

或者类似的东西,比如@section在MVC3中的工作方式。

我怎样才能实现这一目标?

我可以在其IDisposable中关闭TagBuilder等Dispose,但是使用这种方法仍会呈现标记(我可以清除{{1}中的渲染内容但是代码块仍然会不必要地运行,我想避免这种情况。

是否有其他方法可以将剃刀块传递给帮助程序,这可能会或可能不会实际呈现?

4 个答案:

答案 0 :(得分:27)

这是我用来通过传递模板ID和模板本身的razor样式语法来呈现jQuery模板标记的示例:

public static MvcHtmlString jQueryTmpl(this HtmlHelper htmlHelper, 
    string templateId, Func<object, HelperResult> template) 
{
    return MvcHtmlString.Create("<script id=\"" + templateId + 
        "\" type=\"x-jquery-tmpl\">" + template.Invoke(null) + "</script>");
}

,这将通过

调用
@Html.jQueryTmpl("templateId", @<text>any type of valid razor syntax here</text>)

基本上只需使用Func<object, HelperResult>作为参数,然后使用template.Invoke(null)(如有必要,使用参数)来渲染它。显然,您可以跳过对.Invoke()的调用,以避免呈现“默认”标记。

答案 1 :(得分:3)

只是为了扩展已接受的答案,因为我花了很长时间来解决类似的问题,这就是弹出的问题。我真正需要的是@helper,它会接受剃刀文本,因为模板应该包含相当多的代码。我玩了很长时间试图使用我在网上找到的@helper item(Func<object, HelperResult> input)类型的几个版本,但没有成功。因此,我采取了一种方法:

namespace project.MvcHtmlHelpers
{
    public static class HelperExtensions
    {
        public static MvcHtmlString RazorToMvcString(this HtmlHelper htmlHelper, Func<object, HelperResult> template)
        {
            return MvcHtmlString.Create(template.Invoke(null).ToString());
        }
    }
}

@project.MvcHtmlHelpers    
@helper item(other input, MvcHtmlString content)
    {
        <div class="item">
            ...other stuff... 
            <div class="content">
                @content
            </div>
        </div>
    }

并通过

使用此功能
@item(other input, @Html.RazorToMvcString(@<text>this is a test</text>))

现在我可以使用辅助模板进行Razor输入,但我也可以放入部分视图,这在某些方面很方便。由于我不是专家,可能有更好的选择,但对我来说这似乎是一种灵活的方法。

答案 2 :(得分:0)

如果您想知道这是在asp.net core 3.1中如何做

@{
    void TemplateFunc(Func<object, IHtmlContent> template)
    {
        <div>@template(null)</div>
    }
}

然后在标记中可以将其用作

<div>
@{TemplateFunc(@<div>123</div>);}
</div>

答案 3 :(得分:-1)

更进一步,可以将标记直接传递给帮助程序,而无需扩展方法。

@helper HelperWithChild(Func<object, HelperResult> renderChild)
{
    <div class="wrapper">
        @renderChild(this)
    </div>
}

@HelperWithChild(@<h1>Hello</h1>)

对于多行标记,<text>也是必需的:

@HelperWithChild(@<text>
    @AnotherHelper()

    <h1>
        With more markup
    </h1>
</text>)

@helper AnotherHelper()
{
    <p>
        Another helper
    </p>
}

尽管我不确定this将如何与Model一起玩-我的助手仅使用其参数。