Files
Resume/.junie/plans/convert-to-blazor-server.md
T

8.8 KiB

sessionId
sessionId
session-260909-133404-1um1

Requirements

Overview & Goals

Convert the Web project from a standalone Blazor WebAssembly application back to an ASP.NET Core Blazor Server application with interactive server components.

Scope

In Scope

  • Update Web/Web.csproj to use Microsoft.NET.Sdk.Web and remove WebAssembly client dependencies.
  • Convert Web/Program.cs from WebAssemblyHostBuilder to ASP.NET Core WebApplication.CreateBuilder with Razor Components and interactive server render modes.
  • Relocate configuration files (appsettings.json, appsettings.Development.json) from Web/wwwroot/ to the project root Web/.
  • Remove Web/wwwroot/index.html and restore Web/Components/App.razor as the HTML host root.
  • Add Web/Components/Routes.razor, Web/Components/Pages/Error.razor, and Web/Components/Layout/ReconnectModal.razor (with corresponding CSS and JS).
  • Update Web/Components/_Imports.razor with server rendering imports.

Out of Scope

  • Modifying resume content data files (Overview.cs, PersonalInfo.cs, Skills.cs, WorkExperience.cs).
  • Modifying resume UI layouts or styles in Home.razor, MainLayout.razor, or app.css.

User Stories

  • As a visitor, I want to load the resume application rendered quickly from the ASP.NET Core server with interactive server capabilities.
  • As a developer, I want the project configured as a standard ASP.NET Core Blazor Server app so that it can leverage server-side capabilities and runtime services.

Functional Requirements

  • The application must start using ASP.NET Core WebApplication hosting.
  • Navigation to / must render the resume page (Home.razor) inside MainLayout.razor.
  • Navigation to unknown routes must display the custom not-found page (NotFound.razor) via UseStatusCodePagesWithReExecute("/not-found") and the Blazor router.
  • Disconnected or reconnecting Blazor Server circuits must display the interactive reconnection modal dialog.
  • Server-side error routing must be handled via /Error rendering Error.razor.

Non-Functional Requirements

  • Maintain compatibility with .NET 10 (net10.0).
  • Ensure clean build with zero compile errors.

Technical Design

Current Implementation

The Web project is currently configured as a standalone Blazor WebAssembly client using Microsoft.NET.Sdk.BlazorWebAssembly, with Program.cs invoking WebAssemblyHostBuilder.CreateDefault(args), static hosting through Web/wwwroot/index.html, and client configuration files in Web/wwwroot/.

Key Decisions

  • Hosting Model: Use ASP.NET Core Blazor Server with interactive server components (AddInteractiveServerComponents() and .AddInteractiveServerRenderMode()).
  • Host Document: Use Web/Components/App.razor as the HTML root document containing head elements, styles, scripts, reconnect modal, and <Routes />.
  • Configuration Placement: Move appsettings.json and appsettings.Development.json to the Web/ project root, matching standard ASP.NET Core hosting conventions.

Proposed Changes

  1. Web/Web.csproj:
    • Change SDK to Microsoft.NET.Sdk.Web.
    • Remove <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" ... /> and <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" ... />.
    • Set <BlazorDisableThrowNavigationException>true</BlazorDisableThrowNavigationException>.
  2. Web/Program.cs:
    • Build server host via var builder = WebApplication.CreateBuilder(args);.
    • Register builder.Services.AddRazorComponents().AddInteractiveServerComponents();.
    • Configure HTTP request pipeline: exception handler /Error, HSTS, status code re-execute /not-found, HTTPS redirection, antiforgery, static assets mapping (MapStaticAssets()), and MapRazorComponents<App>().AddInteractiveServerRenderMode().
  3. Web/wwwroot/:
    • Remove index.html.
    • Move appsettings.json and appsettings.Development.json up to Web/.
  4. Web/Components/:
    • App.razor: HTML host markup with <Routes />, <ReconnectModal />, <script src="@Assets["_framework/blazor.web.js"]"></script>.
    • Routes.razor: <Router> definition referencing Program.Assembly and NotFoundPage="typeof(Pages.NotFound)".
    • Layout/ReconnectModal.razor (+ .razor.css, .razor.js): Circuit reconnection overlay.
    • Pages/Error.razor: Error display component.
    • _Imports.razor: Add @using static Microsoft.AspNetCore.Components.Web.RenderMode and remove WebAssembly-only namespaces.

