ASP.Net MVC3-通过剃刀标记作为参数

本文关键字:参数 剃刀 Net MVC3- ASP | 更新日期: 2023-09-27 18:22:47

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

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

这一切都可以,但我想更改它,使默认标记不是以字符串形式指定的,而是以剃刀语法指定的,类似于:

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

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

我怎样才能做到这一点?

我可以制作一个IDisposable,它在Dispose中关闭TagBuilder等,但使用这种方法,标记仍然会被渲染(我可以清除Dispose()中渲染的内容,但代码块仍然会不必要地运行,我希望避免这种情况)。

是否有其他方法可以将剃刀块传递给辅助对象,这可能是实际渲染的,也可能不是实际渲染的?

ASP.Net MVC3-通过剃刀标记作为参数

下面是一个我用来渲染jQuery模板标记的例子,通过为模板本身传递模板Id和剃刀风格的语法:

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()的调用,以避免呈现"默认"标记。

只是对已接受的答案进行扩展,因为我花了很长时间才解决类似的问题,这就是弹出的问题。我真正需要的是一个@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的两个输入,但我也可以插入部分视图,这在某些方面很方便。由于我不是专家,可能有更好的选择,但对我来说,这似乎是一种灵活的方法。

如果你想知道这是如何在asp.net核心3.1 中实现的

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

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

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

更进一步,可以直接将标记传递给助手,而不需要扩展方法。

@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配合使用,但我的助手只使用他们的参数。