ASP.NET Core Web API

Build modern, HTTP-based services with ASP.NET Core.

Introduction to ASP.NET Core Web API

ASP.NET Core Web API is a framework for building web services on the .NET platform. It enables you to develop lightweight, HTTP-based services that can be consumed by a wide range of clients, including web browsers, mobile devices, and other server applications.

Leveraging the power and performance of ASP.NET Core, Web API provides a robust and flexible foundation for creating RESTful services. It integrates seamlessly with other ASP.NET Core features like dependency injection, middleware, and configuration.

Key Features

  • RESTful Design: Encourages the creation of services that adhere to REST principles, using standard HTTP methods (GET, POST, PUT, DELETE) and resources.
  • Cross-Platform: Runs on Windows, macOS, and Linux.
  • High Performance: Built on the high-performance Kestrel web server.
  • Built-in Dependency Injection: First-class support for dependency injection simplifies code organization and testability.
  • Configuration: Flexible configuration system to manage application settings.
  • Routing: Powerful routing mechanisms to map incoming requests to specific actions.
  • Model Binding & Validation: Automatic model binding from request data and built-in validation support.
  • Data Formatting: Support for various data formats like JSON and XML through content negotiation.
  • Authentication & Authorization: Comprehensive security features.
  • OpenAPI Support: Integration with OpenAPI (Swagger) for API documentation and interactive exploration.

Getting Started

To start building your first Web API with ASP.NET Core, ensure you have the .NET SDK installed. You can create a new Web API project using the .NET CLI:

dotnet new webapi -o MyWebApiProject
cd MyWebApiProject
dotnet run

This command creates a new directory named MyWebApiProject, sets up a basic Web API project with sample controllers, and then runs the application. The default template often includes a WeatherForecastController.

Controllers

Controllers are the heart of your Web API. They handle incoming requests and return HTTP responses. Controllers are typically C# classes that inherit from ControllerBase.

Attributes are used to define routing and HTTP methods:

using Microsoft.AspNetCore.Mvc;

namespace MyWebApiProject.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class GreetingController : ControllerBase
    {
        [HttpGet]
        public IActionResult GetGreeting()
        {
            return Ok("Hello, Web API!");
        }

        [HttpGet("{name}")]
        public IActionResult GetGreetingByName(string name)
        {
            return Ok($"Hello, {name}!");
        }
    }
}
The [ApiController] attribute enables API-specific behaviors like automatic model validation and HTTP API conventions.

Routing

Routing determines how incoming HTTP requests are mapped to controller actions. ASP.NET Core Web API uses a convention-based and attribute-based routing system.

Route Templates:

  • [Route("api/[controller]")]: This is a common convention. [controller] is a placeholder that gets replaced by the controller's name (e.g., Greeting for GreetingController). The api/ prefix is also common.
  • [HttpGet], [HttpPost], [HttpPut], [HttpDelete]: These route templates specify the HTTP method for an action.
  • [HttpGet("custom")]: Defines a specific route template for an action.
  • Route parameters like {id} can be used to capture values from the URL.

Model Binding

Model binding is the process of taking incoming request data (from the request body, route, query string, form, etc.) and creating a .NET object instance to pass to your controller action.

By default, ASP.NET Core tries to bind parameters from various sources:

  • Route values: Parameters matching route template placeholders (e.g., {id}).
  • Query string values: Parameters matching ?key=value pairs.
  • Form values: Data from HTML forms.
  • JSON/XML body: The request body for complex types.

You can explicitly specify the source using attributes:

  • [FromRoute]
  • [FromQuery]
  • [FromBody]
  • [FromForm]
  • [FromServices] (for dependency-injected services)
[HttpPost]
public IActionResult CreateProduct([FromBody] Product newProduct)
{
    // ... save newProduct
    return CreatedAtAction(nameof(GetProduct), new { id = newProduct.Id }, newProduct);
}

Data Formatting

Web APIs typically exchange data in formats like JSON or XML. ASP.NET Core Web API uses built-in formatters to serialize and deserialize data.

By default, JSON is preferred. You can add support for other formats by including the relevant NuGet packages and configuring the services in Startup.cs (or Program.cs in .NET 6+).

Content Negotiation

Content negotiation allows the client and server to agree on the best data format for the request and response. Clients can indicate their preferred format using the Accept HTTP header, and the server can specify the response format using the Content-Type header.

ASP.NET Core's media formatters handle this automatically.

Action Results

