I make a lot of Blazor Server apps, and I got tired of building from these scratch. This sample brings together all the boilerplate I start with currently.
Blazor Server in .NET9 is really nice IMO because of the improved SignalR reconnection experience. In prior .NET versions, that was a bit of a pain point. Disconnections still happen as this is a limitation of sockets in browsers, but .NET9 is more graceful in how it reconnects and automatically refreshes the page when needed.
I prefer Blazor Server over Web Assembly because Server is much more productive. In Blazor WASM you have to implement an API layer and split your project into separate backend and frontend projects. That's extra work, and a painful context shift IMO. In Blazor Server, it's all one project. Also I've had success deploying to DigitalOcean using GitHub Container Registry. This is cheaper than Azure, though there's a little more to setup. I've used Azure a long time, but I don't like being locked into it.
- Uses Radzen Blazor for UI components
- Has a few custom widgets for common CRUD use and navigation. See the demo crud page.
- I replace the "NoOp"
IEmailSender
with CoreNotify so that account notification emails work right away. See startup. This is technically a paid service of mine. There is a 30-day free trial. There might be a working API key in configuration when you're reading this. I recycle this key occasionally, so it might not work in the template by the time you're reading this. In that case, register your own CoreNotify account and apply your own API key. Info on that is in the CoreNotify readme. - I recommend disabling prerendering. When prerendering is turn on, components get initialized multiple times. This is by design, but not efficient if you have database queries being run during component initialization.
This uses ASP.NET Identity via an EF Core IdentityDbContext
.
- I added a
TimeZoneId
property to the ApplicationUser to demonstrate a simple customization - This can be managed in the profile manage page
- I link appsettings.json from the main app to the Database project so that EF migrations can share the same connection string as the app. I don't want to set the connection string in more than one place.
- The db context has simple auditing of inserts and updates
- I use a BaseTable class to ensure consistent
Id
property use across all entities, among other common properties. - If you need to target different database connections with your migrations, pass an optional additional argument to your
dotnet ef database update
command. For example:dotnet ef database update -- Dev
will update a connection namedDev
. Just make sure the connection is defined in your appsettings or local secrets config. This is implemented in the custom design time db context factory.
Although you can get the ClaimsPrincipal
in a Blazor app easily, there's no obvious way to get the ApplicationUser
. This is a problem if you have custom user properties. Although you could query the user from the database, that is not efficient. To address this, I have the AuthExtensions project. This is offered as a NuGet package AO.Blazor.CurrentUser
, but is also used inline in the template app. Please see its readme for more info.
I use this Docker command to install Postgres locally.
You'll need to make sure Postgres is running before your app is.
- Radzen uses Material Icons. Anywhere there's an
Icon
property, any of these Google icons will work.