DEV Community

Cover image for Blazor WebAssembly for Full-Stack Development: A Comprehensive Guide
Paulo Torres
Paulo Torres

Posted on

Blazor WebAssembly for Full-Stack Development: A Comprehensive Guide

Blazor WebAssembly has revolutionized web development by allowing developers to build full-stack web applications using .NET and C#. Unlike traditional frameworks that require JavaScript for client-side logic, Blazor enables developers to write client-side code in C# and run it directly in the browser. This article delves into advanced techniques for leveraging Blazor WebAssembly in full-stack development, complete with real-world examples.

What is Blazor WebAssembly?

Blazor WebAssembly is a framework in the .NET ecosystem that allows developers to build interactive web applications using C# instead of JavaScript. It compiles C# code into WebAssembly, a low-level assembly-like language that runs in the browser. This enables .NET developers to build full-stack applications using a single programming language, simplifying the development process and fostering a more cohesive codebase.

Key Features of Blazor WebAssembly:

  • Single-Language Development: Use C# for both client and server-side code.
  • WebAssembly: Run compiled .NET code directly in the browser for near-native performance.
  • Reusable Components: Build UI components that can be reused across different parts of the application.
  • Seamless Integration: Integrate with existing .NET libraries and APIs, including ASP.NET Core, Entity Framework Core, and more.

Setting Up a Blazor WebAssembly Project

Step 1: Create a New Blazor WebAssembly Project

Using the .NET CLI or Visual Studio, create a new Blazor WebAssembly project:

dotnet new blazorwasm -o MyBlazorApp
cd MyBlazorApp
Enter fullscreen mode Exit fullscreen mode

Step 2: Understand the Project Structure

Blazor WebAssembly projects have a distinct structure:

  • wwwroot: Contains static assets such as CSS, JavaScript, and images.
  • Pages: Holds Razor components, which are .razor files defining the UI and logic for individual pages.
  • Shared: Contains shared components that can be used across multiple pages.
  • Program.cs: The entry point for the application, where services are configured and the app is bootstrapped.

Step 3: Build a Real-World Example: Task Management Application

Creating the Task Model

First, create a model class to represent tasks:

