AspNetRestKit
A secure ASP.NET Core Web API starter kit with JWT authentication, role-based authorization, multi-database support, audit logging, Serilog, API versioning, pagination, filtering, sorting, CI/CD, and Swagger documentation.

AspNetRestKit is a practical ASP.NET Core Web API starter kit for building and studying clean backend APIs. It keeps a single main Web API project while separating responsibilities through controllers, services, repositories, DTOs, mappers, middleware, settings, and data access folders.
Table of Contents
- Overview
- Features
- Architecture
- Technologies
- Getting Started
- Running with Visual Studio
- Running with .NET CLI
- Configuration
- Database Providers
- Database Scripts
- Authentication and Authorization
- API Endpoints
- Example Requests
- CI/CD
- Logging and Audit
- Security Notes
- Useful Commands
- Contributing
- License
Overview
AspNetRestKit demonstrates modern backend development patterns in a compact and approachable ASP.NET Core Web API codebase.
It includes authentication, authorization, multi-database configuration, API versioning, pagination, filtering, sorting, global exception handling, audit logging, structured logging, CI/CD, and Swagger documentation.
The project intentionally uses a single main project structure instead of a multi-project enterprise layout. This keeps the repository easy to inspect while still preserving clear boundaries between HTTP, business logic, data access, mapping, configuration, and middleware.
Features
API
- Product and Category CRUD operations
- JWT authentication
- Refresh token support
- Role-based authorization
- API versioning with
/api/v1 - Pagination, filtering, and sorting
- Swagger/OpenAPI documentation
- Standard API response format
Data
- Entity Framework Core
- SQLite support
- SQL Server support
- PostgreSQL support
- EF Core design-time DbContext factory
- Provider-based SQL scripts under
/database - Soft delete support
- Seed data
Security
- Password hashing
- JWT Bearer authentication
- Admin/User role model
- Security headers
- Rate limiting
- Custom validation responses
- Global exception handling
- No stack trace exposure in API responses
Quality
- Serilog console and file logging
- Audit logging
- GitHub Actions CI pipeline
- Visual Studio compatible launch profiles
- Hardened
.gitignore
Architecture
| Folder | Responsibility |
|---|---|
Controllers |
Handles HTTP requests and delegates business logic to services |
Services |
Contains business rules and application logic |
DAL |
Contains DbContext, repositories, configurations, and seed data |
Models |
Contains database entities |
DTOs |
Contains feature-specific request and response models |
Mapper |
Contains manual mapping logic |
Middleware |
Contains exception handling and security headers |
Settings |
Contains strongly typed configuration models |
database |
Contains provider-specific SQL scripts |
Technologies
| Technology | Purpose |
|---|---|
| .NET 8 | Runtime and framework |
| ASP.NET Core Web API | REST API development |
| Entity Framework Core | ORM and database access |
| SQLite | Default local database |
| SQL Server | Supported relational database |
| PostgreSQL | Supported relational database |
| JWT Bearer | Authentication |
| Serilog | Structured logging |
| Swagger / OpenAPI | API documentation |
| GitHub Actions | CI pipeline |
Getting Started
Prerequisites
- .NET 8 SDK
- Git
- Visual Studio 2022, Visual Studio 2026, or the latest Visual Studio version
- SQL Server or PostgreSQL only if you want to use them instead of SQLite
Clone the Repository
git clone https://github.com/hamzadenizyilmaz/AspNetRestKit.git
cd AspNetRestKit
Restore Packages
dotnet restore
Build
dotnet build
Running with Visual Studio
- Open Visual Studio 2026, Visual Studio 2022, or the latest Visual Studio version.
- Select Open a project or solution.
- Open
AspNetRestKit.sln. - Wait for NuGet restore to complete.
- Make sure
AspNetRestKitis selected as the startup project. - Select the
httpslaunch profile. - Press
F5orCtrl + F5. - Swagger UI should open automatically.
Default Swagger URLs:
https://localhost:7025/swaggerhttp://localhost:5025/swagger
Package Manager Console
Open:
Tools > NuGet Package Manager > Package Manager Console
Set the default project to:
AspNetRestKit
Run:
Add-Migration InitialCreate
Update-Database
Common Visual Studio Fixes
| Problem | Solution |
|---|---|
| Project does not load | Install .NET 8 SDK |
| NuGet packages are missing | Restore NuGet packages |
| HTTPS error | Run dotnet dev-certs https --trust |
| Swagger does not open | Visit https://localhost:7025/swagger manually |
| Migration fails | Check the default project and ApplicationDbContextFactory |
Running with .NET CLI
dotnet restore
dotnet build
dotnet ef migrations add InitialCreate
dotnet ef database update
dotnet run
Open Swagger:
https://localhost:7025/swagger
Configuration
Main configuration file:
appsettings.json
Important configuration sections:
| Section | Description |
|---|---|
DatabaseSettings |
Selects the active database provider |
ConnectionStrings |
Contains provider-specific connection strings |
JwtSettings |
Configures JWT issuer, audience, secret, and expiration |
Serilog |
Configures console and file logging |
SwaggerSettings |
Configures Swagger title, version, and description |
Do not use the default JWT secret in production. Use environment variables, user secrets, or a secret manager.
dotnet user-secrets init
dotnet user-secrets set "JwtSettings:Secret" "your-secure-development-secret"
Database Providers
AspNetRestKit supports three database providers:
- SQLite
- SQL Server
- PostgreSQL
The default provider is SQLite.
Provider selection is controlled from appsettings.json:
"DatabaseSettings": {
"Provider": "SQLite",
"ConnectionString": ""
}
Available connection strings:
"ConnectionStrings": {
"SQLite": "Data Source=aspnetrestkit.db",
"SqlServer": "Server=localhost;Database=AspNetRestKitDb;Trusted_Connection=True;TrustServerCertificate=True;",
"PostgreSQL": "Host=localhost;Port=5432;Database=AspNetRestKitDb;Username=postgres;Password=your_password"
}
If DatabaseSettings.ConnectionString is empty, the application uses the connection string matching the selected provider.
Switching Provider
- Open
appsettings.json. - Change
DatabaseSettings.Provider. - Update the related connection string.
- Create a migration for the selected provider.
- Apply the database update.
Example:
dotnet ef migrations add InitialCreate_PostgreSQL
dotnet ef database update
Database Scripts
The /database folder contains provider-specific SQL scripts.
database/
+-- sqlite/
| +-- schema.sql
| +-- seed.sql
+-- sqlserver/
| +-- schema.sql
| +-- seed.sql
+-- postgresql/
+-- schema.sql
+-- seed.sql
These scripts are optional and can be used for manual database setup or review. The recommended setup method is EF Core migrations:
dotnet ef migrations add InitialCreate
dotnet ef database update
Generate a SQL script from migrations:
dotnet ef migrations script -o database/generated-script.sql
SQL syntax differs between SQLite, SQL Server, and PostgreSQL, so scripts are separated by provider.
Authentication and Authorization
AspNetRestKit uses JWT Bearer authentication with refresh token support.
Roles
| Role | Description |
|---|---|
Admin |
Can create, update, delete, and manage protected resources |
User |
Can access authenticated user endpoints |
Auth Flow
- Register a user.
- Login with credentials.
- Copy the access token.
- Click Authorize in Swagger.
- Enter the token as
Bearer YOUR_TOKEN. - Call protected endpoints.
Authorization Rules
| Resource | Access |
|---|---|
| Auth register/login/refresh token | Public |
| Product and Category GET endpoints | Public |
| Product and Category write endpoints | Admin |
| Audit logs | Admin |
| Current user endpoint | Authenticated user |
| Refresh token revoke | Authenticated user |
API Endpoints
Auth
| Method | Endpoint | Access | Description |
|---|---|---|---|
| POST | /api/v1/auth/register |
Public | Register user |
| POST | /api/v1/auth/login |
Public | Login and receive token |
| POST | /api/v1/auth/refresh-token |
Public | Refresh access token |
| POST | /api/v1/auth/revoke-token |
Authenticated | Revoke refresh token |
| GET | /api/v1/auth/me |
Authenticated | Get current user |
Products
| Method | Endpoint | Access | Description |
|---|---|---|---|
| GET | /api/v1/products |
Public | Get paged, filtered, and sorted products |
| GET | /api/v1/products/{id} |
Public | Get product by ID |
| GET | /api/v1/products/by-category/{categoryId} |
Public | Get products by category |
| POST | /api/v1/products |
Admin | Create product |
| PUT | /api/v1/products/{id} |
Admin | Update product |
| PATCH | /api/v1/products/{id}/status |
Admin | Change product status |
| DELETE | /api/v1/products/{id} |
Admin | Soft delete product |
Product query parameters:
search, categoryId, minPrice, maxPrice, isActive, pageNumber, pageSize, sortBy, sortDirection
Categories
| Method | Endpoint | Access | Description |
|---|---|---|---|
| GET | /api/v1/categories |
Public | Get paged, filtered, and sorted categories |
| GET | /api/v1/categories/{id} |
Public | Get category by ID |
| POST | /api/v1/categories |
Admin | Create category |
| PUT | /api/v1/categories/{id} |
Admin | Update category |
| PATCH | /api/v1/categories/{id}/status |
Admin | Change category status |
| DELETE | /api/v1/categories/{id} |
Admin | Soft delete category |
Category query parameters:
search, isActive, pageNumber, pageSize, sortBy, sortDirection
Audit Logs
| Method | Endpoint | Access | Description |
|---|---|---|---|
| GET | /api/v1/audit-logs |
Admin | Get paged audit logs |
System
| Method | Endpoint | Access | Description |
|---|---|---|---|
| GET | / |
Public | API status |
| GET | /health |
Public | Health check |
Example Requests
Login
POST /api/v1/auth/login
Content-Type: application/json
{
"email": "[email protected]",
"password": "ChangeThisPassword123!"
}
Get Products with Pagination, Filtering, and Sorting
GET /api/v1/products?search=mouse&minPrice=10&maxPrice=100&pageNumber=1&pageSize=10&sortBy=price&sortDirection=asc
Create Product
POST /api/v1/products
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
{
"name": "Wireless Mouse",
"description": "Ergonomic wireless mouse",
"price": 29.99,
"stockQuantity": 50,
"sku": "ELEC-MOUSE-001",
"categoryId": "REPLACE_WITH_CATEGORY_ID"
}
CI/CD
This repository includes a GitHub Actions workflow:
.github/workflows/dotnet-ci.yml
The pipeline runs on push and pull requests to main.
It performs:
- Restore
- Build
- Vulnerable package check
Logging and Audit
AspNetRestKit uses Serilog for structured logging.
Logs are written to:
logs/aspnetrestkit-.log
Log files are ignored by Git.
Audit logging records important operations such as:
- User registration
- User login
- Product create/update/delete/status changes
- Category create/update/delete/status changes
- Refresh token revoke
Audit logs are available for Admin users through:
GET /api/v1/audit-logs
Security Notes
Before using this project in production:
- Replace the default JWT secret.
- Store secrets using environment variables, user secrets, or a secret manager.
- Restrict CORS origins.
- Protect or disable Swagger.
- Use HTTPS.
- Use a production database configuration.
- Review rate limiting settings.
- Do not commit real database passwords.
- Do not commit
.db,.mdf,.ldf,.env, log, or secret files. - Run dependency vulnerability checks regularly.
Check vulnerable packages:
dotnet list package --vulnerable
Useful Commands
| Command | Description |
|---|---|
dotnet restore |
Restore NuGet packages |
dotnet build |
Build the solution |
dotnet run |
Run the API |
dotnet format |
Format the code |
dotnet ef migrations add InitialCreate |
Create EF Core migration |
dotnet ef database update |
Apply database migration |
dotnet ef migrations script -o database/generated-script.sql |
Generate SQL script |
dotnet list package --vulnerable |
Check vulnerable packages |
dotnet dev-certs https --trust |
Trust local HTTPS certificate |
Contributing
Contributions are welcome.
To contribute:
- Fork the repository.
- Create a feature branch.
- Make your changes.
- Run
dotnet build. - Open a pull request.
Please keep the code clean, documented where necessary, and consistent with the existing structure.
License
This project is licensed under the GNU General Public License v3.0.
See the LICENSE file for details.