A sample Blog Engine API built with .NET 9.0 demonstrating Clean Architecture principles, RESTful API design, and modern .NET development practices.
This project follows Clean Architecture principles with clear separation of concerns:
βββββββββββββββββββββββββββββββββββββββββββββββ
β Presentation Layer (API) β
β BlogEngine.API β
β - Controllers β
β - Startup Configuration β
β - Swagger/OpenAPI β
ββββββββββββββββββββ¬βββββββββββββββββββββββββββ
β
ββββββββββββββββββββ΄βββββββββββββββββββββββββββ
β Application Layer β
β BlogEngine.Services β
β - Business Logic β
β - Service Interfaces & Implementations β
ββββββββββββββββββββ¬βββββββββββββββββββββββββββ
β
ββββββββββββββββββββ΄βββββββββββββββββββββββββββ
β Infrastructure Layer β
β BlogEngine.DataRepositories β
β - Repository Pattern β
β - Data Access Logic β
ββββββββββββββββββββ¬βββββββββββββββββββββββββββ
β
ββββββββββββββββββββ΄βββββββββββββββββββββββββββ
β Domain Layer β
β BlogEngine.DataModels β
β - Entities (User, Post, Comment) β
β - DbContext β
β - Database Migrations β
βββββββββββββββββββββββββββββββββββββββββββββββ
Supporting Projects:
βββ BlogEngine.ViewModels - DTOs
βββ BlogEngine.Utils - Utilities
- API Layer (
BlogEngine.API): Entry point, HTTP concerns, dependency injection configuration - Service Layer (
BlogEngine.Services): Business logic, orchestration, application services - Repository Layer (
BlogEngine.DataRepositories): Data access abstraction, CRUD operations - Domain Layer (
BlogEngine.DataModels): Core entities, database context, migrations - ViewModels (
BlogEngine.ViewModels): Data Transfer Objects (DTOs) - Utils (
BlogEngine.Utils): Shared utilities and helpers
- π JWT Authentication - Secure token-based authentication
- π Blog Post Management - Create, read, update, delete blog posts
- π¬ Comment System - Nested comments with parent-child relationships
- π€ User Management - User registration and profile management
- π Swagger/OpenAPI - Interactive API documentation
- ποΈ SQLite Database - Lightweight, zero-configuration database
- π EF Core Migrations - Version-controlled database schema
- ποΈ Clean Architecture - Maintainable and testable code structure
- π Security - Password encryption, JWT tokens, secure endpoints
- .NET 9.0 SDK or later
- SQL Server (or use Docker Compose - see below)
- Git
The easiest way to get started is using Docker Compose, which includes SQL Server:
git clone https://github.com/azlogs/DotnetCoreDemo.git
cd DotnetCoreDemo/DemoDotnetCore
docker-compose up -dThis will:
- Start SQL Server 2022 in a container
- Wait for SQL Server to be ready
- Start the Blog Engine API
- Create the database automatically
Access the API:
- HTTP:
http://localhost:5000 - HTTPS:
http://localhost:5001 - Swagger:
http://localhost:5000/swagger
To stop:
docker-compose downTo stop and remove database:
docker-compose down -vIf you have SQL Server installed locally:
-
Clone the repository
git clone https://github.com/azlogs/DotnetCoreDemo.git cd DotnetCoreDemo/DemoDotnetCore -
Update connection string
Edit
BlogEngine/appsettings.json:"ConnectionStrings": { "BlogEngineDatabase": "Server=localhost,1433;Database=BlogEngineDatabase;User Id=sa;Password=YourPassword;TrustServerCertificate=True" }
-
Restore dependencies
dotnet restore
-
Apply database migrations
cd BlogEngine.DataModels dotnet ef database update cd ..
-
Run the application
cd BlogEngine dotnet run -
Access the application
Navigate to:
https://localhost:5001/swaggerorhttp://localhost:5000/swaggerThe API is now running and you can test all endpoints through the Swagger interface!
Copy appsettings.Example.json to appsettings.json and update the values:
{
"SecuritySetting": {
"SecrectKey": "YOUR-SECRET-KEY-HERE-MINIMUM-32-CHARACTERS-LONG",
"PasswordSalt": "YOUR-PASSWORD-SALT-HERE-GUID-FORMAT"
},
"ConnectionStrings": {
"BlogEngineDatabase": "Server=localhost,1433;Database=BlogEngineDatabase;User Id=sa;Password=YOUR-STRONG-PASSWORD;TrustServerCertificate=True"
}
}Security Settings:
SecrectKey: Used for JWT token signing (min 32 characters)PasswordSalt: Salt for password hashing (use a GUID)
Database:
- SQL Server connection string
- Default uses port 1433
- Database
BlogEngineDatabaseauto-creates on first run
DemoDotnetCore/
βββ BlogEngine/ # API Project (Presentation)
β βββ Controllers/ # API Controllers
β βββ Options/ # Configuration options
β βββ Startup.cs # App configuration
β βββ Program.cs # Entry point
β βββ appsettings.json # Configuration
β
βββ BlogEngine.Services/ # Application Services
β βββ Interfaces/ # Service contracts
β βββ Implements/ # Service implementations
β
βββ BlogEngine.DataRepositories/ # Data Access Layer
β βββ Interfaces/ # Repository contracts
β βββ Implements/ # Repository implementations
β
βββ BlogEngine.DataModels/ # Domain Models
β βββ Models/ # Entities & DbContext
β βββ Migrations/ # EF Core Migrations
β
βββ BlogEngine.ViewModels/ # DTOs
β βββ UserViewModels/
β βββ PostViewModels/
β βββ CommentViewModels/
β
βββ BlogEngine.Utils/ # Utilities
βββ StringCipher.cs # Encryption utilities
This project uses SQL Server as the database.
- User - User accounts and profiles
- Post - Blog posts with title, content, tags
- Comment - Comments on posts (supports nesting)
- Role - User roles for RBAC
- UserRole - Many-to-many relationship between users and roles
- User β Posts (1:many)
- User β Comments (1:many)
- Post β Comments (1:many)
- Comment β Comment (self-referencing for nested comments)
This API uses JWT (JSON Web Tokens) for authentication.
- Register/Login to obtain a JWT token
- Include the token in subsequent requests:
Authorization: Bearer <your-token> - Swagger UI has built-in JWT authentication support
dotnet builddotnet testcd BlogEngine.DataModels
dotnet ef migrations add <MigrationName>cd BlogEngine.DataModels
dotnet ef database updatecd BlogEngine.DataModels
dotnet ef database update <PreviousMigrationName>POST /api/users/register- Register a new userPOST /api/users/login- Login and get JWT tokenGET /api/users/{id}- Get user by IDPUT /api/users/{id}- Update userDELETE /api/users/{id}- Delete user
GET /api/posts- Get all postsGET /api/posts/{id}- Get post by IDPOST /api/posts- Create new post (requires auth)PUT /api/posts/{id}- Update post (requires auth)DELETE /api/posts/{id}- Delete post (requires auth)
GET /api/comments/post/{postId}- Get comments for a postPOST /api/comments- Create comment (requires auth)PUT /api/comments/{id}- Update comment (requires auth)DELETE /api/comments/{id}- Delete comment (requires auth)
For detailed request/response schemas, see the Swagger documentation at /swagger
- Start the application
- Navigate to
https://localhost:5001/swagger - Click "Authorize" and enter your JWT token
- Test endpoints directly from the browser
- Update
appsettings.jsonwith production values - Use strong, unique
SecrectKeyandPasswordSalt - Consider using environment variables for secrets
- Review and harden security settings
- Set up proper logging and monitoring
- Configure HTTPS/SSL certificates
- Set up database backups
- Review and optimize connection strings
The project includes Docker support with SQL Server for easy containerized deployment.
Quick Start with Docker Compose:
# Navigate to the DemoDotnetCore directory
cd DemoDotnetCore
# Update environment variables in docker-compose.yml
# IMPORTANT: Change the default security keys and SQL Server password!
# Build and run (includes SQL Server 2022)
docker-compose up -d
# View logs
docker-compose logs -f
# Stop containers
docker-compose down
# Stop and remove database volume
docker-compose down -vWhat's Included:
- SQL Server 2022 Developer Edition (free)
- Blog Engine API
- Automatic database initialization
- Health checks to ensure SQL Server is ready
The API will be available at:
- HTTP:
http://localhost:5000 - HTTPS:
http://localhost:5001 - Swagger:
http://localhost:5000/swagger - SQL Server:
localhost:1433
Build Docker Image Manually:
cd DemoDotnetCore
docker build -t blogengine-api .
docker run -p 5000:8080 -p 5001:8081 blogengine-apiImportant Notes:
- SQL Server data is persisted in a Docker volume
- Default password is
YourStrong@Passw0rd- change this for production! - Update security keys in
docker-compose.ymlbefore deployment - For production, use environment variables or secrets management
This project has been upgraded from .NET Core 3.1 to .NET 9.0 with the following improvements:
- β Updated to .NET 9.0 (latest version)
- β Uses SQL Server with Docker Compose for easy setup
- β Added Entity Framework Core migrations
- β Updated all NuGet packages to latest versions
- β Fixed security vulnerabilities
- β Added nullable reference types support
- β Improved Clean Architecture implementation
- β Added Role-Based Access Control (RBAC)
- β Added comprehensive documentation
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is provided as-is for educational and demonstration purposes.
- Ensure you have .NET 9.0 SDK installed:
dotnet --version - Run
dotnet restoreto restore packages
- Ensure SQL Server is running (check
docker-compose psif using Docker) - Check connection string in
appsettings.json - Verify SQL Server is accepting connections on port 1433
- For Docker: ensure health check passes with
docker-compose logs sqlserver
- Ensure
SecrectKeyis at least 32 characters - Check that Authorization header includes "Bearer " prefix
- Default ports are 5000 (HTTP) and 5001 (HTTPS)
- Change ports in
Properties/launchSettings.jsonif needed
For issues, questions, or contributions, please open an issue on GitHub.
Built with β€οΈ using .NET 9.0 and Clean Architecture principles