Presentations : Blazor WebAssembly
The Presentation Blazor WebAssembly layer templates generate a complete Blazor WebAssembly client application for each bounded context. The generator produces the project file, application entry point, dependency injection configuration, layout and menu components, home and error pages, resource files for localization, static web assets, and a full CRUD UI for each entity — including list, details, create, edit, and delete dialogs — all driven by the entity and bounded context definitions configured in the Scaffolder.net UI. Unlike the BlazorServer variant, this layer communicates with the backend via HTTP proxies and runs entirely in the browser.
Project File
The {{Solution.Name}}.Presentation.BlazorWebAssembly.{{BoundedContext.Name}}.csproj file defines the Blazor WebAssembly project using the Microsoft.NET.Sdk.BlazorWebAssembly SDK. It enables HTML asset placeholder overriding and loads all globalization data for client-side localization. It includes project references to the Application project (for shared command/query contracts) and the Shared.Presentation.Blazor and Shared.Presentation.BlazorWebAssembly projects, providing access to shared UI controls and BlazorWebAssembly-specific extensions. It also references the Microsoft.AspNetCore.Components.WebAssembly and Microsoft.AspNetCore.Components.WebAssembly.DevServer packages.
Imports
The _Imports.razor file declares global Razor directives for the presentation project. It imports ASP.NET Core Components routing and web namespaces, MudBlazor, the error and layout component namespaces, and all shared Blazor UI control namespaces (Button, CheckBox, DataGrid, DatePicker, Dialog, ErrorManager, Loading, NavMenu, NumericField, Select, SimpleTable, TextField, etc.). It injects shared services (IDialogService, IJSRuntime, NavigationManager) and string localizers for both the Domain and PresentationBlazorWebAssembly resources. The generator appends entity-specific @inject directives for each entity's query and command service proxies via {PresentationBlazorWebAssemblyGenerator.GetImports}. Finally, it inherits from ApplicationComponentBaseControl to provide shared component base functionality.
Global Usings
The GlobalUsings.cs file declares global using directives for the presentation project. It includes standard .NET namespaces, Microsoft ASP.NET Core Components and WebAssembly hosting namespaces, dependency injection, localization, JS interop, MudBlazor, and Serilog. The generator dynamically appends global usings for each entity's Application layer namespaces (commands, queries, errors, services) and Presentation BlazorWebAssembly namespaces (components, dependency injection, resources) via {PresentationBlazorWebAssemblyGenerator.GetGlobalUsings}, ordered alphabetically by entity name.
Program
The Program.cs file contains the application entry point. It creates the WebAssemblyHostBuilder using the default configuration, calls ConfigureWebAssemblyHostBuilder to register all client-side services, builds the WebAssemblyHost, logs startup information using Serilog, calls ConfigureWebApplicationAsync to apply culture and validation configuration, and runs the host. A global try-catch-finally block ensures fatal exceptions are logged and the logger is properly flushed on shutdown.
Components
The Components directory contains all Razor components for the Blazor WebAssembly application, organized into subdirectories for errors, entity features, home, layouts, menus, and the root routes file.
Components : Errors : NotFound
The NotFoundErrorPage.razor and NotFoundErrorComponent.razor files generate a @page "/NotFound" route with the MainLayoutComponent layout. The page renders the NotFoundErrorComponent, which displays a localized "Page not found" heading and content. Both files have partial code-behind classes declaring the namespace.
Components : Errors : Unknown
The UnknownErrorPage.razor and UnknownErrorComponent.razor files generate a @page "/UnknownError" route. The page renders the UnknownErrorComponent, which displays a localized "Unknown error" heading and content. Both files have partial code-behind classes declaring the namespace.
Components : Features : Entity Commands : Create
Create{{Entity.NameSingular}}Dialog with a Razor file and a code-behind file :
- Create{{Entity.NameSingular}}Dialog.razor : Renders a
DialogControlwith a localized title, a loading state, form input controls generated by{PresentationBlazorWebAssemblyGenerator.GetControls.WithId}(which producesTextFieldControl,NumericFieldControl,DatePickerControl,CheckBoxControl, orSelectEnumControlbased on each property's type), and Cancel / Create action buttons. - Create{{Entity.NameSingular}}Dialog.razor.cs : A sealed partial class implementing
IAsyncDisposablethat holds aCreate{{Entity.NameSingular}}CommandRequest, initializes non-nullable enum properties to their default values via{PresentationBlazorWebAssemblyGenerator.GetEnumsDefaultValue}, calls the command service proxy to create the entity, and closes the dialog with the result. Errors are displayed viaErrorManagerControl.
Components : Features : Entity Commands : Delete
Delete{{Entity.NameSingular}}Dialog with a Razor file and a code-behind file :
- Delete{{Entity.NameSingular}}Dialog.razor : Renders a
DialogControlwith a localized title, a loading state, a read-onlySimpleTableControldisplaying the entity's property values generated by{PresentationBlazorWebAssemblyGenerator.GetTableRows.WithId}, and Cancel / Delete action buttons. - Delete{{Entity.NameSingular}}Dialog.razor.cs : A sealed partial class implementing
IAsyncDisposablethat receives the entity Id as a parameter, loads the delete confirmation data via the query service proxy'sGetDelete{{Entity.NameSingular}}Asyncmethod (navigating to/NotFoundif the entity does not exist), shows aConfirmDeleteDialogControlbefore deletion, calls the command service proxy to delete the entity, and closes the dialog with the result.
Components : Features : Entity Commands : Edit
Edit{{Entity.NameSingular}}Dialog with a Razor file and a code-behind file :
- Edit{{Entity.NameSingular}}Dialog.razor : Renders a
DialogControlwith a localized title, a loading state, form input controls generated by{PresentationBlazorWebAssemblyGenerator.GetControls}(without the Id field, since the Id is not editable), and Cancel / Save action buttons. - Edit{{Entity.NameSingular}}Dialog.razor.cs : A sealed partial class implementing
IAsyncDisposablethat receives the entity Id as a parameter, loads the edit data via the query service proxy'sGetEdit{{Entity.NameSingular}}Asyncmethod (navigating to/NotFoundif the entity does not exist), populates theEdit{{Entity.NameSingular}}CommandRequest, calls the command service proxy to edit the entity, and closes the dialog with the result.
Components : Features : Entity Queries : GetDetails
- Get{{Entity.NameSingular}}DetailsPage.razor : Defines a
@page "/{{Entity.NamePlural}}/{{{Entity.NameSingular}}Id:{{Entity.IdType.ToLower}}}"route, renders a localized page title, and passes the route parameter to theGet{{Entity.NameSingular}}DetailsComponent. - Get{{Entity.NameSingular}}DetailsPage.razor.cs : A sealed partial class declaring the
{{Entity.IdType}}{{Entity.NameSingular}}Idparameter with[EditorRequired]. - Get{{Entity.NameSingular}}DetailsComponent.razor : Displays a localized heading, a loading state, a read-only
SimpleTableControlwith the entity's property values generated by{PresentationBlazorWebAssemblyGenerator.GetTableRows.WithId}, and an Edit button that opens theEdit{{Entity.NameSingular}}Dialog. - Get{{Entity.NameSingular}}DetailsComponent.razor.cs : A sealed partial class implementing
IAsyncDisposablethat loads the entity details via the query service proxy, handles theNotFounderror by redirecting to/NotFound, and opens the edit dialog with the entity Id.
Components : Features : Entity Queries : GetList
- Get{{Entity.NameSingular}}ListPage.razor : Defines a
@page "/{{Entity.NamePlural}}"route, renders a localized page title, and delegates rendering to theGet{{Entity.NameSingular}}ListComponent. - Get{{Entity.NameSingular}}ListPage.razor.cs : A sealed partial class declaring the namespace.
- Get{{Entity.NameSingular}}ListComponent.razor : Displays a localized heading, a loading state, a
DataGridControlwith property columns generated by{PresentationBlazorWebAssemblyGenerator.GetDataGridPropertyColumns.WithId}, a details hyperlink icon column, and a delete icon button column. An Add button opens theCreate{{Entity.NameSingular}}Dialog. - Get{{Entity.NameSingular}}ListComponent.razor.cs : A sealed partial class implementing
IAsyncDisposablethat loads the entity list via the query service proxy, orders the results by Id, and provides methods to open the create and delete dialogs. After a successful dialog action, the list is reloaded.
Components : Home
The HomePage.razor and HomeComponent.razor files generate the application landing page. The page defines a @page "/" route with a localized page title and renders the HomeComponent, which displays a localized heading and a welcome message using the solution name. Both files have partial code-behind classes declaring the namespace.
Components : Layouts
The MainLayoutComponent.razor and its code-behind generate the main application layout. The layout uses MudBlazor's MudLayout with a cascading dark-mode value, a MudAppBar containing a menu toggle button (with localized show/hide titles), the project name, a LanguageSelectorControl, and a dark/light mode toggle button. A MudDrawer hosts the MainMenuComponent, and MudMainContent renders the page body. The code-behind class manages the menu open state and dark mode preference via localStorage through JS interop, and configures a custom MudTheme with dark palette colors.
Components : Menus
The MainMenuComponent.razor and its code-behind generate the application navigation menu. The menu renders a NavMenuControl with a Home link and one NavLinkControl per entity, generated by {PresentationBlazorWebAssemblyGenerator.GetMenu}, which produces links to the /{{Entity.NamePlural}} route with localized display names. Each link uses NavLinkMatch.Prefix matching.
Components : Routes
The Routes.razor file defines the Blazor Router component, wrapped in an ErrorManagerControl. The router uses the presentation assembly (referenced via the {{Solution.Name}}PresentationBlazorWebAssembly{{BoundedContext.Name}}AssemblyReference marker type), sets the MainLayoutComponent as the default layout, and routes to the NotFoundErrorPage when no route matches.
Dependency Injection
DependencyInjection directory contains two extension classes that configure the Blazor WebAssembly host :
- WebAssemblyHostBuilderExtension : A static class with a
ConfigureWebAssemblyHostBuildermethod that registers Serilog, localization, HttpClient, Application service proxies (for HTTP-based command/query communication), MudBlazor services, and the Blazor WebAssembly root component (Routes). - WebAssemblyHostExtension : A static class with a
ConfigureWebApplicationAsyncmethod that applies the stored localStorage culture for client-side localization and configures the FluentValidation display name resolver using the Application and Domain resource types.
Properties
The launchSettings.json file defines the HTTPS launch profile for the development environment, with the application URL set to https://localhost:7200, ASPNETCORE_ENVIRONMENT set to Development, the browser launch option enabled, and a debug inspect URI for Blazor WebAssembly debugging via the WebSocket proxy.
Resources
Resources directory contains the localization resource class and its associated .resx file :
- {{Solution.Name}}PresentationBlazorWebAssembly{{BoundedContext.Name}}Resource.cs : A sealed marker class used by the
IStringLocalizerinfrastructure to resolve localized strings for the presentation layer. - {{Solution.Name}}PresentationBlazorWebAssembly{{BoundedContext.Name}}Resource.resx : The resource file containing localized strings for the layout (project name, menu toggle titles, dark/light mode titles), main menu (Home link, entity plural names generated by
{PresentationBlazorWebAssemblyGenerator.GetResources}), home page, error pages, and entity-specific page titles, headings, and dialog labels for list, details, create, edit, and delete operations — all humanized from the entity names.
wwwroot
wwwroot directory contains the static web assets for the Blazor WebAssembly application :
- index.html : The root HTML document that hosts the Blazor application. It loads MudBlazor CSS, the project-specific CSS, Roboto fonts, the favicon, the Blazor WebAssembly JavaScript bootstrapper, MudBlazor JavaScript, and the custom
Default.js. It includes a loading spinner placeholder displayed while the WebAssembly payload downloads. - appsettings.json : Configures the WebApi base address for HTTP proxy calls, the default and supported localization cultures, and Serilog console logging with minimum levels for the production environment.
- appsettings.Development.json : Overrides the WebApi base address to
https://localhost:7300and Serilog minimum levels toInformationfor the Development environment. - Default.css : Defines custom CSS styles for headings, the language selector control (with dark and light mode variants), dialog control title and content styling, and the loading container and spinner animation displayed during initial load.
- Default.js : Contains JavaScript helper functions for client-side culture management, including
getCultureFromCookieto read the culture from the ASP.NET Core culture cookie andcultureHelperto get/set the culture inlocalStorage. - favicon.png : The binary favicon image served as the browser tab icon. This file is copied as binary content without tag replacement.