Blazor in C#: WebAssembly vs Server for Interactive Web UIs

1. Blazor and WebAssembly Overview

Q: What is Blazor in C#?

Blazor is a .NET framework for building interactive web UIs using C# instead of JavaScript. It allows developers to create single-page applications (SPAs) with rich client-side or server-side interactivity. Blazor has two hosting models:

Q: What is WebAssembly in the context of Blazor?

WebAssembly (WASM) is a binary instruction format that runs in browsers, enabling high-performance execution of languages like C# in the client’s browser. Blazor WebAssembly compiles .NET code to WASM, allowing C# to run client-side without plugins, interacting with the DOM via a lightweight runtime.

Q: Why are Blazor and WebAssembly important?

Q: How does Blazor differ from C/C++ for web development?

2. Creating Interactive Web UIs with Blazor

Q: How do you create interactive web UIs with Blazor?

In Blazor, interactive UIs are built using:

Q: What are the key features of Blazor components?

Q: Can you give an example of creating an interactive web UI with Blazor WebAssembly?

Below is an example of a Blazor WebAssembly application with a simple interactive UI for managing a list of tasks.

@page "/todo"
@using System.Collections.Generic
@inject ITaskService TaskService

<h3>Todo List</h3>

<div>
    <input @bind="newTask" placeholder="Enter new task" />
    <button @onclick="AddTask">Add Task</button>
</div>

<ul>
    @foreach (var task in TaskService.GetTasks())
    {
        <li>
            @task.Title
            <button @onclick="() => RemoveTask(task.Id)">Remove</button>
        </li>
    }
</ul>

@code {
    private string newTask = string.Empty;

    private void AddTask()
    {
        if (!string.IsNullOrWhiteSpace(newTask))
        {
            TaskService.AddTask(new TaskItem { Title = newTask });
            newTask = string.Empty;
        }
    }

    private void RemoveTask(int id)
    {
        TaskService.RemoveTask(id);
    }
}

@* Model and Service (injected) *@
@code {
    public class TaskItem
    {
        public int Id { get; set; }
        public string Title { get; set; } = string.Empty;
    }

    public interface ITaskService
    {
        List<TaskItem> GetTasks();
        void AddTask(TaskItem task);
        void RemoveTask(int id);
    }
}
namespace BlazorTodo
{
    public class TaskService : ITaskService
    {
        private readonly List<TaskItem> _tasks = new();

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

        public void AddTask(TaskItem task)
        {
            task.Id = _tasks.Count + 1;
            _tasks.Add(task);
        }

        public void RemoveTask(int id)
        {
            var task = _tasks.FirstOrDefault(t => t.Id == id);
            if (task != null)
            {
                _tasks.Remove(task);
            }
        }
    }
}
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using BlazorTodo;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.Services.AddSingleton<ITaskService, TaskService>();

await builder.Build().RunAsync();

Description: A Blazor WebAssembly app with a Todo component that allows users to add and remove tasks. Features:

Usage:

3. Blazor Server vs WebAssembly + Interactivity

Q: What are the differences between Blazor Server and Blazor WebAssembly?

Blazor Server:

Blazor WebAssembly:

Q: How do you implement interactivity in Blazor?

Interactivity is achieved through:

Q: Can you give an example of a Blazor Server app with interactivity?

@page "/todo"
@using System.Collections.Generic
@inject ITaskService TaskService

<h3>Todo List (Blazor Server)</h3>

<div>
    <input @bind="newTask" @bind:event="oninput" placeholder="Enter new task" />
    <button @onclick="AddTask">Add Task</button>
</div>

<ul>
    @foreach (var task in TaskService.GetTasks())
    {
        <li>
            @task.Title
            <button @onclick="() => RemoveTask(task.Id)">Remove</button>
        </li>
    }
</ul>

<p>Current input: @newTask</p>

@code {
    private string newTask = string.Empty;

    private void AddTask()
    {
        if (!string.IsNullOrWhiteSpace(newTask))
        {
            TaskService.AddTask(new TaskItem { Title = newTask });
            newTask = string.Empty;
        }
    }

    private void RemoveTask(int id)
    {
        TaskService.RemoveTask(id);
    }
}
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using BlazorTodo;

var builder = WebApplication.CreateBuilder(args);

// Add Blazor Server services
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<ITaskService, TaskService>();

var app = builder.Build();

app.UseStaticFiles();
app.UseRouting();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

app.Run();
@page "/"
@namespace BlazorTodo
@using Microsoft.AspNetCore.Components.Web

<!DOCTYPE html>
<html>
<head>
    <title>Blazor Server Todo</title>
    <base href="/" />
    <component type="typeof(App)" render-mode="ServerPrerendered" />
</head>
<body>
    <div id="app"></div>
    <script src="_framework/blazor.server.js"></script>
</body>
</html>

Description: A Blazor Server app with a Todo component, similar to the WebAssembly example, but using server-side rendering with SignalR. Features:

Usage:

4. Common Mistakes & Best Practices

Q: Common mistakes?

General:

Blazor WebAssembly:

Blazor Server:

Q: Best practices?

General:

Blazor WebAssembly:

Blazor Server:

Interactivity:

General Practices: