Веб-API ASP.NET Core 8: передать массив int в метод контроллера

Я знаю, что об этом задавали где-то еще, но многие вопросы очень старые и устаревшие, и с тех пор .NET немного продвинулся вперед, поэтому я надеюсь, что теперь есть простое решение для этой проблемы, кроме необходимости реализации папка индивидуальной модели...

У меня есть такой метод контроллера веб-API:

[HttpGet("{storeId:int}")]
public async Task<IActionResult> Index(int storeId, int requiredQuantity, [FromQuery] int[] plus)
{
    try
    {
        // lots of incredible things

        return Ok(response);
    }
    catch (Exception ex)
    {
        return StatusCode(500, new { message = "An error occurred while processing your request. Please try again later." });
    }
}

Я могу вызвать это следующим образом:

GET https://localhost:44385/test/test/650?plus=13&plus=4412&plus=4099&requiredQuantity=41

Однако мне нужно иметь возможность вызывать его следующим образом:

GET https://localhost:44385/test/test/650?plus=13,4412,4099&requiredQuantity=41

Возможно ли это близким к нативному способу без необходимости писать полную настраиваемую связку модели или передавать строку и преобразовывать ее в массив int?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Для достижения этой цели вы можете реализовать собственный связыватель моделей.

    public class CommaSeparatedBinder : IModelBinder
    {
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            var stringArray = valueProviderResult.FirstValue?.Split(',')?? Array.Empty<string>();
            int[] intArray = Array.ConvertAll(stringArray, s => int.TryParse(s, out int result) ? result : 0);
            bindingContext.Result = ModelBindingResult.Success(intArray);
            return Task.CompletedTask;
        }
    }

Затем добавьте эту специальную подшивку

public async Task<IActionResult> Index(int storeId, int requiredQuantity, [FromQuery][ModelBinder(typeof(CommaSeparatedBinder))] int[] plus)

Результат теста

Я не уверен в более родном способе, чем использование привязки модели, но вы можете использовать хак. Вы можете использовать атрибут [FromQuery] с простым строковым параметром и обрабатывать встроенное преобразование в своем методе.

    [HttpGet("{storeId:int}")]
    public async Task<IActionResult> Index(int storeId, int requiredQuantity, [FromQuery(Name = "plus")] string plus)
    {
        try
        {
            var plusArray = plus?.Split(',').Select(int.Parse).ToArray() ?? Array.Empty<int>();
            return Ok(plusArray);
        }
        catch (Exception ex)
        {
            return StatusCode(500, new { message = "An error occurred. Please try again later." });
        }
    }

Привет, Кент! Сначала я реализовал этот подход, но было решено, что это немного пахнет, поскольку определение чванства показывало строку, а не массив целых чисел. Хотя это может сработать для некоторых людей, поэтому спасибо за документирование альтернативного подхода.

JsonStatham 05.09.2024 10:17

Другие вопросы по теме