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

Posted

技术标签:

【中文标题】ASP.Net MVC3 - 将剃刀标记作为参数传递【英文标题】:ASP.Net MVC3 - Pass razor markup as a parameter 【发布时间】:2012-02-27 18:57:25 【问题描述】:

我有一个名为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>

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

我怎样才能做到这一点?

我可以创建一个IDisposable,在其Dispose 中关闭TagBuilder 等,但是使用这种方法仍然会呈现标记(我可以清除Dispose() 中呈现的内容,但代码块会仍然不必要地运行,我想避免)。

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

【问题讨论】:

【参考方案1】:

下面是一个示例,我通过传入模板 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&lt;object, HelperResult&gt; 作为参数并使用template.Invoke(null)(必要时使用参数)来呈现它。显然,您可以跳过对.Invoke() 的调用,以避免呈现“默认”标记。

【讨论】:

它不起作用。函数调用中的&lt;text&gt;...&lt;/text&gt; 语法未被识别(无效的表达式术语' 很好,现在可以使用了。根本不需要&lt;text&gt; 标签(@ 就足够了),除非剃刀标记实际上是没有任何标签的纯文本,否则只需@&lt;tag&gt; 就足够了。 &lt;text&gt; 标签是正确的。我倾向于使用它们,以防万一我更改模板中的内容 - 如果您愿意,可以在未来证明。 为什么将 null 传递给模板函数?参数有什么作用? 'IHtmlHelper' 不包含 'jQueryTmpl' 的定义,并且没有可访问的扩展方法 'jQueryTmpl' 接受类型为 'IHtmlHelper' 的第一个参数(您是否缺少using 指令或程序集引用?)没有 mvc 核心??【参考方案2】:

只是为了扩展已接受的答案,因为我花了很长时间才解决类似的问题,这就是弹出的问题。我真正需要的是一个@helper,它可以接受剃须刀文本,因为模板应该包含相当多的代码。我玩了很长时间,试图使用我在网上找到的几个版本的@helper item(Func&lt;object, HelperResult&gt; 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 输入,但我也可以放入部分视图,这在某些时候很方便。由于我不是专家,可能会有更好的选择,但对我来说这似乎是一种灵活的方法。

【讨论】:

【参考方案3】:

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

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

然后在标记中你可以使用它

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

【讨论】:

【参考方案4】:

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

@helper HelperWithChild(Func<object, HelperResult> renderChild)

    <div class="wrapper">
        @renderChild(this)
    </div>


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

对于多行标记&lt;text&gt; 也是必需的:

@HelperWithChild(@<text>
    @AnotherHelper()

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

@helper AnotherHelper()

    <p>
        Another helper
    </p>

虽然我不确定this 将如何与Model 一起发挥作用 - 我的助手只使用他们的参数。

【讨论】:

以上是关于ASP.Net MVC3 - 将剃刀标记作为参数传递的主要内容,如果未能解决你的问题,请参考以下文章

如何将模型作为参数传递给 ASP.NET MVC 中的 [HttpPost] ActionMethod?

在 ASP.Net Core 项目中使用 ADO.Net 将 JSON 类型作为参数传递给 SQL Server 2016 存储过程

Css 在 asp.net mvc3 Razor Views 中无法正常工作

模型在使用 C# 将 POST 方法作为参数传递给 ASP.NET MVC 中同一控制器的 GET 方法时获取 NULL

在 ASP.NET MVC3 中正确使用 TempData?

asp.net-mvc:js文件中的剃刀'@'符号