Building a REST API with ASP.NET Core (Complete Step-by-Step Guide)

Introduction

ASP.NET Core makes it simple to build fast, secure, and cross-platform REST APIs. In this guide, we’ll walk through everything you need — from project setup to controller creation, data access, and testing your endpoints — using best practices for modern .NET development.

What You’ll Learn

  • Create a new ASP.NET Core Web API project
  • Understand controllers and routes
  • Use Entity Framework Core for database access
  • Test endpoints using Swagger or Postman
  • Apply dependency injection and best practices

Step 1: Create a New Web API Project

Open a terminal or Visual Studio and run:


dotnet new webapi -n ProductApi
cd ProductApi

This command creates a new API project with built-in Swagger support.

Step 2: Project Structure Overview

You’ll see files like:


Controllers/
Program.cs
appsettings.json
ProductApi.csproj

Program.cs is where your app configuration, routing, and service registration happen.

Step 3: Define a Model

Create a simple Product model inside the Models folder:


namespace ProductApi.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; } = string.Empty;
        public decimal Price { get; set; }
        public string Category { get; set; } = string.Empty;
    }
}

Step 4: Set Up Entity Framework Core

Install EF Core and SQL Server packages:


dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools

Now, create a new AppDbContext inside the Data folder:


using Microsoft.EntityFrameworkCore;
using ProductApi.Models;

namespace ProductApi.Data
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
        public DbSet<Product> Products { get; set; }
    }
}

Step 5: Configure Database in Program.cs


using Microsoft.EntityFrameworkCore;
using ProductApi.Data;

var builder = WebApplication.CreateBuilder(args);

// Register DbContext
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

// Add services
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

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

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

Update your appsettings.json with a connection string:


"ConnectionStrings": {
  "DefaultConnection": "Server=localhost;Database=ProductApiDb;Trusted_Connection=True;TrustServerCertificate=True;"
}

Step 6: Create the Controller

Add a new file ProductsController.cs under the Controllers folder:


using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using ProductApi.Data;
using ProductApi.Models;

namespace ProductApi.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ProductsController : ControllerBase
    {
        private readonly AppDbContext _context;

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

        // GET: api/products
        [HttpGet]
        public async Task<ActionResult<IEnumerable<Product>>> GetProducts()
        {
            return await _context.Products.ToListAsync();
        }

        // GET: api/products/5
        [HttpGet("{id}")]
        public async Task<ActionResult<Product>> GetProduct(int id)
        {
            var product = await _context.Products.FindAsync(id);
            if (product == null)
                return NotFound();

            return product;
        }

        // POST: api/products
        [HttpPost]
        public async Task<ActionResult<Product>> PostProduct(Product product)
        {
            _context.Products.Add(product);
            await _context.SaveChangesAsync();
            return CreatedAtAction(nameof(GetProduct), new { id = product.Id }, product);
        }

        // PUT: api/products/5
        [HttpPut("{id}")]
        public async Task<IActionResult> PutProduct(int id, Product product)
        {
            if (id != product.Id)
                return BadRequest();

            _context.Entry(product).State = EntityState.Modified;
            await _context.SaveChangesAsync();
            return NoContent();
        }

        // DELETE: api/products/5
        [HttpDelete("{id}")]
        public async Task<IActionResult> DeleteProduct(int id)
        {
            var product = await _context.Products.FindAsync(id);
            if (product == null)
                return NotFound();

            _context.Products.Remove(product);
            await _context.SaveChangesAsync();
            return NoContent();
        }
    }
}

Step 7: Run and Test the API

Start the app using:


dotnet run

Open your browser and navigate to:


https://localhost:5001/swagger

You’ll see the Swagger UI — test all endpoints directly from there!

Step 8: Testing with Postman

  • GET: https://localhost:5001/api/products
  • POST: Add JSON body: { "name": "Laptop", "price": 1200, "category": "Electronics" }

Best Practices

  • Use DTOs to separate domain models from API contracts.
  • Implement Repository or Service layers for complex logic.
  • Enable validation using [Required] and [Range] attributes.
  • Use global error handling middleware.
  • Secure your endpoints with JWT authentication.

Conclusion

Congratulations! 🎉 You’ve built a fully functional REST API using ASP.NET Core. You now know how to handle CRUD operations, connect to a database, and test APIs using Swagger. Next steps? Add authentication, improve error handling, and deploy to Azure for production use.

Post Tags:

#aspnet-core #csharp #dotnet #webapi #restapi

Leave a Reply

Your email address will not be published. Required fields are marked *