Action methods can receive parameters that we can pass from the HTTP request (from different sources).
For example, the values can come from the URL, query parameters, or the request body.
To convert the request data into parameters, ASP.NET uses a process called model binding, which does all the work without us having to worry about it.
- Identify the available sources (query string, route data, body)
- Convert the data to the required type
- Assign the values to the parameters
This assignment is automatic, which simplifies data handling and prevents us from having to write repetitive code and the possibility of making errors.
Parameter Types
As we mentioned, ASP.NET can convert to parameters data received from different sources of the HTTP request.
Type | Recommended Use | Example | ASP.NET Core Attribute |
---|---|---|---|
Route | Unique IDs, specific resources | /api/products/5 | [FromRoute] |
Query | Filters, pagination, sorting | /api/products?category=tech&page=2 | [FromQuery] |
Body | Creation/update (JSON/XML) | POST /api/products + JSON | [FromBody] |
Headers | Authentication, metadata | Authorization: Bearer xyz | [FromHeader] |
Forms | File uploads or form data | Content-Type: multipart/form-data | [FromForm] |
Let’s look at each of them in detail 👇,
Route Parameters
Route parameters are part of the URL itself, making them ideal for identifying unique resources, such as a user or a product.
For example, in /products/5
, the 5
is a route parameter that likely represents an ID.
In ASP.NET, we define these parameters directly in the route template:
[HttpGet("products/{id}")]
public IActionResult GetProduct(int id)
{
var product = _productService.GetById(id);
return Ok(product);
}
The marker {id}
in the route indicates that we expect a numeric value, which ASP.NET automatically converts to the int
type of the method parameter.
When to use route parameters
- Unique identifiers (like database IDs).
- Required data for the operation.
- Hierarchical structures (e.g.,
/departments/{deptId}/employees/{empId}
).
Do not use route parameters for optional data or complex filters, as they clutter the URL and make it hard to read.
Query Parameters
Query parameters appear after the ?
in the URL and are ideal for optional data, such as filters, pagination, or sorting. For example: /products?category=electronics&page=2
.
In ASP.NET, these parameters are defined as method arguments:
[HttpGet("products")]
public IActionResult GetProducts(
[FromQuery] string category,
[FromQuery] int page = 1)
{
var filteredProducts = _productService.GetByCategory(category, page);
return Ok(filteredProducts);
}
The attribute [FromQuery]
is optional, but it helps to clarify intent. Parameters can have default values (like page = 1
).
Best practices with query parameters
- Use descriptive names (
category
instead ofcat
). - Avoid complex structures (use the body for that).
- Consider pagination (
page
,pageSize
) in endpoints that return collections.
Body Parameters
The request body is primarily used in POST
, PUT
, and PATCH
operations to send structured data, such as a JSON object. For example, when creating a new product:
[HttpPost("products")]
public IActionResult CreateProduct([FromBody] ProductDto productDto)
{
var createdProduct = _productService.Create(productDto);
return CreatedAtAction(nameof(GetProduct), new { id = createdProduct.Id }, createdProduct);
}
The attribute [FromBody]
indicates that ASP.NET should deserialize the received JSON into a ProductDto
object.
Key rules for the body
- Avoid sending IDs in the body for update operations (better use routes).
Form Parameters
Form parameters are used to receive data sent from HTML forms. This data is sent in the request body and can be bound to action parameters.
[HttpPost("products/create")]
public IActionResult Create([FromForm] Product product)
{
// Logic to create a new product
CreateProduct(product);
return RedirectToAction("Index");
}
Header Parameters*
Header parameters are extracted from HTTP headers. For this, the [FromHeader]
attribute is used.
[HttpGet("products")]
public IActionResult List([FromHeader(Name = "Accept-Language")] string language)
{
// Logic to list products according to the language
var products = ListProductsByLanguage(language);
return View(products);
}