.NET - Build a REST API for Task Management

.NET - Build a REST API for Task Management

.NET - Build a REST API for Task Management

In this comprehensive tutorial, we will walk you through the process of building a RESTful Task Management API using ASP.NET Core and Entity Framework Core. This guide is suitable for developers who want to build APIs in .NET, create to-do or task-based applications, and implement CRUD operations effectively.

What You Will Learn

  • Setting up a new ASP.NET Core Web API project
  • Creating models and DbContext with Entity Framework Core
  • Implementing CRUD operations (Create, Read, Update, Delete)
  • Adding Data Annotations and Validation
  • Using Dependency Injection and Repository Pattern
  • Testing the API using Postman or Swagger

Technologies Used

  • ASP.NET Core 7.0+
  • Entity Framework Core
  • SQLite or SQL Server
  • C# Language
  • Swagger UI / Postman

Step 1: Create the ASP.NET Core Web API Project

dotnet new webapi -n TaskManagementApi
cd TaskManagementApi

This command scaffolds a new Web API project.

Project Structure

TaskManagementApi/
β”œβ”€β”€ Controllers/
β”‚   └── TasksController.cs
β”œβ”€β”€ Models/
β”‚   └── TaskItem.cs
β”œβ”€β”€ Data/
β”‚   └── AppDbContext.cs
β”œβ”€β”€ Repositories/
β”‚   └── ITaskRepository.cs
β”‚   └── TaskRepository.cs
β”œβ”€β”€ Program.cs
└── appsettings.json

Step 2: Define the TaskItem Model

using System.ComponentModel.DataAnnotations;

namespace TaskManagementApi.Models
{
    public class TaskItem
    {
        public int Id { get; set; }

        [Required]
        [MaxLength(100)]
        public string Title { get; set; }

        public string Description { get; set; }

        public bool IsCompleted { get; set; } = false;

        public DateTime CreatedAt { get; set; } = DateTime.UtcNow;

        public DateTime? DueDate { get; set; }
    }
}

Step 3: Configure EF Core with DbContext

AppDbContext.cs

using Microsoft.EntityFrameworkCore;
using TaskManagementApi.Models;

namespace TaskManagementApi.Data
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions options) : base(options) { }

        public DbSet<TaskItem> TaskItems { get; set; }
    }
}

Step 4: Update appsettings.json

{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=tasks.db"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}

Step 5: Register Services in Program.cs

using Microsoft.EntityFrameworkCore;
using TaskManagementApi.Data;
using TaskManagementApi.Repositories;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlite(builder.Configuration.GetConnectionString("DefaultConnection")));

builder.Services.AddScoped<ITaskRepository, TaskRepository>();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

Step 6: Create Repository Interface and Class

ITaskRepository.cs

using TaskManagementApi.Models;

namespace TaskManagementApi.Repositories
{
    public interface ITaskRepository
    {
        Task<IEnumerable<TaskItem>> GetAllAsync();
        Task<TaskItem> GetByIdAsync(int id);
        Task<TaskItem> AddAsync(TaskItem task);
        Task<TaskItem> UpdateAsync(TaskItem task);
        Task DeleteAsync(int id);
    }
}

TaskRepository.cs

using Microsoft.EntityFrameworkCore;
using TaskManagementApi.Data;
using TaskManagementApi.Models;

namespace TaskManagementApi.Repositories
{
    public class TaskRepository : ITaskRepository
    {
        private readonly AppDbContext _context;

        public TaskRepository(AppDbContext context)
        {
            _context = context;
        }

        public async Task<IEnumerable<TaskItem>> GetAllAsync()
        {
            return await _context.TaskItems.ToListAsync();
        }

        public async Task<TaskItem> GetByIdAsync(int id)
        {
            return await _context.TaskItems.FindAsync(id);
        }

        public async Task<TaskItem> AddAsync(TaskItem task)
        {
            _context.TaskItems.Add(task);
            await _context.SaveChangesAsync();
            return task;
        }

        public async Task<TaskItem> UpdateAsync(TaskItem task)
        {
            _context.TaskItems.Update(task);
            await _context.SaveChangesAsync();
            return task;
        }

        public async Task DeleteAsync(int id)
        {
            var task = await _context.TaskItems.FindAsync(id);
            if (task != null)
            {
                _context.TaskItems.Remove(task);
                await _context.SaveChangesAsync();
            }
        }
    }
}

