There are four basic ways to receive parameters in an ASP.NET Core Web API: query strings, path parameters, request body, and request headers. I’ll show examples of these below.
Query string parameters
Let’s say you have two query string keys: name and servings. To get these query string values, add method parameters with names that match the query string key names (name and servings):
[ApiController]
[Route("[controller]")]
public class RecipeController : ControllerBase
{
[HttpGet()]
public Recipe Get(string name, int servings)
{
return new Recipe()
{
Name = name,
Servings = servings
};
}
}
Code language: C# (cs)
Now send a request with query string keys and values:
GET /Recipe?name=pizza&servings=4
Code language: plaintext (plaintext)
The values from the query string are mapped to the method parameters (name, servings), and it returns the following 200 (OK) response:
{
"name": "pizza",
"servings": 4
}
Code language: JSON / JSON with Comments (json)
You can map the query string to a complex type by explicitly adding the [FromQuery] attribute:
[HttpGet()]
public Recipe Get([FromQuery]Recipe recipe)
{
return recipe;
}
Code language: C# (cs)
Path parameters
To add path parameters, configure the route (in the HttpGet attribute) with the parameter names, and then add method parameters with matching names:
[ApiController]
[Route("[controller]")]
public class RecipeController : ControllerBase
{
[HttpGet("{name}/{servings}")]
public Recipe Get(string name, int servings)
{
return new Recipe()
{
Name = name,
Servings = servings
};
}
}
Code language: C# (cs)
Now send a request with the parameter values as part of the path:
GET /Recipe/soup/8
Code language: plaintext (plaintext)
The values from the path are mapped to the method parameters and it returns the following 200 (OK) response:
{
"name": "soup",
"servings": 8
}
Code language: JSON / JSON with Comments (json)
If you want to map path parameters to a complex type (instead of having several simple type parameters), use the [FromRoute] attribute:
[HttpGet("{name}/{servings}")]
public Recipe Get([FromRoute]Recipe recipe)
{
return recipe;
}
Code language: C# (cs)
Request body
When you have multiple parameters, it’s common to encapsulate them in a complex type and get them from the request body. To do that, add the complex type as a method parameter:
[ApiController]
[Route("[controller]")]
public class RecipeController : ControllerBase
{
[HttpPost()]
public IActionResult Post(Recipe recipe)
{
return Ok($"Posted {recipe.Name}");
}
}
Code language: C# (cs)
Now send the request with JSON in the body:
POST /Recipe
Content-Type: application/json
Body:
{
"name": "steak",
"servings": 1
}
Code language: plaintext (plaintext)
The request body JSON is deserialized to a Recipe object (and you can configure how JSON deserialization is handled). The endpoint returns a 200 (OK) response with the following:
Posted steak
Code language: plaintext (plaintext)
Request headers
Sometimes it’s useful to send parameters via request headers. These are often used in addition to other parameters. To get the value of a request header, add a method parameter with the same name as the header, and apply the [FromHeader] attribute to it.
[ApiController]
[Route("[controller]")]
public class RecipeController : ControllerBase
{
[HttpGet("{name}/{servings}")]
public Recipe Get(string name, int servings, [FromHeader]bool includeImageUrl)
{
string imageUrl = null;
if (includeImageUrl)
imageUrl = $"{name}.png";
return new Recipe()
{
Name = name,
Servings = servings,
ImageUrl = imageUrl
};
}
}
Code language: C# (cs)
Now send a request with a request header:
GET /Recipe/cake/20
Headers:
IncludeImageUrl=true
Code language: plaintext (plaintext)
In addition to mapping the path parameters (name and servings), it mapped the request header to the includeImageUrl parameter and returned the following 200 (OK) response:
{
"name": "cake",
"servings": 20,
"imageUrl": "cake.png"
}
Code language: JSON / JSON with Comments (json)
Further reading
This was meant to be an introduction to the basic ways of receiving parameters. For more advanced scenarios, you may want to check these out:
Furthermore, I highly suggest understanding and using model validation attributes to guard against bad input.