Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pass HTML content to a Partial View in MVC-Razor like a "for" block

I'm using Chromatron theme for an admin panel in my application. There is a sidebar gadget that has HTML content and with a little CSS trick it can be shown completely different.

<section class="sidebar nested">
    <h2>Nested Section</h2>
    <p>Lorem ipsum dolor sit amet, conse ctetur adipiscing elit. Maec enas id augue ac metu aliquam.</p>
    <p>Sed pharetra placerat est suscipit sagittis. Phasellus <a href="#">aliquam</a> males uada blandit. Donec adipiscing sem erat.</p>
</section>

I want to have a Partial View that is used like this:

@Html.Partial("Path/To/Partial/View"){
    <h2>Nested Section</h2>
    <p>Lorem ipsum dolor sit amet, conse ctetur adipiscing elit. Maec enas id augue ac metu aliquam.</p>
    <p>Sed pharetra placerat est suscipit sagittis. Phasellus <a href="#">aliquam</a> males uada blandit. Donec adipiscing sem erat.</p>
}

TBH, I want to have functionality like I have in a @for(...){ } block. Is this possible in Razor?

like image 354
Achilles Avatar asked Mar 06 '12 17:03

Achilles


1 Answers

I was having the same dilemma. Try creating a viewmodel type with a Func property and then pass the html as delegate.

public class ContainerViewModel
{
    public String Caption { get; set; }
    public String Name { get; set; }
    public Int32 Width { get; set; }
    public Func<object, IHtmlString> Content { get; set; }
}

@Html.Partial("Container", new ContainerViewModel()
{
    Name = "test",
    Caption = "Test container",
    Content =  
    @<text>
       <h1>Hello World</h1>
    </text>,
    Width = 600
})

You can call it like this in your partial.

@Model.Content(null)

If you want to be fancy you can add this extension method.

public static class PartialExtensions
{
    public static IHtmlString Display<T>
        (this T model, Expression<Func<T, Func<Object, IHtmlString>>> content) 
    {
        var compiled = content.Compile();
        return compiled.Invoke(model).Invoke(null);
    }
}

Then, any time you use this pattern, you can call it like this in your partial (not fully tested).

@model ContainerViewModel
@Model.Display(m => m.Content)  // Use delegate property

Hope this works for you.

It works because the @... syntax creates a little HtmlHelper for you that consumes a Model (which you're declaring here as type object, and passing null for), and returns an IHtmlString.

BEWARE form values don't seem to post to the server if @Html.BeginForm is used in the content.

Therefore, wrap your form around the container.

like image 173
jwize Avatar answered Sep 26 '22 09:09

jwize