File Structure

Web/
├── appsettings.json
├── appsettings.Development.json
├── Program.cs
├── Web.csproj
├── Properties/
│   └── launchSettings.json
├── Components/
│   ├── _Imports.razor
│   ├── App.razor
│   ├── Routes.razor
│   ├── Layout/
│   │   ├── MainLayout.razor
│   │   ├── MainLayout.razor.css
│   │   ├── ReconnectModal.razor
│   │   ├── ReconnectModal.razor.css
│   │   └── ReconnectModal.razor.js
│   └── Pages/
│       ├── Error.razor
│       ├── Home.razor
│       ├── Home.razor.css
│       └── NotFound.razor
├── Data/
│   ├── Overview.cs
│   ├── PersonalInfo.cs
│   ├── Skills.cs
│   └── WorkExperience.cs
└── wwwroot/
    ├── app.css
    ├── favicon.png
    └── lib/bootstrap/...

Architecture Diagram

graph TD
    Browser[Web Browser] -->|HTTP / WebSocket SignalR| ASPNET[ASP.NET Core Server]
    ASPNET --> Pipeline[Middleware Pipeline]
    Pipeline --> MapStatic[MapStaticAssets]
    Pipeline --> RazorComponents[MapRazorComponents: App.razor]
    RazorComponents --> Routes[Routes.razor / Router]
    Routes --> MainLayout[MainLayout.razor]
    MainLayout --> Home[Home.razor]
    MainLayout --> NotFound[NotFound.razor]
    Home --> Data[Data Layer: Overview, PersonalInfo, Skills, WorkExperience]

Testing

Validation Approach

  • Verify successful compilation with dotnet build Web/Web.csproj.
  • Validate that no obsolete WebAssembly packages or unused index.html remain.
  • Validate that all server components, router, reconnect modal, error handling, and static asset mappings compile and link properly.

Key Scenarios

  • Build Verification: Ensure dotnet build Web/Web.csproj completes with 0 errors.
  • Root Page Loading: Ensure root route / routes to Home.razor within MainLayout.razor.
  • 404 Handling: Ensure unknown routes re-execute to /not-found rendering NotFound.razor.
  • Error Page: Ensure /Error is routable to Error.razor.

Edge Cases

  • Disconnected SignalR circuit: Reconnection modal displays appropriate rejoining/paused/failed statuses.
  • Static asset path resolution: Verify _framework/blazor.web.js, Bootstrap CSS, and app.css resolve with @Assets.

Delivery Steps

✓ Step 1: Convert project SDK, configuration files, and ASP.NET Core server pipeline

The Web project is configured as an ASP.NET Core Web application with server hosting services and pipeline middleware.

  • Update Web/Web.csproj SDK to Microsoft.NET.Sdk.Web, remove Microsoft.AspNetCore.Components.WebAssembly package dependencies, and set BlazorDisableThrowNavigationException.
  • Relocate appsettings.json and appsettings.Development.json from Web/wwwroot/ to the project root directory Web/.
  • Remove the standalone static Web/wwwroot/index.html host file.
  • Rewrite Web/Program.cs to initialize WebApplication.CreateBuilder(args), configure Razor components with interactive server support (AddRazorComponents().AddInteractiveServerComponents()), and set up HTTP middleware (antiforgery, static asset mapping, status code re-execution, exception handling, and MapRazorComponents<App>().AddInteractiveServerRenderMode()).

✓ Step 2: Restore Blazor Server host, routing, reconnect UX, and imports

The application renders HTML from the server with full routing, error handling, and circuit reconnection UI.

  • Update Web/Components/App.razor to serve as the HTML root document with <Routes />, <ReconnectModal />, <HeadOutlet />, stylesheet assets, and _framework/blazor.web.js.
  • Add Web/Components/Routes.razor defining the <Router> with AppAssembly="typeof(Program).Assembly" and NotFoundPage="typeof(Pages.NotFound)".
  • Add Web/Components/Layout/ReconnectModal.razor and its scoped CSS / JS assets (ReconnectModal.razor.css, ReconnectModal.razor.js) to handle Blazor Server circuit reconnection states.
  • Add Web/Components/Pages/Error.razor to handle server-side request errors and show request diagnostic IDs.
  • Update Web/Components/_Imports.razor to import static render modes and server component namespaces.
  • Verify the solution builds without errors and serves the resume application over Blazor Server.