Guides.NET
Blazor Web App with EF Core, Identity, and SQLite
Create an ASP.NET Core Blazor app with Razor components, EF Core on SQLite, ASP.NET Identity, SignalR, Serilog, and xUnit using Better Fullstack.
Use this stack when one .NET project should serve both the UI, as Razor components, and a small JSON API, with a file-based SQLite database for local work.
npm create better-fullstack@latest my-blazor-app -- \ --ecosystem dotnet \ --dotnet-web-framework aspnet-blazor \ --dotnet-orm ef-core \ --dotnet-auth aspnet-identity \ --dotnet-api minimal-api \ --dotnet-testing xunit \ --dotnet-job-queue none \ --dotnet-realtime signalr \ --dotnet-observability serilog \ --dotnet-validation none \ --dotnet-caching none \ --dotnet-deploy docker \ --dotnet-libraries none \ --database sqliteWhat this creates
- An ASP.NET Core app that registers Razor components with interactive server rendering.
App.razor,Routes.razor, and aHome.razorpage at/.- EF Core with the SQLite provider and an
AppDbContextholding aTodosset. - ASP.NET Core Identity registered against that context.
GET /api/status,GET /api/todos, andPOST /api/todosbeside the components.- A SignalR hub at
/hubs/updates, Serilog console logging, an xUnit project, and aDockerfile.
Generated shape
my-blazor-app/
├── my_blazor_app.csproj
├── my_blazor_app.http
├── Program.cs
├── appsettings.json
├── appsettings.Development.json
├── Dockerfile
├── Components/
│ ├── App.razor
│ ├── Routes.razor
│ ├── _Imports.razor
│ └── Pages/
│ └── Home.razor
└── my_blazor_app.Tests/
├── my_blazor_app.Tests.csproj
└── ApiTests.csThe project name becomes my_blazor_app, and _Imports.razor imports my_blazor_app.Components.
Prerequisites
- .NET SDK 10 or newer.
- No database server.
appsettings.jsonsetsData Source=my_blazor_app.db, a SQLite file next to the app.
Run and verify
cd my-blazor-app
dotnet restore
dotnet runOpen the URL ASP.NET Core prints. / renders Home.razor, which links to /api/status.
dotnet test my_blazor_app.Tests/my_blazor_app.Tests.csprojNo solution file is generated, so name the test project. The generated test requests / through WebApplicationFactory<Program> and expects a 200 response.
Create the database before using the todo endpoints
Program.cs registers AppDbContext but never calls Migrate() or EnsureCreated(), so the SQLite file has no Todos table until you create it. Microsoft.EntityFrameworkCore.Design is already referenced:
dotnet tool install --global dotnet-ef
dotnet ef migrations add InitialCreate
dotnet ef database updateInteractivity
Program.cs registers the interactive server render mode, and App.razor includes a <script src="_framework/blazor.web.js"> tag. The generated app does not serve that script: a request for /_framework/blazor.web.js returns 404, so the Blazor client never starts in the browser. Pages render as static server-side HTML, and a component marked @rendermode RenderMode.InteractiveServer shows its prerendered markup but does not run @onclick or other event handlers.
Representative snippets
Components and API endpoints share one pipeline:
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
app.MapGet("/api/todos", async (AppDbContext db) =>
{
return Results.Ok(await db.Todos.OrderBy(todo => todo.Id).ToListAsync());
});
app.MapHub<UpdatesHub>("/hubs/updates");
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();The hub broadcasts any message it receives to every connected client:
public sealed class UpdatesHub : Hub
{
public Task Broadcast(string message) => Clients.All.SendAsync("update", message);
}When to choose it
Choose Blazor when the team wants C# end to end and a server-rendered UI without a separate JavaScript build. Choose the ASP.NET Core and EF Core guide for an API-only service on PostgreSQL.
Compatibility notes
--dotnet-web-framework aspnet-blazoris the server-side Blazor app. The separate--dotnet-frontendoption (blazor-webassembly,blazor-web-app) adds a .NET frontend part in composed projects.--dotnet-auth aspnet-identitycallsAddIdentityCore<IdentityUser>().AddEntityFrameworkStores<AppDbContext>(), butAppDbContextderives fromDbContext, notIdentityDbContext. Change the base class and add a migration before resolving the user store. No login pages are generated.--database postgresswitches EF Core to the Npgsql provider.
Deployment notes
The Dockerfile publishes with the .NET 10 SDK and runs on the ASP.NET 10 runtime image on port 8080. The SQLite file lives inside the container's /app directory, so it is lost when the container is replaced. Mount a volume and point ConnectionStrings__DefaultConnection at it, or switch to PostgreSQL for hosted environments.
Troubleshooting
| Symptom | Check |
|---|---|
SQLite Error 1: 'no such table: Todos' | Create and apply an EF Core migration. |
| Button clicks on a page do nothing | /_framework/blazor.web.js returns 404 in the generated app, so the Blazor client does not start. |
| Identity user store fails to resolve | AppDbContext must derive from IdentityDbContext and have a migration. |
The .http file's GET / returns HTML | / is the Blazor page here; use /api/status for the JSON status response. |
localhost:5000 returns 403 on macOS | AirPlay Receiver also listens on port 5000. Start the app with another port, for example PORT=5080 dotnet run. |
| The generated README mentions TypeScript and npm | The .NET scaffold currently writes the TypeScript README. Use the commands in this guide. |
Next steps
- Open the Stack Builder.
- Read the .NET ecosystem docs.
- Review the CLI create reference.