Blazor (Server & WebAssembly)

15 questions found

What is Blazor, and what are the two primary hosting models (Server and WebAssembly)?

Beginner
Blazor is a framework for building interactive web UIs using C# and .NET instead of JavaScript. Blazor Server runs application logic on the server, with the browser maintaining a persistent SignalR connection that relays UI events up and DOM updates down as lightweight diffs. Blazor WebAssembly (WASM) instead downloads the .NET runtime and app assemblies to the browser, executing entirely client-side, with no ongoing server connection required for UI logic.
// Program.cs for Blazor Server
builder.Services.AddRazorComponents().AddInteractiveServerComponents();

// Program.cs for Blazor WebAssembly (client project)
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
Real-world example An internal admin tool with users on a reliable corporate network chooses Blazor Server for its fast initial load and simpler debugging, while a public-facing app needing offline capability chooses Blazor WebAssembly instead.

Common follow-ups: What is Blazor United / Auto render mode and how does it combine both models?;What are the latency implications of Blazor Server's SignalR dependency?

SignalR & Real-Time Communication;ASP.NET Core Middleware & Request Pipeline

How does Blazor Server's reliance on a persistent SignalR connection affect its behavior under network interruptions?

Intermediate
Since all UI state and event handling logic actually executes on the server, a Blazor Server app's interactivity entirely depends on its SignalR connection -- if the connection drops (network blip, server restart, idle timeout), the UI becomes unresponsive until reconnection succeeds, at which point Blazor attempts to resync client-side DOM state with the server, though any unsaved in-progress state can be lost if reconnection fails entirely, showing a default 'Attempting to reconnect' overlay.
// Customizing reconnection UI behavior in Blazor Server
<div id="components-reconnect-modal">
    Connection lost. Attempting to reconnect...
</div>

// Configuring reconnection retry intervals
builder.Services.Configure<CircuitOptions>(options => {
    options.DisconnectedCircuitMaxRetained = 100;
});
Real-world example A Blazor Server app running on an unreliable mobile connection frequently shows the reconnection overlay, prompting the team to consider Blazor WebAssembly or Blazor United's auto mode for better resilience to network drops.

Common follow-ups: What is a 'circuit' in Blazor Server terminology?;How long does the server retain disconnected circuit state before discarding it?

SignalR & Real-Time Communication;Diagnostics & Performance

What is a 'circuit' in Blazor Server, and how does server-side state management work across it?

Advanced
A circuit represents the server-side connection and state for one Blazor Server user session -- it holds the component tree, its current render state, and any DHTML event handlers, kept alive on the server for the browser tab's lifetime via the SignalR connection. Because state lives server-side per circuit, Blazor Server apps consume server memory proportional to concurrently connected users, unlike Blazor WebAssembly where all state lives in the client's browser memory instead.
// Server memory scales with concurrent circuits:
// 1000 concurrent Blazor Server users = 1000 active circuits
// each holding component state, consuming server RAM

builder.Services.Configure<CircuitOptions>(options => {
    options.DisconnectedCircuitRetentionPeriod = TimeSpan.FromMinutes(3);
});
Real-world example A capacity-planning exercise for a Blazor Server application estimates server memory needs based on expected concurrent circuit count, a scaling consideration that simply doesn't apply the same way to a Blazor WebAssembly deployment.

Common follow-ups: How does this scaling concern compare to Blazor WebAssembly's client-side memory model?;What happens to server resources when a circuit is abandoned?

Diagnostics & Performance;Caching (In-Memory Distributed & Redis)

How do Razor components (.razor files) combine markup and C# code, and what is the @code block?

Intermediate
A .razor component file mixes HTML-like markup with embedded C# expressions (using @ syntax) for data binding and control flow, plus an @code block containing the component's C# class members (properties, fields, methods, lifecycle overrides) -- Blazor compiles this into a regular C# class at build time, with the markup becoming a BuildRenderTree method.
<h3>@Title</h3>
<button @onclick="IncrementCount">Count: @count</button>

@code {
    [Parameter] public string Title { get; set; } = "Counter";
    private int count = 0;
    private void IncrementCount() => count++;
}
Real-world example A reusable Counter.razor component exposes a Title parameter so it can be embedded multiple times on a page with different labels, each maintaining its own independent count state.

Common follow-ups: How do [Parameter] properties enable passing data from parent to child components?;What does the generated BuildRenderTree method actually do?

Dependency Injection;Web Components & Custom Elements

How does two-way data binding work with @bind in Blazor, and how can you customize the triggering event?

Advanced
@bind creates a two-way binding between a component field/property and an HTML element's value, automatically wiring up both the value attribute and an appropriate change event (oninput or onchange depending on element type) to keep them in sync. You can customize the triggering event with @bind:event (e.g., 'oninput' for immediate updates as the user types) and apply formatting/parsing with @bind:format for types like DateTime.
<input @bind="searchTerm" @bind:event="oninput" />
<p>Searching for: @searchTerm</p>

@code {
    private string searchTerm = "";
}

<!-- Default @bind uses onchange (fires on blur); oninput fires on every keystroke -->
Real-world example A live search-as-you-type feature explicitly sets @bind:event="oninput" instead of relying on the default onchange behavior, ensuring search results update on every keystroke rather than only after the input loses focus.

Common follow-ups: How does @bind-Value work for custom component parameters?;What's the performance cost of oninput binding on every keystroke in Blazor Server?

ASP.NET Core Middleware & Request Pipeline;Diagnostics & Performance

What are Blazor component lifecycle methods, and what is the purpose of OnInitializedAsync versus OnParametersSetAsync?

