In today’s connected digital environment, the demand for seamless data exchange between applications is higher than ever. For startups, enterprise companies, and product-driven teams, building efficient and scalable APIs is non-negotiable. That’s where a RESTful API with ASP.NET Core, C# comes into play.
This guide walks you through creating a real-world ASP.NET Core Web API using Entity Framework Core, structured around a practical example: a Library Inventory Management System.
Whether you’re modernizing legacy systems or building microservices from scratch, this API architecture lays a robust foundation for your backend services.
Why Choose ASP.NET Core and C# for RESTful APIs?
ASP.NET Core is Microsoft’s open-source, high-performance framework optimized for building cloud-based and enterprise-grade applications.
When combined with the reliability and type safety of C#, it becomes a powerful tool for building RESTful APIs that are secure, scalable, and production-ready.
Use Case: Library Inventory API
Let’s say your organization needs a backend service to manage a library’s books. Here’s what the API needs to support:
- 🔍 List all books
- 📘 Get book details by ID
- ➕ Add new books
- ✏️ Update book information
- ❌ Delete books from the collection
We’ll walk through how to build this RESTful API in C# using ASP.NET Core Web API and Entity Framework Core for database access.
Step 1: Create the ASP.NET Core Web API Project
Open your terminal and run:
bash
CopyEdit
dotnet new webapi -n LibraryApi
cd LibraryApi
This command scaffolds a clean Web API project ready for implementation.
Step 2: Define the Data Model
Create a folder named Models and add Book.cs:
csharp
CopyEdit
namespace LibraryApi.Models
{
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public string ISBN { get; set; }
public int PublicationYear { get; set; }
}
}
This model represents the structure of a book entity in our API.
Step 3: Integrate Entity Framework Core
Install EF Core packages:
bash
CopyEdit
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools
dotnet add package Microsoft.EntityFrameworkCore.Design
Create LibraryDbContext.cs in a Data folder:
csharp
CopyEdit
using LibraryApi.Models;
using Microsoft.EntityFrameworkCore;
namespace LibraryApi.Data
{
public class LibraryDbContext : DbContext
{
public LibraryDbContext(DbContextOptions<LibraryDbContext> options) : base(options) { }
public DbSet<Book> Books { get; set; }
}
}
Step 4: Configure the Database Connection
In appsettings.json, add:
json
CopyEdit
“ConnectionStrings”: {
“DefaultConnection”: “Server=your_server;Database=LibraryDB;User Id=your_user;Password=your_password;TrustServerCertificate=True;”
}
Then update Program.cs:
csharp
CopyEdit
builder.Services.AddDbContext<LibraryDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString(“DefaultConnection”)));
Step 5: Apply Migrations
Generate the database schema:
bash
CopyEdit
dotnet ef migrations add InitialCreate
dotnet ef database update
This creates the Books table in your SQL Server database.
Step 6: Create the Controller
Add a new controller named BooksController.cs inside the Controllers folder:
csharp
CopyEdit
[ApiController]
[Route(“api/[controller]”)]
public class BooksController : ControllerBase
{
private readonly LibraryDbContext _context;
public BooksController(LibraryDbContext context)
{
_context = context;
}
[HttpGet]
public async Task<ActionResult<IEnumerable<Book>>> GetBooks() => await _context.Books.ToListAsync();
[HttpGet(“{id}”)]
public async Task<ActionResult<Book>> GetBook(int id)
{
var book = await _context.Books.FindAsync(id);
return book == null ? NotFound() : book;
}
[HttpPost]
public async Task<ActionResult<Book>> PostBook(Book book)
{
_context.Books.Add(book);
await _context.SaveChangesAsync();
return CreatedAtAction(nameof(GetBook), new { id = book.Id }, book);
}
[HttpPut(“{id}”)]
public async Task<IActionResult> PutBook(int id, Book book)
{
if (id != book.Id) return BadRequest();
_context.Entry(book).State = EntityState.Modified;
try { await _context.SaveChangesAsync(); }
catch (DbUpdateConcurrencyException)
{
if (!_context.Books.Any(e => e.Id == id)) return NotFound();
throw;
}
return NoContent();
}
[HttpDelete(“{id}”)]
public async Task<IActionResult> DeleteBook(int id)
{
var book = await _context.Books.FindAsync(id);
if (book == null) return NotFound();
_context.Books.Remove(book);
await _context.SaveChangesAsync();
return NoContent();
}
}
Step 7: Test the RESTful API
You can interact with your API using:
- Swagger UI (navigate to https://localhost:<port>/swagger)
- Postman (send HTTP requests to test endpoints)
- curl (e.g., curl https://localhost:<port>/api/Books)
Best Practices for Production-Ready C# APIs
To make your C# API development reliable and secure, consider implementing these practices:
Input Validation
Use [Required] and other data annotations in your model to enforce rules.
Global Error Handling
Create middleware to capture and return structured error responses.
Use DTOs
Data Transfer Objects allow you to expose only what’s necessary to clients.
Secure the API
Use JWT authentication or OAuth 2.0 to protect sensitive endpoints.
API Versioning
Support long-term evolution by versioning endpoints (/api/v1/books).
Async Database Access
Always use async/await with EF Core for better scalability.
Logging and Monitoring
Add structured logs using tools like Serilog or Application Insights.
Unit and Integration Testing
Use xUnit, Moq, and TestServer for confidence in deployment.
Conclusion
Developing a RESTful API with ASP.NET Core, C# offers the performance, flexibility, and security needed for real-world software systems.
With Entity Framework Core managing your data access and ASP.NET Core handling HTTP requests efficiently, this approach is ideal for businesses building microservices, mobile backends, or enterprise platforms.
Additional Resources: