I am using .net core 3+ web api.
Below is how my action looks like below, it uses HTTP GET and I want to pass few fields and one of the fields is a list of integers.
[HttpGet]
[Route("cities")]
public ActionResult<IEnumerable<City>> GetCities([FromQuery] CityQuery query)
{...}
and here is CityQuery
class -
public class CityQuery
{
[FromQuery(Name = "stateids")]
[Required(ErrorMessage = "stateid is missing")]
public string StateIdsStr { get; set; }
public IEnumerable<int> StateList
{
get
{
if (!string.IsNullOrEmpty(StateIdsStr))
{
var output = StateIdsStr.Split(',').Select(id =>
{
int.TryParse(id, out var stateId);
return stateId;
}).ToList();
return output;
}
return new List<int>();
}
}
}
Is there a generic way I can use to accept list of integers as input and not accept string and then parse it?
Or is there a better way to do this? I tried googling but could not find much. Thanks in advance.
3 Answers 3
This can help
[HttpGet]
[Route("cities")]
public ActionResult<IEnumerable<City>> GetCities([FromQuery] int[] stateids)
{
...
}
but the query string will change to https://localhost/api/controller/cities?stateids=1&stateids=2&stateids=3
If you required comma separated query string with integer, you can go for Custom model binder
https://learn.microsoft.com/en-us/aspnet/core/mvc/advanced/custom-model-binding?view=aspnetcore-3.1
Comments
You can use custom model binding, below is a working demo:
Model:
public class CityQuery
{
public List<int> StateList{ get; set; }
}
CustomModelBinder:
public class CustomModelBinder: IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
var values = bindingContext.ValueProvider.GetValue("stateids");
if (values.Length == 0)
{
return Task.CompletedTask;
}
var splitData = values.FirstValue.Split(',');
var result = new CityQuery()
{
StateList = new List<int>()
};
foreach(var id in splitData)
{
result.StateList.Add(int.Parse(id));
}
bindingContext.Result = ModelBindingResult.Success(result);
return Task.CompletedTask;
}
}
Applying ModelBinding Attribute on Action method:
[HttpGet]
[Route("cities")]
public ActionResult GetCities([ModelBinder(BinderType = typeof(CustomModelBinder))] CityQuery query)
{
return View();
}
when the url like /cities?stateids=1,2,3
, the stateids will be filled to StateList
1 Comment
I think you just need to use [FromUri]
before int array parameter :
public ActionResult<IEnumerable<City>> GetCities([FromUri] int[] stateList)
And request would be like :
/cities?stateList=1&stateList=2&stateList=3
3 Comments
stateids
with value 1,2,3
. There's no convention on passing value arrays in query parametersExplore related questions
See similar questions with these tags.
[FromUri] int[] stateList
? How do you want to pass those parameters?ids=1&ids=2&ids=3
and bind them to a singleids
array