ASP.Net MVC3 - Pass razor markup as a parameter ASP.Net MVC3 - Pass razor markup as a parameter asp.net asp.net

ASP.Net MVC3 - Pass razor markup as a parameter


Here's an example I use to render jQuery Template markup by passing in a template Id and razor-style syntax for the template itself:

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>");}

and this would be called with

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

Basically just use Func<object, HelperResult> as your parameter and template.Invoke(null) (with arguments if necessary) to render it. Obviously you can skip the call to .Invoke() to avoid rendering the "default" markup.


Just to expand on the accepted answer, as it took me quite a while to resolve a similar problem and this is the question which popped up. What I really need was a @helper, which would accept razor text, as the template should contain quite some code. I played around for a long while trying to use several versions of type @helper item(Func<object, HelperResult> input), which I found on the web, with no success. Therefore I went for an approach like:

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());        }    }}

and

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

and use this via

@item(other input, @Html.RazorToMvcString(@<text>this is a test</text>))

Now I can use the helper template for both Razor input, but I can also drop in partial views, which is handy at some points. As I am no expert there might be better options, but it seems like a flexible approach to me.


In case you're wondering this is how to do it in asp.net core 3.1

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

Then in markup you can use it as

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