21

How can I write Blazor HTML code within a function inside of the @code block?

Consider the following code:

@page "/Test"

@if (option == 1)
{
    drawSomething("Something");
}
else
{
    drawSomething("Something else");
}

@code {
    int option;

    void drawSomething(string message)
    {
        <p>message</p>
    }
}

It does not produce any errors until I try to build, then it gives me the following error:

Error CS0103 The name '__builder' does not exist in the current context

On the lines in (Test.razor.g.cs):

__builder.AddContent(0, "        ");
__builder.AddMarkupContent(1, "<p>message</p>\r\n");

It seems very limited if this means Blazor HTML code can only be written in the first part of the file and not inside functions or classes.

I'm using the latest version as of writing version (3.0.100-preview9-014004) of blazor.

Note: The output in the given example is highly simplified, and I would like to know if and how I am able to write code from within a function and not solve the output above in a better way.

3 Answers 3

22

Update, you can now use:

@GreetPerson("John")

@code {
  RenderFragment GreetPerson(string name)
  {
    return @<p>Hello <em>@name</em></p>;
  }
}

Old answer:

This was announced as a feature for Preview6 but it didn't work as advertised then, and some details seem to have changed later. There is a comment from Cosmin Sontu at the bottom of that page that points the right way:

@using Microsoft.AspNetCore.Components.Rendering

@*tested with preview 9*@
@{ GreetPerson(__builder, "John"); }

@code {

    void GreetPerson(RenderTreeBuilder __builder, string name)
    {            
        <p>Hello, <em>@name!</em></p>
    }
}

The name __builder cannot be changed. That is a double underscore.

Sign up to request clarification or add additional context in comments.

6 Comments

Excellent, it looks a bit like a hack, but works exactly as I needed so I'm very grateful that its possible, thank you very much for the help!
This is not suppose to be a viable solution in Razor Components, This is worse than a hack, even if currently works. Next preview, it won't. I'll write down a sort of an answer...
@Issac Don't you think there will be a simple change in syntax for supporting similar functionality if this is removed though since it is mentioned as a feature in the blog post for Preview6, and seems like quite basic functionality to me tbh.
This is a great way to make reusable templates! The render methods can be made static and placed in any random .razor file and referenced anywhere. @enet, it still works in production and I disagree it's a hack. It's simply taking advantage of the known way Blazor generates .cs from .Razor files.
This is also documented as a valid method of doing this: github.com/dotnet/AspNetCore.Docs/blob/…
|
14

Version 1

In Blazor idiomatic way would be create component instead of attempting to write HTML directly in the @code.

Create drawSomething.razor

<p>@Message</p>

@code {
    [Parameter]
    public string Message {get;set;}
}

and in your Test.razor

@page "/Test"

@if (option == 1)
{
    <drawSomething Message="Something" />
}
else
{
    <drawSomething Message="Something else" />
}

@code {
    int option;
}

Here I assuming that you have something more complex, then just plain

.

Version 2

If you really want easy way, then just

@page "/Test"

@if (option == 1)
{
    <p>Something</p>
}
else
{
    <p>Something else</p>
}

@code {
    int option;
}

Version 3 Based on suggestion from Isaac

@page "/Test"

@if (option == 1)
{
    @drawSomething("Something")
}
else
{
    @drawSomething("Something else")
}

@code {
    int option;

    RenderFragment drawSomething(string message)
    {
        return @<p>@message</p>;
    }
}

2 Comments

Thanks for the extensive answer, however I do know about components, the example may be a bit too simplified as your solution is of course much better for it, but for this question I'm interested in actually writing HTML within a function and not just outputting the message if it is possible.
Your version 3 is wrong or outdated. The usage must be: @drawSomething("Something")
0
@page "/test1"


@((MarkupString)@block)

@((MarkupString)ShowHtmlBlock())


@code {
    string block = "<h3>Test1</h3>";

    private string ShowHtmlBlock()
    {
        return $@"</iframe width=""1024px"" height=""768px""><image width=""1024px"" height=""768px"" src=""https://p1.pxfuel.com/preview/653/702/399/rose-flower-flowers-red-rose.jpg"" allowfullscreen /></iframe>";
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.