A professional, production-ready ASP.NET Core Web API for managing tasks and users, built with Clean Architecture principles.
This project demonstrates modern backend development practices using .NET 9, Entity Framework Core, SQL Server LocalDB, and comprehensive error handling.
Portfolio Project - Built to showcase enterprise-level .NET development skills for job applications
Build a production-style RESTful Web API while applying:
- Clean Architecture with clear layer separation
- Repository Pattern for data access abstraction
- SOLID principles and separation of concerns
- DTO-based API communication for clean data contracts
- FluentValidation for robust input validation
- Global Exception Middleware for centralized error handling
- Async/await throughout the entire application
- Swagger/OpenAPI for comprehensive API documentation
The solution follows Clean Architecture with the following structure:
TaskManagement.sln
- TaskManagement.Api (Presentation / API Layer)
- TaskManagement.Application (Business Logic Layer)
- TaskManagement.Domain (Core Domain Models)
- TaskManagement.Infrastructure (Data Access / EF Core)
- RESTful Controllers (TasksController, UsersController)
- HTTP endpoints with proper status codes
- Global Exception Middleware
- Swagger/OpenAPI documentation
- Request/Response models
- Dependency Injection configuration
- Business logic services (TaskService, UserService)
- Service interfaces (ITaskService, IUserService)
- DTOs (Data Transfer Objects)
- Repository interfaces (ITaskRepository, IUserRepository)
- FluentValidation validators
- Core entities (TaskItem, User)
- Enums (TaskStatus)
- Business rules
- Zero external dependencies - pure domain logic
- EF Core DbContext
- Repository implementations
- Entity configurations
- Database migrations
- Data persistence logic
- Full CRUD operations for Tasks and Users
- Advanced filtering (by status, user, search term, date range)
- FluentValidation for comprehensive input validation
- Global Exception Middleware with structured error responses
- Async/await throughout the entire codebase
- Swagger UI with detailed endpoint documentation
- SQL Server LocalDB integration with EF Core
- Repository Pattern for clean data access
- Clean Architecture with proper layer separation
- Dependency Injection with scoped services
- Entity Framework Core 9.0 with Code First migrations
- Structured logging with ILogger
- XML documentation for Swagger
- ProducesResponseType attributes for all endpoints
- Production/Development environment-specific error handling
| Technology | Version | Purpose |
|---|---|---|
| C# | 13.0 | Primary language |
| .NET | 9.0 | Framework |
| ASP.NET Core | 9.0 | Web API framework |
| Entity Framework Core | 9.0 | ORM for database access |
| SQL Server LocalDB | Latest | Database |
| FluentValidation | 11.11.0 | Input validation |
| Swashbuckle | 7.2.0 | Swagger/OpenAPI documentation |
The project uses Entity Framework Core Code First approach.
Id(int, PK, Identity)Name(nvarchar(100), Required)Email(nvarchar(255), Required, Unique Index)
Id(int, PK, Identity)Title(nvarchar(200), Required)Description(nvarchar(1000))Status(nvarchar, stored as string: "Todo", "InProgress", "Done")UserId(int, FK to Users, Required)CreatedDate(datetime2, Required)
Relationships:
- One User -> Many TaskItems (Cascade Delete)
git clone https://github.com/robbevanhalst-dev/dotnet-aspnetcore-task-api.git
cd dotnet-aspnetcore-task-api- .NET 9 SDK
- Visual Studio 2022 (or VS Code with C# extension)
- SQL Server LocalDB (included with Visual Studio)
dotnet restoreThe migrations are already created. Run:
dotnet ef database update --project src/TaskManagement.Infrastructure --startup-project src/TaskManagement.ApiOr in Package Manager Console (Visual Studio):
Update-Database
In Visual Studio:
- Set
TaskManagement.Apias startup project - Press
F5 - Swagger UI opens automatically at
https://localhost:7291
Via Command Line:
cd src/TaskManagement.Api
dotnet runThen navigate to: https://localhost:7291
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /api/tasks |
Get all tasks | - |
| GET | /api/tasks/{id} |
Get task by ID | - |
| GET | /api/tasks/filter |
Get filtered tasks (status, userId, searchTerm, dates) | - |
| GET | /api/tasks/user/{userId} |
Get tasks by user ID | - |
| POST | /api/tasks |
Create new task | - |
| PUT | /api/tasks/{id} |
Update existing task | - |
| DELETE | /api/tasks/{id} |
Delete task | - |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /api/users |
Get all users | - |
| GET | /api/users/{id} |
Get user by ID | - |
| POST | /api/users |
Create new user | - |
| DELETE | /api/users/{id} |
Delete user | - |
POST /api/users
Content-Type: application/json
{
"name": "John Doe",
"email": "john.doe@example.com"
}POST /api/tasks
Content-Type: application/json
{
"title": "Complete project documentation",
"description": "Write comprehensive API documentation",
"status": 0,
"userId": 1
}Status Values:
0= Todo1= InProgress2= Done
GET /api/tasks/filter?status=1&searchTerm=documentation&userId=1PUT /api/tasks/1
Content-Type: application/json
{
"title": "Updated title",
"description": "Updated description",
"status": 2
}- β Clean Architecture - Clear separation of concerns with 4 distinct layers
- β Repository Pattern - Abstraction over data access for improved testability
- β Service Layer Pattern - Business logic encapsulation
- β Dependency Injection - Loose coupling and adherence to SOLID principles
- β DTO Pattern - Data transfer objects for clean API contracts
- β Async/Await - Non-blocking I/O operations for optimal performance
- β FluentValidation - Declarative validation rules, separated from business logic
- β Global Exception Middleware - Centralized error handling
- β Structured Logging - ILogger with multiple log levels
- β XML Documentation - IntelliSense and Swagger integration
- β Entity Configurations - Fluent API for EF Core mappings
- β Environment-specific settings - Development vs Production configuration
- β SOLID Principles - Applied throughout the entire solution
- β Single Responsibility - Each class has one clear purpose
- β Interface Segregation - Clean contracts between layers
- β Dependency Inversion - Depend on abstractions, not concrete implementations
- β DRY (Don't Repeat Yourself) - Reusable code components
- β Separation of Concerns - Each layer has its own responsibility
- β Code-First Migrations - Database schema managed through C# code
- β Entity Configurations - Fluent API for relationships and constraints
- β Eager Loading - Include() statements for performance optimization
- β Connection String Management - Managed via appsettings.json
The API uses Global Exception Middleware for consistent error responses:
{
"statusCode": 404,
"message": "Task with id '999' was not found",
"details": null,
"timestamp": "2024-02-12T12:30:00.000Z",
"path": "/api/tasks/999"
}{
"statusCode": 400,
"message": "One or more validation errors occurred",
"details": "{\"Title\":[\"Title is required\"],\"Email\":[\"Invalid email format\"]}",
"timestamp": "2024-02-12T12:30:00.000Z",
"path": "/api/tasks"
}- Title: Required, max 200 characters
- Description: Max 1000 characters
- Status: Must be valid enum (0-2)
- UserId: Required, must be > 0
- Title: Required, max 200 characters
- Description: Max 1000 characters
- Status: Must be valid enum (0-2)
- Name: Required, max 100 characters
- Email: Required, valid email format, max 255 characters, unique
Planned enhancements to further professionalize this project:
- Unit Tests - xUnit + Moq for services and repositories
- Integration Tests - Test complete API flows
- Test Coverage - Minimum 80% code coverage
- Authentication & Authorization - JWT tokens with role-based access
- Pagination - Efficient data retrieval for large datasets
- Caching - Redis or In-Memory caching
- Rate Limiting - API abuse prevention
- Docker Support - Containerization with Docker Compose
- CI/CD Pipeline - GitHub Actions for automated testing & deployment
- Health Checks - Endpoint monitoring
- Logging - Structured logging with Serilog
- AutoMapper - Automated DTO mappings
- API Versioning - Backwards compatibility
- Sorting & Advanced Filtering - More query options
- File Uploads - Attachments for tasks
- SignalR - Real-time notifications
- Background Jobs - Hangfire for scheduled tasks
Robbe Vanhalst
Junior .NET Developer - Actively seeking opportunities
π§ Email: robbevanhalst.dev@gmail.com
πΌ LinkedIn: Robbe Vanhalst
π GitHub: @robbevanhalst-dev
π Location: Kortrijk, Belgium
This project was developed as a portfolio piece to demonstrate my .NET development skills during job applications. It showcases professional coding practices, clean architecture, and modern .NET technologies.
Skills Demonstrated:
- β Clean Architecture & SOLID Principles
- β ASP.NET Core 9 Web API Development
- β Entity Framework Core & Database Design
- β Repository Pattern & Dependency Injection
- β RESTful API Design & Best Practices
- β Error Handling & Input Validation
- β API Documentation (Swagger/OpenAPI)
- β Asynchronous Programming (async/await)
Interested in collaboration or have questions about this project?
Feel free to reach out via LinkedIn or email!
β If you find this project useful, please give it a star on GitHub!