Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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>
like image 592
haferje Avatar asked Jul 30 '15 16:07

haferje


2 Answers

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.

like image 137
Chris Pratt Avatar answered Oct 22 '22 22:10

Chris Pratt


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?

like image 31
James Wilkins Avatar answered Oct 22 '22 20:10

James Wilkins