haferje
haferje

Reputation: 1003

Is it possible for a lambda function to contain Razor syntax and be executed in a View?

Is it possible to define the contents of a lambda expression (delegate, Action, Func<>) with Razor syntax, so that when this model method is executed in the view, it will insert that Razor content?

The intended purpose of this is for our developers to be able to define their own custom content to be inserted at a particular point in the CustomControl's view.

The following is stripped-down example code that mimics my current layout. The particular parts of focus are the RenderSideContent method definition and its executing call.

Index.cshtml

@model My.PageModel

@My.CustomControl(new CustomControlModel
    {
        AreaTitle = "Details",
        RenderSideContent = () =>
        {
            <div>
                @using (My.CustomWrapper("General"))
                {
                    My.BasicControl(Model.Controls[0])
                }
            </div>
        }
    })

CustomControl.cshtml

<div>
    @Model.AreaTitle
    <div class="my-custom-content">
        @Model.RenderSideContent()
    </div>
</div>

Upvotes: 6

Views: 1920

Answers (2)

James Wilkins
James Wilkins

Reputation: 7378

It is possible, using Templated Razor Delegates:

@{
  Func<dynamic, object> b = @<strong>@item</strong>;
}
<span>This sentence is @b("In Bold").</span>

@<text>...</text> is the format. The razor compiler will create a lambda expression. At the moment I'm using ASP.Net Core, so it looks like this:

item => new Microsoft.AspNetCore.Mvc.Razor.HelperResult(async(__razor_template_writer) => {...}

So this should work:

@model My.PageModel

@My.CustomControl(new CustomControlModel
    {
        AreaTitle = "Details",
        RenderSideContent =
            @<div>
                @using (My.CustomWrapper("General"))
                {
                    My.BasicControl(Model.Controls[0])
                }
            </div>
    })

http://haacked.com/archive/2011/02/27/templated-razor-delegates.aspx/

See also: Are lambda expressions supported by Razor?

Upvotes: 2

Chris Pratt
Chris Pratt

Reputation: 239440

Yes and no. No, you can't just feed it custom Razor like that, because in that context, you're dealing with straight C# and something like <div> is not valid C#. However, you can build an IHtmlString or MvcHtmlString object in the lambda and then return that.

However, you're going to need to create versions of your custom controls that return HTML versus render HTML. Basically, think of Html.Partial vs Html.RenderPartial. The former actually writes to the response while the latter merely returns an MvcHtmlString that can be rendered to the page at will.

Upvotes: 3

Related Questions