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

ASP.NET Nano Web API

The Web API project is the top level project in the .NET Solution. It contains the entry point of the application, program.cs, and is configured with appsettings.json. Keeping app settings in an external json file makes it easier to manage configuration changes as they happen. Some of these app settings, like connection strings, are replaced by environment variables when an app is published.

Any clean architecture solution will have an equivalent top layer which contains the presentation elements. These can be RESTful API controllers that expose functionality to the outside or pages in a razor pages / MVC project. When a solution is compiled, other layers (class libraries) are rolled into the Web API.

Since .NET 6 onward, there is no startup.cs class. All of the app bootstrapping is now contained within program.cs.

By using extension methods, code can be better organized and moved out of the program.cs class itself.

In the Nano ASP.NET Boilerplate, all service registration code is handled by the ConfigureApplicationServices method in the ServiceCollectionExtensions class.

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

Following the DB Contexts’ registration, AddAndMigrateTenantDatabases runs pending migrations. (named AddAndMigrateDatabase if using single-database multi-tenancy). In a multi-db setup, these migrations will apply to all tenant databases in addition to the primary one.

All other services that do not require configuration are handled by AddServices from the DynamicServiceRegistrationExtensions class.

The main method, AddServices, dynamically registers any class in the solution that inherits from a ITransientService or IScopedService marker interface. This prevents you from having to manually add new registration code anytime you create a new service.

For example, the ProductService implements IProductService which inherits from ITransientService. The product service will be automatically registered as a transient service. The same can be done for scoped services.

The AddServices method is called in ConfigureApplicationServices, which as the name implies, bundles all the app configuration logic.

Modify appsettings.json variables to change things like the connection string, logging level, host URL, etc. The boilerplate has test keys for Ethereal mail and Cloudinary should be replaced with your own; both services are free and are quick to set up.

Static files are kept in the wwwroot directory. If using React / Vue, place the compiled build files in this directory. In a SPA setup, the FallbackController directs all web traffic to index.html in wwwroot.

TenantResolver is middleware responsible for reading the tenant and user info on every request. Middleware is run before a request 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.

To quickly scaffold new services with CRUD functionality, use the dotnet new nano-controller command. Check out the CLI tool guide for parameters and options.

The API controllers in WebApi use services from the Infrastructure and Application layers. 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.

To 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.

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