Step 7: Create the TasksController

using Microsoft.AspNetCore.Mvc;
using TaskManagementApi.Models;
using TaskManagementApi.Repositories;

namespace TaskManagementApi.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class TasksController : ControllerBase
    {
        private readonly ITaskRepository _repo;

        public TasksController(ITaskRepository repo)
        {
            _repo = repo;
        }

        [HttpGet]
        public async Task<ActionResult<IEnumerable<TaskItem>>> GetTasks()
        {
            var tasks = await _repo.GetAllAsync();
            return Ok(tasks);
        }

        [HttpGet("{id}")]
        public async Task<ActionResult<TaskItem>> GetTask(int id)
        {
            var task = await _repo.GetByIdAsync(id);
            if (task == null) return NotFound();
            return Ok(task);
        }

        [HttpPost]
        public async Task<ActionResult<TaskItem>> CreateTask(TaskItem task)
        {
            var created = await _repo.AddAsync(task);
            return CreatedAtAction(nameof(GetTask), new { id = created.Id }, created);
        }

        [HttpPut("{id}")]
        public async Task<ActionResult<TaskItem>> UpdateTask(int id, TaskItem task)
        {
            if (id != task.Id) return BadRequest();
            var updated = await _repo.UpdateAsync(task);
            return Ok(updated);
        }

        [HttpDelete("{id}")]
        public async Task<IActionResult> DeleteTask(int id)
        {
            await _repo.DeleteAsync(id);
            return NoContent();
        }
    }
}

Step 8: Add EF Migrations and Update DB

dotnet tool install --global dotnet-ef
dotnet ef migrations add InitialCreate
dotnet ef database update

Step 9: Test the API with Swagger or Postman

Run the application and visit:

https://localhost:{port}/swagger

Try out the GET, POST, PUT, and DELETE endpoints directly from Swagger UI.

Step 10: Optional Enhancements

  • Add user authentication with JWT
  • Filter tasks by status (e.g., Completed / Pending)
  • Sort tasks by due date
  • Add pagination support


This tutorial walked you through creating a fully functional Task Management REST API using ASP.NET Core and Entity Framework Core. You implemented clean architecture with repository pattern, dependency injection, CRUD operations, and testing via Swagger.

You can extend this project into a complete to-do application with front-end support using Blazor, Angular, or React.


Beginner 5 Hours
.NET - Build a REST API for Task Management

.NET - Build a REST API for Task Management

In this comprehensive tutorial, we will walk you through the process of building a RESTful Task Management API using ASP.NET Core and Entity Framework Core. This guide is suitable for developers who want to build APIs in .NET, create to-do or task-based applications, and implement CRUD operations effectively.

What You Will Learn

  • Setting up a new ASP.NET Core Web API project
  • Creating models and DbContext with Entity Framework Core
  • Implementing CRUD operations (Create, Read, Update, Delete)
  • Adding Data Annotations and Validation
  • Using Dependency Injection and Repository Pattern
  • Testing the API using Postman or Swagger

Technologies Used

  • ASP.NET Core 7.0+
  • Entity Framework Core
  • SQLite or SQL Server
  • C# Language
  • Swagger UI / Postman

Step 1: Create the ASP.NET Core Web API Project

dotnet new webapi -n TaskManagementApi cd TaskManagementApi

This command scaffolds a new Web API project.

Project Structure

TaskManagementApi/ ├── Controllers/ │ └── TasksController.cs ├── Models/ │ └── TaskItem.cs ├── Data/ │ └── AppDbContext.cs ├── Repositories/ │ └── ITaskRepository.cs │ └── TaskRepository.cs ├── Program.cs └── appsettings.json

Step 2: Define the TaskItem Model

using System.ComponentModel.DataAnnotations; namespace TaskManagementApi.Models { public class TaskItem { public int Id { get; set; } [Required] [MaxLength(100)] public string Title { get; set; } public string Description { get; set; } public bool IsCompleted { get; set; } = false; public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTime? DueDate { get; set; } } }

Step 3: Configure EF Core with DbContext

AppDbContext.cs

using Microsoft.EntityFrameworkCore; using TaskManagementApi.Models; namespace TaskManagementApi.Data { public class AppDbContext : DbContext { public AppDbContext(DbContextOptions options) : base(options) { } public DbSet<TaskItem> TaskItems { get; set; } } }

