Required query string parameter in ASP.NET Core
You can consider using the model binding feature of the framework
According to documentation here: Customize model binding behavior with attributes
MVC contains several attributes that you can use to direct its default model binding behavior to a different source. For example, you can specify whether binding is required for a property, or if it should never happen at all by using the
[BindRequired]
or[BindNever]
attributes.
So I suggest you add a BindRequiredAttribute
to the model property.
public class QueryParameters
{
[BindRequired]
public int A { get; set; }
public int B { get; set; }
}
From there the framework should be able to handle the binding and updating model state so that you can check the state of the model in the action
[Route("api/[controller]")]
public class ValuesController : Controller
{
// GET api/values
[HttpGet]
public IActionResult Get([FromQuery]QueryParameters parameters)
{
if (ModelState.IsValid)
{
return Ok(new [] { parameters.A.ToString(), parameters.B.ToString() });
}
return BadRequest();
}
}
The other option would be to create a custom model binder that would fault the action if the required query string is not present.
Reference: Custom Model Binding
In ASP.NET Core 2.1 and above you can use top level parameters validation. You can put attributes on parameters
[HttpGet]
public IActionResult GetDices([BindRequired, Range(1, 6)]int number)
{
if (!ModelState.IsValid)
{
return BadRequest("Invalid number");
}
return Ok(_diceRepo.GetDices(number));
}
More about this https://programmingcsharp.com/asp-net-parameter-validation/#Top-level_node_validation
Let the framework do the work for you. Here is one solution, as it appears there are a number of ways to accomplish the same thing in ASP.NET Core. But this is what works for me and is quite simple. It seems to be a combination of some of the answers already given.
public class QueryParameters
{
[Required]
public int A { get; set; }
public int B { get; set; }
}
[Route("api/[controller]")]
public class ValuesController : Controller
{
// GET api/values
// [HttpGet] isn't needed as it is the default method, but ok to leave in
// QueryParameters is injected here, the framework takes what is in your query string and does its best to match any parameters the action is looking for. In the case of QueryParameters, you have A and B properties, so those get matched up with the a and b query string parameters
public IEnumerable<string> Get(QueryParameters parameters)
{
if (!ModelState.IsValid)
{
return BadRequest(); // or whatever you want to do
}
return new [] { parameters.a.ToString(), parameters.b.ToString() };
}
}