Introduction to .NET Core Web API
.NET Core Web API is a framework for building HTTP services that can be used by a broad range of clients, including browsers and mobile devices. It's part of the .NET ecosystem and provides a powerful, flexible, and cross-platform way to develop modern web services.
Key benefits include:
- Cross-platform compatibility (Windows, macOS, Linux).
- High performance and scalability.
- Modern tooling and development experience.
- Extensive ecosystem and community support.
Getting Started with .NET Core Web API
To begin, you'll need the .NET SDK installed. You can download it from the official .NET website. Once installed, you can create a new Web API project using the .NET CLI:
dotnet new webapi -n MyAwesomeApi
This command creates a new directory named MyAwesomeApi containing a basic Web API project structure.
To run your application:
cd MyAwesomeApidotnet run
By default, the API will be listening on a local port, usually https://localhost:5001 and http://localhost:5000.
Creating Controllers
Controllers are the heart of your Web API. They handle incoming HTTP requests and return responses. A typical controller inherits from ControllerBase and uses attributes to define actions and their corresponding HTTP methods.
Here's an example of a simple controller:
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
[HttpGet]
public IActionResult GetAllProducts()
{
var products = new[]
{
new { Id = 1, Name = "Laptop" },
new { Id = 2, Name = "Keyboard" }
};
return Ok(products);
}
[HttpGet("{id}")]
public IActionResult GetProductById(int id)
{
if (id == 1)
{
return Ok(new { Id = 1, Name = "Laptop" });
}
return NotFound();
}
}
The [ApiController] attribute enables several API-specific behaviors, such as automatic model validation. The [Route("api/[controller]")] attribute defines the base URL for this controller. [HttpGet] indicates that the method handles GET requests.
Routing
Routing in .NET Core Web API maps incoming HTTP requests to specific controller actions. By default, it uses convention-based routing, but attribute routing (as shown in the controller example) offers more flexibility.
You can define explicit routes with parameters:
[HttpGet("category/{categoryName}")]
public IActionResult GetProductsByCategory(string categoryName)
{
// ... logic to get products by category
return Ok($$"Products in category: {categoryName}");
}
Model Binding and Validation
Model binding is the process of taking incoming request data (like form data, route data, or query string parameters) and binding it to a .NET object. Model validation ensures that the bound data meets certain criteria.
Define a model class:
public class Product
{
public int Id { get; set; }
[Required]
[StringLength(100)]
public string Name { get; set; }
[Range(0.01, 1000.00)]
public decimal Price { get; set; }
}
Use this model in a controller action:
[HttpPost]
public IActionResult CreateProduct(Product product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// ... logic to save the product
return CreatedAtAction(nameof(GetProductById), new { id = product.Id }, product);
}
Dependency Injection (DI)
.NET Core has built-in support for Dependency Injection, which is crucial for building loosely coupled and testable applications.
Register services in Startup.cs (or Program.cs in .NET 6+):
// In Startup.ConfigureServices or Program.cs builder.Services
builder.Services.AddScoped<IProductService, ProductService>();
Inject services into controllers:
public class ProductsController : ControllerBase
{
private readonly IProductService _productService;
public ProductsController(IProductService productService)
{
_productService = productService;
}
[HttpGet]
public IActionResult GetAllProducts()
{
return Ok(_productService.GetAll());
}
}
Data Access with Entity Framework Core (EF Core)
Entity Framework Core is a modern, cross-platform Object-Relational Mapper (ORM) for .NET. It simplifies database interactions.
Install the EF Core package:
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
Define your DbContext and models, then register it:
// In Program.cs
builder.Services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
Inject the DbContext or a repository into your services/controllers to interact with the database.
Authentication and Authorization
Secure your API endpoints using various authentication and authorization mechanisms like JWT tokens, OAuth 2.0, or API keys.
Configure authentication services in Startup.cs (or Program.cs):
// Example for JWT Bearer Authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
// ... other validation parameters
};
});
Apply authorization attributes to controllers or actions:
[Authorize(Roles = "Admin")]
[ApiController]
[Route("api/[controller]")]
public class AdminController : ControllerBase { ... }
Testing Your Web API
Write unit and integration tests to ensure your API behaves as expected. .NET Core provides excellent testing support.
Use testing frameworks like xUnit, NUnit, or MSTest. Create a separate test project and use the Microsoft.AspNetCore.Mvc.Testing library for integration tests.
// Example Integration Test
[Fact]
public async Task Get_Products_ReturnsOkResult()
{
var client = _factory.CreateClient();
var response = await client.GetAsync("/api/products");
response.EnsureSuccessStatusCode(); // Status Code 200-299
// ... assert content
}
Deployment
Deploy your .NET Core Web API to various environments, including IIS, Azure App Service, Docker containers, or Kubernetes.
Use the dotnet publish command to create a self-contained or framework-dependent deployment package.
// Publish for production (framework-dependent)
dotnet publish -c Release -o ./publish