blazor-creacion-componentes-code-behind

Components in Blazor: Structure, Nesting, and Code-Behind

  • 4 min

A Blazor component is a self-contained part of the interface that combines markup and presentation logic.

A complete page like Home, a form, or a button can be components. This composition allows you to divide the interface into reusable pieces that fit together.

A Blazor component is a self-contained piece of user interface (UI) that encapsulates:

  1. Rendering: Its appearance (HTML + CSS).
  2. Logic: Its behavior (C#).

Today we will learn how to create them, organize them, and most importantly, to maintain sanity in large projects: how to separate the code from the view.

Basic Structure of a Component

Technically, a component is a file with the .razor extension. The file name is important: it must start with a capital letter and follow PascalCase. For example: MyCard.razor.

Why a capital letter? Because Blazor compiles each .razor file into a C# Class. By .NET convention, classes use PascalCase. Additionally, it helps to distinguish HTML tags (<div>) from our components (<MyCard>).

Let’s create a simple component to display user information. We’ll call it UserProfile.razor.

<div class="card" style="width: 18rem;">
    <div class="card-body">
        <h5 class="card-title">@UserName</h5>
        <p class="card-text">Role: @Role</p>
        <button class="btn btn-primary" @onclick="ChangeRole">Promote</button>
    </div>
</div>

@code {
    // Component state
    private string UserName = "Luis Llamas";
    private string Role = "Editor";

    // Behavior
    private void ChangeRole()
    {
        Role = "Administrator";
    }
}
Copied!

This is the single-file structure. HTML is at the top and the @code block, with the C# logic, is below. It’s a straightforward option for small components.

How to Nest Components

The interesting part comes when we start using components inside other components. To use our UserProfile inside, for example, Home.razor, we simply invoke it as if it were an HTML tag.

@page "/"

<PageTitle>Home</PageTitle>

<h1>Dashboard</h1>

<div class="d-flex gap-3">
    <UserProfile />
    <UserProfile />
    <UserProfile />
</div>
Copied!

During compilation, Blazor replaces each <UserProfile /> tag with an instance of the UserProfile class and renders its content. Each instance maintains its own independent state. If you click “Promote” on the first user, the other two are not affected.

Namespaces and _Imports.razor

Sometimes, when trying to use a component, the editor doesn’t recognize it (it doesn’t turn green/violet). This is usually because the component is in a different folder and we haven’t imported the namespace.

If UserProfile.razor is in the Components/UI folder, its full namespace is MyProject.Components.UI.

To avoid repeating @using MyProject.Components.UI in every file, you can add it to _Imports.razor. Its directives apply to components in the same folder and its subfolders; if it’s in the appropriate root, it will cover the entire application.

Separating Code with Code-Behind

The single-file approach (@code) is fine for demos and simple visual components. But what happens when we have a complex component with 200 lines of logic, dependency injection, and database calls?

The .razor file becomes unmanageable.

To avoid this, we can use code-behind, which physically separates the view (.razor) from the logic (.cs). The approach will feel familiar if you come from WPF or Web Forms.

How to Implement Code-Behind

The key is the use of Partial Classes (partial).

Blazor compiles the .razor file into a C# class. If we create another partial class with the same name and namespace, the compiler merges both parts.

Step 1: The View File (UserProfile.razor) We remove the @code block (or leave only the minimum necessary for purely visual aspects).

<div class="card">
    <h3>@UserName</h3>
    <button @onclick="UpdateUser">Update</button>
</div>
Copied!

Step 2: The Logic File (UserProfile.razor.cs) We create a conventional C# class. By convention, we name it the same as the component, adding .cs.

In Visual Studio, if you name the file UserProfile.razor.cs, it will automatically nest it under the .razor file in the solution explorer, keeping everything organized.

// UserProfile.razor.cs
using Microsoft.AspNetCore.Components;

namespace MyProject.Components.Pages
{
    // IMPORTANT: Must be public and partial
    public partial class UserProfile
    {
        // Both parts form the same class, so it can be private
        private string UserName { get; set; } = "Luis";

        private void UpdateUser()
        {
            UserName = "Updated User";
        }
    }
}
Copied!

Which Approach Should We Use?

We like clean code, but we are also pragmatic. There is no single recipe, but here is our recommendation:

ApproachWhen to Use ItAdvantages
@code BlockSmall, primarily visual components (buttons, badges, or simple cards).• Fewer files to manage.

• Immediate visual context.

• Rapid development.
Code-behindPages (@page), complex forms, or significant presentation logic.• Smaller, more readable files.

• Separation of concerns.

• Better version control (Git) by separating design and logic changes.