Blazor Basics & Components in C# – Ultimate Guide

Blazor Basics & Components in C# – Ultimate Guide

Blazor Basics & Components in C# – The Ultimate Guide

1. Introduction to Blazor

1.1 What is Blazor?

Blazor is a revolutionary web framework from Microsoft that lets you build rich, interactive web apps using C# instead of JavaScript. By compiling C# into WebAssembly or running it on the server, Blazor enables full-stack development with a single language. This means you can share libraries and models between client and server—simplifying your codebase and developer experience.

Blazor offers a component‑based architecture, routing, dependency injection, forms, and more. And because it leverages modern browser standards, your users enjoy a fast, responsive experience without relying on traditional JavaScript frameworks.

1.2 Blazor Hosting Models: Server vs WebAssembly

There are two main ways to host Blazor apps:

  • Blazor Server: Your C# component logic runs on the server. The UI updates are sent via SignalR. This model uses minimal client resources and works well for intranet apps.
  • Blazor WebAssembly: The entire app, including the .NET runtime, runs in the browser as WebAssembly. Offers offline support and full client‑side rendering.

Select the model that best suits your needs and constraints—though most concepts, including components, apply to both.

1.3 Why Use Blazor for Modern Web Apps

Blazor brings many benefits:

  • Full .NET ecosystem: Use C#, EF Core, Identity, and your favorite libraries.
  • Single-language code: No more back-and-forth between C# and JavaScript.
  • Reusability: Components can be shared across pages and other apps.
  • Strong typing: Enjoy compile-time safety and IntelliSense.

Whether you're a .NET web developer or a full-stack engineer, Blazor lets you write cleaner, more maintainable code and ship faster by avoiding language context switching.

2. Setting Up a Blazor Project

2.1 Prerequisites and Tooling

To get started with Blazor, you need:

  • .NET 7 (or latest SDK)
  • Visual Studio 2022/2023, Visual Studio Code, or JetBrains Rider
  • Basic familiarity with C#, ASP.NET, and HTML

Install .NET SDK:

dotnet --version

Look for version 7.0+ to ensure full support for the latest Blazor features.

2.2 Creating Your First Blazor App

Create a new Blazor WebAssembly app using the CLI:

dotnet new blazorwasm -n BlazorBasicsApp

Or create a Blazor Server app:

dotnet new blazorserver -n BlazorBasicsApp

Open the generated project folder in your IDE and run:

dotnet run

Navigate to https://localhost:5001 and you’ll see the default Blazor template in action.

2.3 Project Structure and Folders Overview

Blazor projects follow a logical structure:

  • Pages/: Razor components representing pages (with routing)
  • Shared/: Reusable components
  • wwwroot/: Static assets (CSS, images)
  • Program.cs: Startup logic and DI registration

Understanding this structure helps you maintain organized code as your app grows.

3. Blazor Components Fundamentals

3.1 What Are Components?

Components are the basic building blocks in Blazor. Each component encapsulates UI (HTML), behavior (C#), and rendering logic. You define them using Razor syntax in .razor files.

Think of them as reusable functions—every page you see is just a combination of components.

3.2 Anatomy of a Razor Component

A Razor component has three main parts:

  • Markup: HTML UI
  • @code block: C# logic and properties
  • Parameters: External input via [Parameter] attributes

Example:

@* HelloWorld.razor *@

Hello, @Name!

@code { [Parameter] public string Name { get; set; } = "World"; }

3.3 First Hello World Component

Add a new file Pages/Hello.razor with:

@page "/hello"

Hello, @Name!

@code { private string Name { get; set; } = "Blazor"; }

Navigate to /hello and type in the textbox to see real-time updates—no JavaScript needed!

4. Understanding Component Parameters

4.1 Passing Data into Components

Blazor components can accept data from their parent components using parameters. You declare parameters in the @code block using the [Parameter] attribute.


@* Greeting.razor *@

Hello, @Name!

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

You can now use this component and pass in a value like this:


<Greeting Name="Alice" />

4.2 Optional Parameters and Defaults

You can assign default values to parameters to make them optional:


[Parameter]
public string Color { get; set; } = "blue";

If the parent doesn’t supply a value, Blazor will use the default.

4.3 Two-Way Binding with Parameters

You can use two-way binding for parameters by adding the [Parameter] and [EditorRequired] attribute combination (or manually raise events):


[Parameter]
public string Title { get; set; }

[Parameter]
public EventCallback<string> TitleChanged { get; set; }

private async Task UpdateTitle(string value) {
    Title = value;
    await TitleChanged.InvokeAsync(value);
}
---

5. Event Handling in Blazor

5.1 Handling Button Clicks

Handling events in Blazor is as easy as adding a method and calling it via @onclick:


<button @onclick="ShowMessage">Click Me</button>

@code {
    private void ShowMessage() {
        Console.WriteLine("Button clicked!");
    }
}

This is similar to JavaScript but written in C# and compiled to WebAssembly or executed on the server.

5.2 Passing Parameters to Events

You can pass arguments to event handlers using lambda expressions:


<button @onclick="() => ShowAlert(5)">Show 5</button>

@code {
    private void ShowAlert(int value) {
        Console.WriteLine($"You clicked: {value}");
    }
}

5.3 Preventing Default and StopPropagation

Use @onclick:preventDefault and @onclick:stopPropagation for fine-grained control:


<a href="https://example.com" @onclick:preventDefault @onclick="OpenModal">Open Modal</a>

This allows you to control behavior just like JavaScript, but within your C# component.

---

6. Data Binding in Blazor

6.1 One-Way Binding

Use curly braces @{ } or simply @variable to bind a variable’s value into the DOM:


<p>Hello, @username</p>

@code {
    string username = "Blazor Dev";
}

6.2 Two-Way Binding with @bind

Use @bind to bind an input’s value to a field or property. Changes in the UI update the variable, and vice versa:


<input @bind="username" />
<p>You typed: @username</p>

@code {
    private string username = "";
}

6.3 @bind-Value:event and Custom Events

You can specify the binding event (e.g., oninput) like this:


<input @bind-value="username" @bind-value:event="oninput" />

This enables instant feedback on every keystroke.

---

7. Component Lifecycle

7.1 Lifecycle Overview

Blazor components go through a series of lifecycle stages. You can hook into these using lifecycle methods like:

  • OnInitialized() – Called after parameters are set (sync)
  • OnInitializedAsync() – Async version
  • OnParametersSet() – When parameter values change
  • OnAfterRender() – After rendering is done

7.2 Using OnInitializedAsync


@code {
    protected override async Task OnInitializedAsync() {
        products = await ProductService.GetAllAsync();
    }

    private List<Product> products;
}

This is perfect for making API calls during component initialization.

7.3 Dispose and Cleanup

Implement IDisposable to clean up resources like timers or subscriptions:


@implements IDisposable

@code {
    private Timer _timer;

    protected override void OnInitialized() {
        _timer = new Timer(UpdateTime, null, 0, 1000);
    }

    public void Dispose() {
        _timer?.Dispose();
    }

    private void UpdateTime(object state) {
        // Refresh UI or perform action
    }
}

This ensures your components don’t cause memory leaks or performance issues—key for Google AdSense compliance and SEO reliability.

8. Routing in Blazor

8.1 Defining Routes with @page

Routing in Blazor is simple. You define routes directly in Razor components using the @page directive:


@page "/about"
<h2>About Us</h2>

This component will now respond to /about in the browser.

8.2 Route Parameters

You can accept values from the URL using parameters:


@page "/user/{id:int}"

<h3>User ID: @Id</h3>

@code {
    [Parameter]
    public int Id { get; set; }
}

You can also support optional parameters and constraints like {name:alpha}.

8.3 NavigationManager and Navigation

Inject NavigationManager to programmatically change routes:


@inject NavigationManager Nav

<button @onclick="GoToHome">Go Home</button>

@code {
    void GoToHome() => Nav.NavigateTo("/");
}
---

9. Forms and Validation

9.1 Using EditForm

EditForm is a special Blazor component that binds to a model and supports validation:


<EditForm Model="@formModel" OnValidSubmit="HandleSubmit">
    <InputText @bind-Value="formModel.Name" />
    <ValidationMessage For="() => formModel.Name" />
    <button type="submit">Submit</button>
</EditForm>

@code {
    private FormModel formModel = new();

    private void HandleSubmit() {
        Console.WriteLine($"Submitted: {formModel.Name}");
    }

    public class FormModel {
        [Required] public string Name { get; set; }
    }
}

9.2 Custom Validation

Implement IValidatableObject for model-level rules:


public class FormModel : IValidatableObject {
    public string Name { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext context) {
        if (Name?.ToLower() == "admin")
            yield return new ValidationResult("Admin is not allowed.", new[] { nameof(Name) });
    }
}

9.3 Input Components

Use Blazor’s built-in input controls:

  • InputText
  • InputTextArea
  • InputCheckbox
  • InputSelect

These support full validation and binding out-of-the-box.

---

10. Dependency Injection (DI)

10.1 Injecting Services

Blazor supports DI via @inject or constructor injection:


@inject IWeatherService WeatherService

<p>@WeatherService.GetForecast()</p>

10.2 Registering Services

Register services in Program.cs:


builder.Services.AddScoped<IWeatherService, WeatherService>();

10.3 Scoped, Singleton, Transient

Blazor supports these lifetimes:

  • Scoped: One instance per user session
  • Singleton: One instance for the app’s lifetime
  • Transient: New instance each time

Use scoped for most web apps to match user sessions cleanly.

---

11. JavaScript Interop

11.1 Calling JS from Blazor

Sometimes, C# can't do everything alone. Call JS like this:


@inject IJSRuntime JS

<button @onclick="CallJS">Alert</button>

@code {
    async Task CallJS() {
        await JS.InvokeVoidAsync("alert", "Hello from Blazor!");
    }
}

11.2 Calling C# from JS

Define a C# method as static and JS invokable:


[JSInvokable]
public static void FromJS(string message) {
    Console.WriteLine($"JS says: {message}");
}

Call from JS:


DotNet.invokeMethodAsync("MyApp", "FromJS", "Hi!");

11.3 When to Use JSInterop

Use JSInterop for things like:

  • Working with browser APIs
  • Calling third-party JS libraries
  • DOM manipulation not possible in C#
---

12. Component Communication

12.1 Parent to Child

Use parameters to pass data:


<ChildComponent Message="Hello from parent!" />

@code {
    public string Message { get; set; } = "Hello from parent!";
}

12.2 Child to Parent

Use EventCallback to notify parent:


<ChildComponent OnClick="ParentHandler" />

@code {
    void ParentHandler() => Console.WriteLine("Child clicked");
}

12.3 Cascading Parameters

Pass data to deeply nested components using CascadingValue:


<CascadingValue Value="Theme">
    <Child />
</CascadingValue>

@code {
    string Theme = "dark";
}

Then inject with:


[CascadingParameter]
public string Theme { get; set; }

13. Layouts and Reusability

13.1 Creating Layouts

Layouts let you define a common structure for pages. You define them using LayoutComponentBase or Razor syntax:


@inherits LayoutComponentBase

<div class="main-layout">
    <header>Blazor App Header</header>
    <div class="content">
        @Body
    </div>
</div>

13.2 Applying Layouts to Pages

Use the @layout directive at the top of your page to apply a layout:


@layout MainLayout

Or set it globally in App.razor:


<Router AppAssembly="@typeof(App).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
</Router>

13.3 Reusable Components and Templates

You can create your own reusable input, layout, or control components. Use generics for templates:


@typeparam TItem

<div>@Item</div>

@code {
    [Parameter]
    public TItem Item { get; set; }
}
---

14. Hosting & Deployment

14.1 Publishing Blazor WASM


dotnet publish -c Release -o ./publish

This creates static files you can host on:

  • GitHub Pages
  • Azure Static Web Apps
  • Firebase Hosting
  • Cloudflare Pages

14.2 Hosting Blazor Server

Blazor Server runs on ASP.NET Core with SignalR, so you can deploy to:

  • Azure App Service
  • Docker containers
  • Self-hosted Linux/Windows servers

14.3 Deploying to GitHub Pages

For Blazor WASM:


dotnet publish -c Release
# Copy wwwroot to gh-pages branch and push
---

15. Best Practices

  • Use component libraries: Like MudBlazor, Radzen, or Telerik for rich UI
  • Keep components small: One feature or purpose per component
  • Use partial classes: Keep UI and logic separated for maintainability
  • Avoid tight coupling: Prefer interfaces and services for DI
  • Organize with folders: Group related components for clarity
---

16. Frequently Asked Questions (FAQs)

1. Is Blazor production ready?

Absolutely. Blazor WASM and Server are stable and used in real-world enterprise apps.

2. Can I use JavaScript in Blazor?

Yes. Blazor supports full JavaScript interop for calling JS from C# and vice versa.

3. Does Blazor work with .NET MAUI?

Yes. Blazor Hybrid lets you build native apps using Razor components inside .NET MAUI.

4. What's the difference between Blazor Server and WASM?

Blazor Server executes on the server with SignalR UI sync. WASM runs entirely in the browser.

5. Can Blazor apps be indexed by search engines?

Blazor Server apps are fully indexable. Blazor WASM needs pre-rendering for SEO bots.

---

17. Conclusion

Blazor empowers you to build fast, modern, and interactive web apps using just C#. By mastering components, routing, forms, data binding, DI, and interop, you can create rich UIs with ease and elegance—without ever writing a single line of JavaScript if you don’t want to.

Whether you choose Blazor Server for enterprise dashboards or Blazor WebAssembly for client-side apps, the possibilities are endless. This guide has covered everything you need to start building powerful, production-ready Blazor applications with confidence.

---

Please don’t forget to leave a review.

Post a Comment

Post a Comment (0)

Previous Post Next Post

ads

ads

Update cookies preferences