
Upgrade to .NET 10 by downloading and installing the SDK for your preferred IDE on Windows, Linux, or macOS, and avoid the runtime.
Open the solution in Visual Studio to upgrade your multi-tenant .NET full-stack projects to .NET 10, updating the Web API and domain project target frameworks and refreshing all packages.
Update packages across domain and application, including fluent validation and map star; verify dotnet eight compatibility, exclude mediator due to licensing, and review the clean mediator as an alternative.
Upgrade a multi-tenant .net app by resolving breaking changes from package upgrades, installing finbuckle packages, updating constructors and namespaces, and validating the build before launching on .NET 10.
Design a dotnet multi-tenant web api with a root tenant that administers others, while tenants manage their own data using per-tenant or shared databases with role-based permissions via asp.net identity.
design a multi-tenant web api with swagger ui, role based permissions, and json web tokens. present tenant onboarding and a blazor webassembly front end with per-tenant or shared database strategies.
Plan a full stack workflow by implementing the back end first, then the front end, using preview videos to align the front end with the completed back end.
Develop a Blazor WebAssembly frontend for a multi-tenant application, integrating tenant management, subscription control, dynamic user and role permissions, and authentication and authorization in the UI.
Install Microsoft SQL Server and the management studio to visualize and query your databases, with SQL Server as the default database. You may also use Postgres by adjusting the code, and set up Visual Studio 2022 or Visual Studio Code with the provided download URLs.
In Visual Studio 2022, create a blank multi-project solution with domain, application, infrastructure, and web api layers, wire references so each layer depends on the previous and target dotnet eight.
Turn off the nullable enable setting for Web API, domain, and application projects to avoid mandatory initialization of nullable properties, illustrated by updating the weather forecast class and warnings.
Summarizes project responsibilities in clean architecture: define domain entities in the domain layer, implement CRUD in the application layer, and manage infrastructure with Entity Framework Core and a web API.
Define a school domain entity in the domain layer with id, name, and established date to represent a specific school within a multi-tenant architecture where each school is a tenant.
Install and configure multi-tenant infrastructure by adding the buckle multi-tenant package, asp.net core, and entity framework core packages via NuGet, then set up identity, sql server provider, and ef tools.
Define a tenant entity model implementing tenant info, including identity, identifier, name, and connection string. Include admin email and is active flag with subscription status for dedicated or shared databases.
Create a tenant db context for ABC school, inheriting from the multi-tenant DB context, configuring the tenants table and multi-tenancy schema, and planning to replace magic strings with constants.
Configure a multi-tenant setup by adding a startup-based dependency injection extension that wires a tenant db context, sql server connection, header and claim based tenant identification, and EF Core stores.
Define tenancy constants to replace magic strings, exposing a public tenant ID name. Integrate these constants in startup and the db context, and plan future schema constants and migrations.
Configure multi-tenant support by wiring infrastructure services and middleware into the final dependency injection container. Add multi-tenant middleware in program.cs and apply infrastructure use in the app pipeline.
Extend the ASP.NET identity subsystem by creating application user and role models, adding first name, last name, an is-active flag, and refresh token fields to support JSON web token authentication.
Create ApplicationRole and ApplicationRoleClaim by extending IdentityRole and IdentityRoleClaim, add descriptions, and group permissions for administrators, management, HR, and academics in a multi-tenant .NET app.
Create a base db context for multi-tenant identity, integrate identity models, and wire constructors to accept tenant context, letting the application context focus on application entities.
Configure the base db context to let each tenant use its own SQL Server database, via a tenant-specific connection string, hiding the base tenant info and applying migrations across databases.
Initialize the base db context with tenant info from the tenant info context accessor, binding to the current tenant to support per-tenant connection strings and migrations.
Define the application DbContext by inheriting from the base DbContext, add the schools DbSet, and register it in startup via dependency injection with SQL Server and a shared connection string.
Configure entity type configurations to customize ASP.NET Identity tables, changing their names and schema, and enable multi-tenant data isolation by adding tenant-aware columns.
Override on model creating in the base db context and apply configuration from the executing assembly to load all entity type configurations, including the school entity in the academics schema.
Install the Entity Framework tools in the web API project to enable migrations, then add the default connection string for a shared multi-tenant database and verify the build before migration.
Set your web api as the startup project, generate a tenant db migration with the tenant db context, and apply it to create the tenants table, then update the database.
Create and review the application db context migration, disable the unique constraint on the role name index to support multi-tenant shared databases, and verify identity tables are created.
Define school action constants in infrastructure constants to seed permissions for a multi-tenant app, creating read, create, update, delete, and upgrade subscription actions and mapping them to roles and users.
Create and organize feature constants and permissions, defining a public static class for school features such as tenant, users, roles, and role claims, and build role permissions across features.
Define a school permission record with action, feature, description, and basic and root tenant flags, plus a name generator that builds permission strings like permission.{feature}.{action} for seeding role claims.
Define a school permissions class to build and list tenant-related permissions, including create, read, update, upgrade subscription for root and route tenants, with identity and school features.
Define identity by configuring users, roles, and permissions for a multi-tenant system. Authorize actions across users, roles, role claims, and school entities with read, create, update, and delete permissions.
Expose read-only school permissions and filter by root, admin, and basic categories to assign correct rights within a multi-tenant application.
Define admin and basic role constants, expose a static read-only collection of default roles, and implement an is-default-role check to prevent deletion of system-defined roles.
Define claim constants for the JSON web token payload, declaring tenant and permission keys as public constant strings, then apply these to the token before moving to database setup.
Define an additional property representing a group in permission records and assign each permission to a specific group such as tenancy, system access, or academics, enabling later filtering by group.
Initialize and seed a multi-tenant database by applying migrations, checking for pending migrations, and configuring users, roles, and permissions via the application db context and identity managers.
Seed the database with default roles, assign permissions to each role, and prepare user creation in a multi-tenant .NET full-stack app, using helper methods and role management.
Seed the default roles from predefined constants, create any that do not exist using the role manager, and prepare to assign permissions.
Assign permissions to roles by checking role constants, applying admin or basic permissions, and using a helper to asynchronously update claims, avoid duplicates, and save permission changes to the database.
Assign permissions to specific roles within a multi-tenant application, handling admin and root tenant permissions, and passing the incoming role and permissions.
Seed the root tenant admin by defining constants for default password and admin first and last name, then create and hash the user via the multi-tenant context and user manager.
Assigns a new user to the admin role by checking role membership with is in role async, then updates user_roles and seeds default roles and admin users.
Define and seed a tenant database for a multi-tenant app, implementing a tenant db setup, interface, and async data initialization. Inject dependencies and seed tenant data before identity data.
Initialize the database with a root tenant by checking for an existing root, creating the root tenant using predefined constants, and saving changes via the tenant context and cancellation token.
Seed application data for every tenant by listing tenants, creating a scoped context, and initializing the application database for each tenant using the multi-tenant context.
Learn to seed tenant and application databases via dependency injection, wire as transient services, and invoke an async database initializer in startup.
Configure identity in dependency injection for a multi-tenant .NET app by defining application user and role, password options, wiring entity framework store and token providers, and seeding users and roles.
Launch the app and confirm successful seeding of the database: tenants, users, roles, and permissions align with admin and basic roles, with role claims and groups verified.
define and raise custom unauthorized exceptions in the application layer with status code 401, and handle them via a global exception handling middleware during login.
Define custom exceptions by extending the base exception class, add properties and constructors, and use 404 not found, 403 forbidden, 409 conflict codes, with identity exceptions and a startup class.
Create a global, generic API response wrapper with a non-generic base and a generic payload, including messages and a success flag for consistent contracts.
Implement a non-generic response wrapper to centralize handling of failure and success, exposing messages, a successful flag, and static fail and success methods.
Implement non-generic failure response wrappers with three overloads: single message, list of messages, and synchronous and asynchronous variants, each setting isSuccessful to false for failed requests.
Explore non-generic response wrappers and failure implementations across function overloads, covering asynchronous and synchronous calls, task.from_result wrapping, and parameter variations.
Explore building non-generic and generic response wrappers for success scenarios, including synchronous and asynchronous overloads with single or multiple messages and proper flag handling.
Define and implement a generic response wrapper in a single file, including a public class ResponseWrapper<T> with data, and synchronous and asynchronous success and failure methods that fulfill the contract.
Explore implementing permission-based authorization by defining the first of three essential classes—a permission requirement that implements IAuthorizationRequirement with a permission property and a constructor in the identity infrastructure.
Define a permission policy provider to dynamically create authorization policies for specific permissions, using token claims prefixed with 'permission' to evaluate access.
Define and implement a permission-based authorization handler that reads user claims, matches claim type and value to the permission requirement, and succeeds when authorized.
Inject permissions into dependency injection by registering a custom permission authorization policy provider and a permission authorization handler as singleton and scoped services in the web api infrastructure.
Implement a login feature that accepts a username and password, generates a json web token, and returns a token response with the jwt, a refresh token, and its expiry date.
Define a refresh token request model that accepts the current JWT and refresh token, validates expiry, and uses them to issue a new JWT, requiring login if expired.
Define a publicly accessible ITokenService interface with loginAsync and refreshTokenAsync methods that return TokenResponse and accept TokenRequest and RefreshTokenRequest, where TokenResponse includes token, refresh token, and refresh token expiry.
Implement the token service in the infrastructure layer, wiring in the user manager and multi-tenant context to support login and refresh token flows using jwt.
Implement an asynchronous login with multi-tenant validations: verify active tenant, confirm user exists in that tenant, check password, and ensure the user is active before authenticating.
Implement token service login validation by checking non-root tenants' subscription expiry using valid up to dates; throw an authorization exception if expired, while root tenants bypass expiry checks.
Implement a full login flow that generates a jwt, builds user and tenant claims, updates the user with a refresh token, and uses modular, asynchronous helpers for signing.
Learn to generate tokens that include role claims, permissions, and user claims by injecting role and user managers, querying roles and claims, and building a token for authorization.
Learn to implement refresh tokens by creating a claims principal extensions class that exposes access to user information such as email, user id, and tenant details from the current context.
Implement a complete refresh token flow: validate the expiring token, verify signing key and claims, locate the user by email, validate and update refresh token, and generate a new token.
Create a JWT settings class in the application layer to hold the secret, token expiry in minutes, and refresh token expiry in days, replacing magic strings with configuration.
Learn how to refactor configuration into dependency injection by creating a public extension that binds JWT settings from app settings and registers them in the program startup.
Register a json web token service in dependency injection, configure jwt bearer authentication, and handle authentication events to return consistent, wrapped error responses via a global response wrapper.
Implement jwt authentication into dependency injection, handle on challenge responses, set unauthorized and forbidden results, and add authorization overloads to secure endpoints.
Register JWT authentication in dependency injection, dynamically create in-memory policies from constant permissions, and wire the JWT service in program to enable login and token-based access.
Install the swagger package, create an Open API swagger header, and implement a tenant header attribute inheriting the swagger header to pass the tenant in the login request header.
Implement a tenant header in a multi-tenant .NET app to drive login via token endpoint, specifying the tenant at login and including it in JWT claims, shown in Swagger UI.
Explore dynamic Swagger documentation by adding Swagger settings drawn from configuration, including the API title, company name, license, contact number, and email address, and extend the Swagger UI accordingly.
Implement a swagger header attribute processor to evaluate the tenant header, process metadata in the header, identify swagger headers, and update open api parameters with a string tenant value.
Create a swagger global auth processor to enforce a bearer JWT scheme across endpoints. Retrieve endpoint metadata, skip endpoints with allow anonymous, and configure OpenAPI security requirements.
Register OpenAPI processors in dependency injection, bind swagger settings from configuration, and configure OpenAPI documentation with title, description, contact, license, and a JWT bearer security scheme.
Register the OpenAPI document in the service container and add an IApplicationBuilder extension to enable OpenAPI, swagger, and swagger UI with model depth -1, dock expansion none, and alpha sort.
Remove the default swagger UI and endpoint explorer from program.cs, replace with add OpenAPI document, and remove JWT middleware in favor of infrastructure authentication and authorization middlewares after multi-tenant setup.
Define a permission-based authorize attribute to protect endpoints by generating permissions from feature and action, then apply the attribute and test policy-based authorization.
Test the post authorize attribute in api testing using swagger, open api extensions, and the authorization header to attach tokens and inspect authorized versus unauthorized responses.
Enable user login in the application layer using CQRS with mediator. Install mediator, Map Star, fluent validation, and the dependency injection extension to map requests and validate inputs.
Configure dependency injection in the application layer by creating a startup class, registering validators from the assembly, and wiring mediator with services in the web api program.
Define and implement a get token query using mediator, token request, and token service to generate a token and refresh token, using a response wrapper for multi-tenant .NET full-stack apps.
Implement the get refresh token query with mediator, create a request handler that injects the token service to refresh the token, and return a response wrapper with refreshed token.
Design a base api controller that injects a mediator sender to dispatch commands and queries, using dependency injection and http context to resolve the required services.
Define a token controller with a post login endpoint that accepts a tenant header, uses a mediator to get a token, and returns a jwt or bad request.
Implements a refresh token endpoint using http post to generate a new jwt from refresh token, reading the token from request body and returning success or bad request alongside login.
Create a new refresh token permission under the tokens feature in system access, marked as basic for all users, and require it for the refresh endpoint.
Test the login endpoint by using root tenant, username, and password from constants. Retrieve the JWT and inspect its payload for name identifier, email, name, tenant, role, and permissions.
Test protected endpoints by validating token-based authentication and read permissions like school read, using a weather forecast endpoint to confirm authorization and successful 200 responses.
Learn to handle expired JSON web tokens by guarding response modification with a has started check, returning unauthorized and a token expired message; replicate by shortening token lifespan.
Implement a global error handling middleware for a web api that catches all exceptions and returns a json error with a message and proper status code.
Fix error handling middleware to propagate custom exception messages by switching to a traditional switch statement, updating status codes and response messages for each exception.
Test the error handling middleware in a multi-tenant .NET app by simulating an invalid token and tracing unauthorized exceptions, ensuring the global response wrapper outputs with correct status and messages.
Dive deep into .NET 8 with our advanced online course, focusing on multi-tenancy solutions and cutting-edge techniques. Learn to architect clean and scalable solutions while mastering multi-tenancy support using Finbuckle libraries. Explore subscription management for tenants, ASP.NET Core Identity for user management, and JWT authentication for secure access control.
Unlock the power of permission-based authorization and seamlessly implement global response wrappers for standardized API responses. Delve into advanced patterns such as CQRS with MediatR, Pipeline behaviours and leverage FluentValidation for robust data validation. Discover the elegance of C# 9's primary constructor syntax and elevate your API documentation with advanced Swagger UI implementations.
Ideal for developers seeking to enhance their ASP.NET Core skills, this course offers practical insights and hands-on experience to excel in building sophisticated, multi-tenant applications.
Key Topics Covered:
Multi-Tenancy Support with Finbuckle
Subscription Management for Tenants
ASP.NET Core Identity and JWT Authentication
Permission-Based Authorization
Global Response Wrapper Implementation
CQRS Patterns with MediatR
Data Validation using FluentValidation
Primary Constructor Syntax in C# 9
Advanced Swagger UI Implementations
Blazor Webassembly
MudBlazor UI Library
And much more...
Prerequisites: Basic understanding of ASP.NET Core development and C# programming language recommended.
Enroll now and unlock the full potential of ASP.NET Core for multi-tenant applications!