While implicit parameter binding provides a convenient way to handle HTTP
request data in Minimal APIs, there are scenarios where more control is needed. Explicit parameter binding allows us to specify exactly how and where parameters should be resolved, providing precision and clarity in handling complex API requirements.
This method involves the use of attributes to ensure the correct data is bound to the handler method parameters. Let’s explore various explicit parameter binding techniques in Minimal APIs by updating some of our existing endpoints.
Let’s start by adding one using
statement at the top of our Program
class:
using Microsoft.AspNetCore.Mvc;
We add the Microsoft.AspNetCore.Mvc
namespace as the attributes we need in this section reside there.
Once this is done, let’s update the endpoint we used while exploring route parameters:
app.MapGet("/hello/{name}", ([FromRoute] string name) => $"Hello, {name}!");
Here, we add the [FromRoute]
attribute to the name parameter, explicitly specifying that it should be resolved from the corresponding route parameter.
Let’s move on to the /search
endpoint used in the query string example:
app.MapGet("/search", ([FromQuery] string? term) => { if (string.IsNullOrEmpty(term)) { return "No search term provided."; } return $"Searching for: {term}"; });
This time, we use the [FromQuery]
attribute. This is useful when we need to indicate that a parameter comes from the query string.
This is especially helpful when the query string name does not directly match the method parameter name for some reason:
app.MapGet("/search", ([FromQuery(Name = "phrase")] string? term) => { if (string.IsNullOrEmpty(term)) { return "No search term provided."; } return $"Searching for: {term}"; });
We set the Name
property of the [FromQuery]
attribute to phrase
. This will bind any parameter used with the query string phrase
to the term
parameter. This means that now we have to use https://localhost:5001/search?phrase=api
instead of https://localhost:5001/search?term=api
as we did earlier when calling this particular endpoint.
We can extract parameters from the request body as well. Let’s go to the /products
endpoint:
app.MapPost("/products", ([FromBody] Product product) => { return Results.Created($"/products/{product.Id}", product); });
We simply add the [FromBody]
attribute to the product parameter. This will try to bind the parameter from the JSON
request body.
There are several other attributes available. We can use the [FromServices]
one, to specify that the parameter will come from the DI container.
The [FromHeader]
attribute comes in handy when we need to use request headers as the source of our parameters. Here, we might have to rely on specifying the header’s Name
property but we already saw how to do that in the [FromQuery]
attribute example.
Finally, ASP.NET Core enables us to bind several special types. Those include HttpContext
, HttpRequest
, HttpResponse
as well as the CancellationToken
instance related to the given request.
We now have the needed knowledge to start building our API in earnest. In the next module, we’ll start by introducing GET
endpoints to our application.