Intermediate
OnInitializedAsync runs once when the component is first created, ideal for initial data loading. OnParametersSetAsync runs every time the component receives new parameter values from its parent (including the very first time, after OnInitializedAsync), useful for reacting to changing inputs -- e.g., a component displaying details for an Id parameter should re-fetch data in OnParametersSetAsync if the Id can change without the component being recreated.
@code {
    [Parameter] public int UserId { get; set; }
    private User? user;

    protected override async Task OnParametersSetAsync() {
        user = await UserService.GetUserAsync(UserId);  // re-runs if UserId changes
    }
}
Real-world example A user-detail component correctly refetches data whenever its parent navigates to a different user's Id by implementing OnParametersSetAsync instead of OnInitializedAsync, which would only load data once and never update on subsequent Id changes.

Common follow-ups: What's the full order of Blazor's lifecycle methods (SetParametersAsync, OnInitialized, OnAfterRender)?;When would you use OnAfterRenderAsync instead?

Dependency Injection;Blazor (Server & WebAssembly)

How does Blazor's render mode system (Static, Interactive Server, Interactive WebAssembly, Interactive Auto) work in .NET 8+'s unified Blazor model?

Advanced
Since .NET 8, a single Blazor project can mix render modes per component: Static Server-Side Rendering (no interactivity, fastest initial load), Interactive Server (SignalR-based, like classic Blazor Server), Interactive WebAssembly (client-side execution, like classic Blazor WASM), and Interactive Auto (starts with Server for instant interactivity, then switches to WebAssembly once the client-side runtime finishes downloading in the background) -- letting you choose the optimal trade-off per-component rather than committing the entire app to one model.
@page "/counter"
@rendermode InteractiveAuto

<button @onclick="IncrementCount">Count: @count</button>

@code {
    private int count = 0;
    private void IncrementCount() => count++;
}
Real-world example A content-heavy marketing site uses Static SSR for most pages (fastest possible load, good SEO) but applies InteractiveServer render mode only to a specific contact form component that needs client-side validation feedback.

Common follow-ups: How does Interactive Auto decide when to switch from Server to WebAssembly?;What are the constraints on mixing render modes within one component tree?

ASP.NET Core Middleware & Request Pipeline;Diagnostics & Performance

How do you call JavaScript from C# code in Blazor (JS interop), and when is it necessary?

Intermediate
IJSRuntime.InvokeAsync<T>("functionName", args) calls a JavaScript function from C# and awaits its result, necessary for accessing browser APIs Blazor doesn't wrap natively (like localStorage, certain DOM APIs, or existing third-party JS libraries like chart rendering libraries) that don't have a direct Blazor equivalent.
@inject IJSRuntime JS

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

@code {
    private async Task ShowAlert() {
        await JS.InvokeVoidAsync("alert", "Hello from Blazor!");
    }
}
Real-world example A Blazor dashboard integrates an existing JavaScript charting library (like Chart.js) via JS interop, since no mature native Blazor charting component existed that matched the team's exact visualization requirements.

Common follow-ups: How does JS interop performance differ between Blazor Server (network round-trip) and WebAssembly (in-process)?;How do you call C# methods FROM JavaScript (the reverse direction)?

Web Components & Custom Elements;ASP.NET Core Middleware & Request Pipeline

What is the performance implication of JS interop calls in Blazor Server versus Blazor WebAssembly?

Advanced
In Blazor Server, every JS interop call is a network round-trip over the SignalR connection (browser to server and back), adding real latency proportional to network conditions -- making frequent, chatty JS interop calls a potential performance bottleneck. In Blazor WebAssembly, JS interop happens entirely in-process within the browser (no network hop), making it dramatically faster, though still not free due to the WASM-to-JS marshaling overhead.
// Blazor Server: this call incurs a real network round-trip
await JS.InvokeVoidAsync("updateChart", chartData);  // browser <-> server over SignalR

// Blazor WebAssembly: same call, purely in-browser, no network latency
await JS.InvokeVoidAsync("updateChart", chartData);  // in-process WASM <-> JS marshal
Real-world example A Blazor Server app calling JS interop on every mouse-move event for a drawing feature experiences noticeable lag due to network round-trip overhead on each call, leading the team to switch that specific interactive component to WebAssembly render mode.

Common follow-ups: How would you batch multiple JS interop calls to reduce round-trips?;What is JSImport/JSExport and how does it improve WebAssembly interop performance?

Diagnostics & Performance;SignalR & Real-Time Communication

How does dependency injection work in Blazor components, and what's the difference between @inject and constructor injection?

Intermediate
Blazor components support DI via the @inject directive (syntactic sugar generating a property with [Inject] attribute) or explicit [Inject] properties, resolving services from the DI container when the component is instantiated -- components generally can't use constructor injection directly since the framework controls their instantiation, unlike typical .NET classes.
@inject IUserService UserService
@inject NavigationManager Navigation

@code {
    protected override async Task OnInitializedAsync() {
        var user = await UserService.GetCurrentUserAsync();
        if (user == null) Navigation.NavigateTo("/login");
    }
}
Real-world example A shared authentication check pattern injects both a UserService and NavigationManager into every protected page component, redirecting unauthenticated users to a login page directly from OnInitializedAsync.

Common follow-ups: Why can't Blazor components use constructor injection like typical services?;How does service lifetime (scoped vs singleton) differ in meaning between Blazor Server and WebAssembly?

Dependency Injection;Authentication & Authorization (Identity JWT OAuth)

Showing 1–10 of 15