public class TaskItem
{
    public int Id { get; set; }
    public string Title { get; set; }
    public bool IsCompleted { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Creating the Task Service

Next, create a service to manage tasks. This service will handle CRUD operations.

public class TaskService
{
    private readonly List<TaskItem> _tasks = new List<TaskItem>();

    public TaskService()
    {
        // Sample data
        _tasks.Add(new TaskItem { Id = 1, Title = "Learn Blazor", IsCompleted = false });
        _tasks.Add(new TaskItem { Id = 2, Title = "Build a Blazor App", IsCompleted = false });
    }

    public IEnumerable<TaskItem> GetTasks() => _tasks;

    public TaskItem GetTaskById(int id) => _tasks.FirstOrDefault(t => t.Id == id);

    public void AddTask(TaskItem task) => _tasks.Add(task);

    public void UpdateTask(TaskItem task)
    {
        var existingTask = GetTaskById(task.Id);
        if (existingTask != null)
        {
            existingTask.Title = task.Title;
            existingTask.IsCompleted = task.IsCompleted;
        }
    }

    public void DeleteTask(int id) => _tasks.RemoveAll(t => t.Id == id);
}
Enter fullscreen mode Exit fullscreen mode

Registering the Service in Program.cs

Add the TaskService to the dependency injection container:

builder.Services.AddSingleton<TaskService>();
Enter fullscreen mode Exit fullscreen mode

Creating the Task List Component

Create a new Razor component to display the list of tasks:

@page "/tasks"
@inject TaskService TaskService

<h3>Task List</h3>

<ul>
    @foreach (var task in TaskService.GetTasks())
    {
        <li>
            <input type="checkbox" @bind="task.IsCompleted" />
            @task.Title
        </li>
    }
</ul>
Enter fullscreen mode Exit fullscreen mode

Adding Task Management Features

Add features to create, update, and delete tasks:

@code {
    private string newTaskTitle;

    private void AddTask()
    {
        var newTask = new TaskItem
        {
            Id = TaskService.GetTasks().Max(t => t.Id) + 1,
            Title = newTaskTitle,
            IsCompleted = false
        };
        TaskService.AddTask(newTask);
        newTaskTitle = string.Empty;
    }

    private void DeleteTask(TaskItem task)
    {
        TaskService.DeleteTask(task.Id);
    }
}
Enter fullscreen mode Exit fullscreen mode

Advanced Blazor WebAssembly Techniques

1. Implementing Authentication and Authorization

Blazor WebAssembly supports various authentication methods, including ASP.NET Core Identity and third-party providers like Google or Microsoft. Implementing authentication involves configuring services in Program.cs, creating custom authentication states, and protecting routes with [Authorize].

Example: Configuring Authentication with Azure AD B2C

builder.Services.AddMsalAuthentication(options =>
{
    builder.Configuration.Bind("AzureAdB2C", options.ProviderOptions.Authentication);
});
Enter fullscreen mode Exit fullscreen mode

2. Server-Side Blazor with SignalR

While Blazor WebAssembly runs entirely in the browser, Blazor Server relies on SignalR to manage client-server communication. This hybrid approach allows for real-time updates and state management on the server.

Example: Real-Time Notifications

public class NotificationService
{
    public event Action OnNotificationReceived;

    public void ReceiveNotification(string message)
    {
        OnNotificationReceived?.Invoke(message);
    }
}
Enter fullscreen mode Exit fullscreen mode

3. Integrating with APIs

Blazor WebAssembly applications often need to consume external APIs. Use HttpClient to interact with RESTful services.

Example: Consuming a REST API

@inject HttpClient Http

@code {
    private IEnumerable<TaskItem> tasks;

    protected override async Task OnInitializedAsync()
    {
        tasks = await Http.GetFromJsonAsync<IEnumerable<TaskItem>>("https://api.example.com/tasks");
    }
}
Enter fullscreen mode Exit fullscreen mode

4. Optimizing Performance

Blazor WebAssembly's performance can be optimized by leveraging techniques like lazy loading, JavaScript interop, and pre-rendering.

Example: Lazy Loading Components

@page "/lazy"
@using System.Threading.Tasks

<h3>Lazy Loaded Component</h3>

@if (isLoading)
{
    <p>Loading...</p>
}
else
{
    <p>Data Loaded!</p>
}

@code {
    private bool isLoading = true;

    protected override async Task OnInitializedAsync()
    {
        await Task.Delay(2000); // Simulate a delay
        isLoading = false;
    }
}
Enter fullscreen mode Exit fullscreen mode

5. Deploying Blazor WebAssembly Applications

Blazor WebAssembly applications can be deployed to various platforms, including Azure Static Web Apps, GitHub Pages, or as a Progressive Web App (PWA).

Example: Deploying to Azure Static Web Apps

  1. Create a new Static Web App in the Azure portal.
  2. Configure GitHub Actions to automate the deployment process.
  3. Push your code to GitHub, and Azure will automatically build and deploy the application.

Conclusion

Blazor WebAssembly represents a significant shift in web development, allowing .NET developers to leverage their skills across the full stack. By enabling C# code to run directly in the browser, Blazor eliminates the need for JavaScript, providing a unified development experience. Through real-world examples, this article has demonstrated how to build a full-stack application with Blazor WebAssembly, covering everything from basic setup to advanced features like authentication, real-time updates, and performance optimization. As Blazor continues to evolve, it offers exciting possibilities for building modern, interactive web applications using .NET.

Top comments (1)

Collapse
 
jangelodev profile image
João Angelo

Hi Paulo Torres,
Top, very nice and helpful !
Thanks for sharing.