Controller actions should return results that represent the HTTP response. ASP.NET Core provides a rich set of IActionResult implementations:

  • Ok(): Returns an HTTP 200 OK response.
  • NotFound(): Returns an HTTP 404 Not Found response.
  • BadRequest(): Returns an HTTP 400 Bad Request response.
  • Created(uri, content): Returns an HTTP 201 Created response.
  • NoContent(): Returns an HTTP 204 No Content response.
  • Redirect(url): Returns an HTTP 302 Found response.
  • StatusCode(code): Returns a response with a specified HTTP status code.

Dependency Injection

ASP.NET Core has built-in support for dependency injection (DI), which is crucial for building loosely coupled and testable applications. You register your services in the DI container and then inject them into your controllers.

// Startup.cs (or Program.cs in .NET 6+)
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddScoped(); // Register a scoped service
}

// Controller
public class MyController : ControllerBase
{
    private readonly IMyService _myService;

    public MyController(IMyService myService)
    {
        _myService = myService;
    }

    [HttpGet]
    public IActionResult GetData()
    {
        var data = _myService.GetData();
        return Ok(data);
    }
}

Authentication & Authorization

Securing your Web API is paramount. ASP.NET Core provides flexible middleware and services for handling:

  • Authentication: Verifying the identity of the client (e.g., using JWT tokens, cookies, OAuth).
  • Authorization: Determining if an authenticated client has permission to access a resource (e.g., role-based, policy-based).

Common approaches include:

  • JWT Bearer Tokens: A popular choice for stateless APIs.
  • OAuth 2.0: For delegated authorization.
  • ASP.NET Core Identity: For managing users, passwords, and claims.

You configure authentication and authorization services in Startup.cs (or Program.cs) and apply attributes like [Authorize] to controllers or actions.

Error Handling

Robust error handling is essential for a good API experience. ASP.NET Core offers:

  • Exception Handling Middleware: Catches exceptions thrown by the pipeline and returns appropriate error responses.
  • IActionResult: Use responses like BadRequest, NotFound, InternalServerError.
  • Custom Error Responses: Define specific DTOs for error messages.
  • ModelState Validation: Automatically returns 400 Bad Request if model validation fails (when using [ApiController]).
When using [ApiController], model validation errors automatically return a 400 response with details about the errors.

Testing Web APIs

Writing unit and integration tests for your Web APIs ensures their correctness and reliability.

  • Unit Tests: Test individual components (like services) in isolation, mocking dependencies.
  • Integration Tests: Test the API pipeline by making HTTP requests to a test server and asserting the responses. The Microsoft.AspNetCore.Mvc.Testing NuGet package is invaluable for this.

Performance Optimizations

To ensure your Web API is performant:

  • Asynchronous Programming: Use async and await for I/O-bound operations.
  • Efficient Data Retrieval: Optimize database queries.
  • Caching: Implement response caching where appropriate.
  • Minimize Payload Size: Return only necessary data.
  • HTTP/2: Leverage HTTP/2 for multiplexing and header compression.
  • Kestrel Performance: Configure Kestrel for optimal throughput.

CORS (Cross-Origin Resource Sharing)

CORS is a security feature that restricts web pages from making requests to a different domain than the one that served the web page. ASP.NET Core provides middleware to configure CORS policies.

// Startup.cs (or Program.cs in .NET 6+)
services.AddCors(options =>
{
    options.AddPolicy("AllowMyOrigin",
        builder =>
        {
            builder.WithOrigins("https://www.example.com")
                   .AllowAnyHeader()
                   .AllowAnyMethod();
        });
});

// In Configure:
app.UseCors("AllowMyOrigin");

API Versioning

As your API evolves, you'll need to manage different versions. Common strategies include:

  • URL Path Versioning: e.g., /api/v1/products, /api/v2/products.
  • Query String Versioning: e.g., /api/products?api-version=1.0.
  • Header Versioning: Using custom HTTP headers.

Consider using a dedicated NuGet package like Microsoft.AspNetCore.Mvc.Versioning for comprehensive support.

Tutorial: Create Your First Web API

Follow this step-by-step guide to build a simple API for managing a list of items.

  1. Create a new ASP.NET Core Web API project.
  2. Define a model class (e.g., TodoItem).
  3. Create a controller (e.g., TodoItemsController).
  4. Implement actions for CRUD operations (GET, POST, PUT, DELETE).
  5. Use [ApiController] and attribute routing.
  6. Return appropriate IActionResults.
  7. Run the application and test using tools like Postman or Swagger UI.

Refer to the official ASP.NET Core documentation for detailed steps.