Nano ASP.NET SaaS Boilerplate
Admin credentials (all tenants): / Password123!
Sample data resets every hour
Nano ASP.NET SaaS Boilerplate
.NET Solution
Vue UI
React UI
Razor Pages
.NET Solution

Web Api

The WebApi project is the top level project in the .NET Solution. It contains RESTful API controllers that expose functionality to the outside. The entry point of the app is program.cs and is configured with appsettings.json.

Service Registrations

All service registration code is handled by ConfigureApplicationServices.


This class contains an extension method ConfigureApplicationServices, responsible for registering application services that require configuration.  These services are CORS, Fluent Validation, AutoMapper, MailKit, Cloudinary, Api Endpoints, Db Contexts, Identity, and Authentication.

Following the DB Contexts’ registration, AddAndMigrateTenantDatabases will run any pending migrations. (AddAndMigrateDatabase in single-database)

All other services that do not require configuration are handled by AddServices.


This class contains an extension method AddServices, which is called by ConfigureApplicationServices. AddServices dynamically registers any class in the solution that inherits from ITransientService or IScopedService.

For example, the ProductService implements IProductService which inherits from ITransientService. In this case, the product service will get registered as a transient service. The same can be done for scoped services. The AddServices method is called in ConfigureApplicationServices.

App Settings

In appsettings.json you can set the database name in Default Connection, or adjust logging level, host URL, etc. The boilerplate has test keys for Ethereal mail and Cloudinary but these should be changed; both services are free and are quick to set up.


Static files are kept in the wwwroot directory. This is where you put compiled build files from the React / Vue project. The FallbackController directs all web traffic to index.html in wwwroot.

Middleware & Services

TenantResolver is middleware responsible for reading the tenant and user info on every request. Middleware is run on a request before it reaches a controller.

TenantResolver will check if the request contains a JWT bearer token. On authenticated requests, the tenant and user ID will be read from the token. These values are stored in CurrentTenantUserService which are then used by the app to isolate tenant data and provide any user based functionality. These topics are explored further in the Authorization & Authentication and Multi-Tenancy guides.

If single-database or single-tenant type is chosen for the multi-tenancy option, there will be slight differences to the code.

API Controllers

The API controllers in WebApi typically use services from Infrastructure and Application. Access can be controlled by applying an Authorize attribute with roles on a particular controller or endpoint. Check out the Authorization & Authentication guide to learn more.

You can quickly scaffold new API controllers with CRUD endpoints. Use the dotnet new nano-controller command. Check out the CLI tool guide for parameters and options.

Next Steps

In the next guide, we’ll see how Application Services are structured by examining the Product Service.