. NET CORE WEB API принимает список целых чисел в качестве входного параметра в HTTP GET API - PullRequest
0 голосов
/ 09 июля 2020

Я использую. net core 3+ web api.

Ниже показано, как выглядит мое действие ниже, оно использует HTTP GET, и я хочу передать несколько полей, и одно из полей представляет собой список целых чисел.

[HttpGet]
[Route("cities")]
public ActionResult<IEnumerable<City>> GetCities([FromQuery] CityQuery query)
{...}

и вот 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>();
        }
    }
}

Есть ли общий c способ, который я могу использовать, чтобы принять список целых чисел в качестве ввода и не принимать строку, а затем проанализировать ее?

Или есть лучший способ сделать это? Я пробовал погуглить, но ничего не нашел. Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 09 июля 2020

Это может помочь

    [HttpGet]
    [Route("cities")]
    public ActionResult<IEnumerable<City>> GetCities([FromQuery] int[] stateids)
    {
        ...
    }

, но строка запроса изменится на https://localhost/api/controller/cities?stateids=1&stateids=2&stateids=3

Если вам нужна строка запроса, разделенная запятыми, с целым числом, вы можете go для пользовательского связывателя модели

https://docs.microsoft.com/en-us/aspnet/core/mvc/advanced/custom-model-binding?view=aspnetcore-3.1

1 голос
/ 10 июля 2020

Вы можете использовать пользовательскую привязку модели, ниже - рабочая демонстрация:

Модель:

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;
    }
}

Применение атрибута ModelBinding к методу действия :

[HttpGet]
[Route("cities")]
public ActionResult GetCities([ModelBinder(BinderType = typeof(CustomModelBinder))] CityQuery query)
{
    return View();
}

когда URL-адрес похож на /cities?stateids=1,2,3, идентификаторы состояния будут заполнены до StateList

0 голосов
/ 09 июля 2020

Я думаю, вам просто нужно использовать [FromUri] перед параметром массива int:

public ActionResult<IEnumerable<City>> GetCities([FromUri] int[] stateList)

И запрос будет примерно таким:

/cities?stateList=1&stateList=2&stateList=3 
...