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>
或者类似的东西,比如@section
s 在 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<object, HelperResult>
作为参数并使用template.Invoke(null)
(必要时使用参数)来呈现它。显然,您可以跳过对.Invoke()
的调用,以避免呈现“默认”标记。
【讨论】:
它不起作用。函数调用中的<text>...</text>
语法未被识别(无效的表达式术语'
很好,现在可以使用了。根本不需要<text>
标签(@
就足够了),除非剃刀标记实际上是没有任何标签的纯文本,否则只需@<tag>
就足够了。
<text>
标签是正确的。我倾向于使用它们,以防万一我更改模板中的内容 - 如果您愿意,可以在未来证明。
为什么将 null 传递给模板函数?参数有什么作用?
'IHtmlHelper只是为了扩展已接受的答案,因为我花了很长时间才解决类似的问题,这就是弹出的问题。我真正需要的是一个@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 输入,但我也可以放入部分视图,这在某些时候很方便。由于我不是专家,可能会有更好的选择,但对我来说这似乎是一种灵活的方法。
【讨论】:
【参考方案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>)
对于多行标记<text>
也是必需的:
@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