Я знаю, что об этом задавали где-то еще, но многие вопросы очень старые и устаревшие, и с тех пор .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?
Для достижения этой цели вы можете реализовать собственный связыватель моделей.
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." });
}
}
Привет, Кент! Сначала я реализовал этот подход, но было решено, что это немного пахнет, поскольку определение чванства показывало строку, а не массив целых чисел. Хотя это может сработать для некоторых людей, поэтому спасибо за документирование альтернативного подхода.