Welcome to this course on Model Binding in Minimal APIs. Previously, we covered how to build Minimal APIs, define complex routes with default/optional parameters, respond with different status codes and error details, and more. In this course, we'll focus on model binding—the process of mapping an HTTP request into POCOs (Plain Old CLR Objects), providing input to the endpoint handlers. By the end of this lesson, you'll understand how to dynamically receive data through various sources such as route parameters, query strings, and headers.
Model binding extracts values from an HTTP request and maps them to .NET objects. These objects are then passed as method parameters to the endpoint handler. Here’s an example illustrating model binding:
C#1app.MapGet("/todo/{id}", (string id) => 2{ 3 return $"Retrieving TODO with id {id}"; 4});
In this case, the id
parameter is automatically bound from the route parameter of the HTTP request. If you navigate to /todo/123
, the API will respond with "Retrieving TODO with id 123".
To effectively utilize model binding, it's crucial to understand what an HTTP request consists of. An HTTP request typically includes:
/todo/123
, 123
is a URL parameter./todos?status=Completed
, status=Completed
is a query parameter.Authorization: Bearer token123
.{ "name": "New Todo", "status": "Pending" }
.sessionId=abc123
.GET /todos
.By understanding these components, you'll be able to extract the necessary data to create effective and dynamic API endpoints.
In Minimal APIs, you can bind data from various sources within an HTTP request:
HttpRequest
and HttpContext
, associated with every request. We will cover this in more detail later in this course.Understanding these binding sources will help you create more versatile and responsive APIs.
Let's start with a simple example of extracting a query parameter. Consider the following code snippet:
C#1app.MapGet("/todos", (string status) => 2{ 3 var todos = new List<TodoItem> 4 { 5 new TodoItem { Id = 1, Status = "Pending", Description = "Buy groceries" }, 6 new TodoItem { Id = 2, Status = "Completed", Description = "Clean the house" }, 7 new TodoItem { Id = 3, Status = "In Progress", Description = "Write a blog post" } 8 }; 9 10 return todos.Where(todo => todo.Status.Equals(status, StringComparison.OrdinalIgnoreCase)); 11});
In this example, the status
query parameter is extracted and used to filter a list of TodoItem
objects. When a GET request is made to /todos?status=Completed
, the endpoint returns to-do items with the "Completed" status.
Now let's look at a more complicated example that extracts header values, query parameters, and URL parameters using attributes:
C#1app.MapGet("/todos/{status}", 2 ([FromRoute] string status, 3 [FromQuery] int page, 4 [FromHeader(Name = "PageSize")] int pageSize) => 5 { 6 var todos = new List<TodoItem> 7 { 8 new TodoItem { Id = 1, Status = "Pending", Description = "Buy groceries" }, 9 new TodoItem { Id = 2, Status = "Completed", Description = "Clean the house" }, 10 new TodoItem { Id = 3, Status = "In Progress", Description = "Write a blog post" } 11 }; 12 13 var filteredTodos = todos.Where(todo => todo.Status.Equals(status, StringComparison.OrdinalIgnoreCase)); 14 var paginatedTodos = filteredTodos.Skip((page - 1) * pageSize).Take(pageSize); 15 return paginatedTodos; 16 } 17);
In this example:
status
is derived from the route using [FromRoute]
.page
number is derived from the query string using [FromQuery]
.pageSize
is derived from the HTTP headers using [FromHeader(Name = "PageSize")]
.This allows for more complex logic and flexibility when handling incoming requests.
In this lesson, we explored the basics of model binding in Minimal APIs, covering the definition and purpose of model binding, the components of an HTTP request that can serve as sources for model binding, various binding sources in Minimal APIs, and provided simple and complex examples demonstrating how to bind query, route, and header parameters. You will now engage in practice exercises to apply these concepts hands-on, helping to solidify your understanding of model binding in Minimal APIs.