ChrisA
ChrisA

Reputation: 4193

Blazor pages: how to use BuildRenderTree to add dynamic content

Background: We run dozens of sites for clients; all use an identical code base (ASP.NET WebForms) but completely different designs. Page structure is generated programmatically from SQL Server meta-data, using controls such as Panel, which are added to the ASP.NET page's Controls collection, and become DIVs in the rendered HTML.

Objective: We want to migrate eventually to ASP.NET CORE. However, there seems to be no equivalent to the page's controls collection. The closest thing I can find is the RenderTreeBuilder to add a Blazor component.

Question: Is it possible use BuildRenderTree to add a component which contains our home-baked HTML (for instance, to contain everything between <body> and </body>?

I've read articles such as:

https://chrissainty.com/building-components-via-rendertreebuilder/

https://learn.microsoft.com/en-us/aspnet/core/blazor/components?view=aspnetcore-3.1#manual-rendertreebuilder-logic

... and experimented with adding HTML elements, but it's extremely cumbersome, and I'd like to programmatically generate the HTML for pretty much the whole page, and add it as one RenderFragment (is that the right term?).

Is this possible? Is there an alternative?

Edit:


@Henk's answer, using the MarkupString struct, and mine, using RenderTreeBuilder.AddMarkupContent seem similar in terms of effort and plumbing required.

Are there any pros and cons of the two approaches I should consider?

Upvotes: 3

Views: 5314

Answers (3)

Greg Gum
Greg Gum

Reputation: 38149

You can also render a string as HTML like this:

@page "/test";
<h1>My Page</h1>

@((MarkupString)content)


@code{
    //Get content from Database
    string content = "<p>Hello</p>";
}

See section "Raw HTML" here

Upvotes: 1

ChrisA
ChrisA

Reputation: 4193

I hadn't come across the MarkupString struct, so @Henk's answer is really helpful. I've now also come across the RenderTreeBuilder.AddMarkupContent method, so I'll offer this as an alternate answer:

My markup:

@page "/"
<PageBuilder></PageBuilder>

PageBuilder is a class that inherits from ComponentBase:

public class PageBuilder : ComponentBase
{
    protected override void BuildRenderTree(RenderTreeBuilder b)
    {
        base.BuildRenderTree(b);
        b.OpenElement(0, "div");
        b.AddMarkupContent(1, TheContent());
        b.CloseElement();
    }
    public string TheContent()
    {
        return "<div>This is the generated content</div>";
    }

I'll edit my original question a little, as I'd like to know whether there's anything to choose between this approach and @Henk's.

Upvotes: 3

Henk Holterman
Henk Holterman

Reputation: 273854

If you just want HTML (plain, dead) then you don't need a rendertree:

<h1>My Page</h1>
@MyHtmlComposer()

@code{
    private MarkupString MyHtmlComposer()
    {
        string html = "<p>Hello</p>";
        return new MarkupString(html);
    }
}

Upvotes: 2

Related Questions