Step 4: Update appsettings.json

{ "ConnectionStrings": { "DefaultConnection": "Data Source=tasks.db" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }

Step 5: Register Services in Program.cs

using Microsoft.EntityFrameworkCore; using TaskManagementApi.Data; using TaskManagementApi.Repositories; var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlite(builder.Configuration.GetConnectionString("DefaultConnection"))); builder.Services.AddScoped<ITaskRepository, TaskRepository>(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();

Step 6: Create Repository Interface and Class

ITaskRepository.cs

using TaskManagementApi.Models; namespace TaskManagementApi.Repositories { public interface ITaskRepository { Task<IEnumerable<TaskItem>> GetAllAsync(); Task<TaskItem> GetByIdAsync(int id); Task<TaskItem> AddAsync(TaskItem task); Task<TaskItem> UpdateAsync(TaskItem task); Task DeleteAsync(int id); } }

TaskRepository.cs

using Microsoft.EntityFrameworkCore; using TaskManagementApi.Data; using TaskManagementApi.Models; namespace TaskManagementApi.Repositories { public class TaskRepository : ITaskRepository { private readonly AppDbContext _context; public TaskRepository(AppDbContext context) { _context = context; } public async Task<IEnumerable<TaskItem>> GetAllAsync() { return await _context.TaskItems.ToListAsync(); } public async Task<TaskItem> GetByIdAsync(int id) { return await _context.TaskItems.FindAsync(id); } public async Task<TaskItem> AddAsync(TaskItem task) { _context.TaskItems.Add(task); await _context.SaveChangesAsync(); return task; } public async Task<TaskItem> UpdateAsync(TaskItem task) { _context.TaskItems.Update(task); await _context.SaveChangesAsync(); return task; } public async Task DeleteAsync(int id) { var task = await _context.TaskItems.FindAsync(id); if (task != null) { _context.TaskItems.Remove(task); await _context.SaveChangesAsync(); } } } }

Step 7: Create the TasksController

using Microsoft.AspNetCore.Mvc; using TaskManagementApi.Models; using TaskManagementApi.Repositories; namespace TaskManagementApi.Controllers { [ApiController] [Route("api/[controller]")] public class TasksController : ControllerBase { private readonly ITaskRepository _repo; public TasksController(ITaskRepository repo) { _repo = repo; } [HttpGet] public async Task<ActionResult<IEnumerable<TaskItem>>> GetTasks() { var tasks = await _repo.GetAllAsync(); return Ok(tasks); } [HttpGet("{id}")] public async Task<ActionResult<TaskItem>> GetTask(int id) { var task = await _repo.GetByIdAsync(id); if (task == null) return NotFound(); return Ok(task); } [HttpPost] public async Task<ActionResult<TaskItem>> CreateTask(TaskItem task) { var created = await _repo.AddAsync(task); return CreatedAtAction(nameof(GetTask), new { id = created.Id }, created); } [HttpPut("{id}")] public async Task<ActionResult<TaskItem>> UpdateTask(int id, TaskItem task) { if (id != task.Id) return BadRequest(); var updated = await _repo.UpdateAsync(task); return Ok(updated); } [HttpDelete("{id}")] public async Task<IActionResult> DeleteTask(int id) { await _repo.DeleteAsync(id); return NoContent(); } } }

Step 8: Add EF Migrations and Update DB

dotnet tool install --global dotnet-ef dotnet ef migrations add InitialCreate dotnet ef database update

Step 9: Test the API with Swagger or Postman

Run the application and visit:

https://localhost:{port}/swagger

Try out the GET, POST, PUT, and DELETE endpoints directly from Swagger UI.

Step 10: Optional Enhancements

  • Add user authentication with JWT
  • Filter tasks by status (e.g., Completed / Pending)
  • Sort tasks by due date
  • Add pagination support


This tutorial walked you through creating a fully functional Task Management REST API using ASP.NET Core and Entity Framework Core. You implemented clean architecture with repository pattern, dependency injection, CRUD operations, and testing via Swagger.

You can extend this project into a complete to-do application with front-end support using Blazor, Angular, or React.


Related Tutorials

Frequently Asked Questions for General

line

Copyrights © 2024 letsupdateskills All rights reserved