Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Core Model Binding from Route and Query String

I would like to perform a GET request such as https://localhost:12345/api/employees/1/calendar/2018/2019?checkHistoricalFlag=true

I have created this method in my controller which works as expected:

[AllowAnonymous]
[HttpGet("/api/employees/{clockNumber:int}/calendar/{yearFrom:int}/{yearTo:int}")]
public IActionResult Get(int clockNumber, int yearFrom, int yearTo, bool checkHistoricalFlag = false)
{
  return Ok();
}

However I would prefer to use the following view model:

public class DetailsQuery
{
  [Required]
  public int? ClockNumber { get; set; }
  [Required]
  public int? YearFrom { get; set; }
  [Required]
  public int? YearTo { get; set; }
  public bool CheckHistoricalFlag { get; set; } = false;
}

This binds the route parameters but ignores "checkHistoricalFlag" from the query string:

[AllowAnonymous]
[HttpGet("/api/employees/{clockNumber:int}/calendar/{yearFrom:int}/{yearTo:int}")]
public IActionResult Get([FromRoute]DetailsQuery query)
{
  return Ok();
}

Removing [FromRoute] results in a 415 "Unsupported Media Type" error.

Is it possible to bind both the route parameters and query string values to a single view model or do I need to specify the query string values separately?

[AllowAnonymous]
[HttpGet("/api/employees/{clockNumber:int}/calendar/{yearFrom:int}/{yearTo:int}")]
public IActionResult Get([FromRoute]DetailsQuery query, bool checkHistoricalFlag = false)
{
  return Ok();
}
like image 605
Newm Avatar asked Sep 16 '25 04:09

Newm


1 Answers

The comment from Imantas pointed me to using [FromQuery] on the view model which now looks like:

public class DetailsQuery
{
  [Required]
  public int? ClockNumber { get; set; }
  [Required]
  public int? YearFrom { get; set; }
  [Required]
  public int? YearTo { get; set; }
  [FromQuery]
  public bool CheckHistoricalFlag { get; set; } = false;
}

The controller method is now:

[AllowAnonymous]
[HttpGet("/api/employees/{clockNumber:int}/calendar/{yearFrom:int}/{yearTo:int}")]
public ActionResult Get([FromRoute]DetailsQuery query)
{
  return Ok();
}

Which works as expected.

Thanks for the pointer Imantas.

like image 59
Newm Avatar answered Sep 18 '25 17:09

Newm