Может ли swagger обрабатывать IEnumerable строк в Http-запросах?

#c# #swagger

Вопрос:

Я довольно новичок в веб-разработке и чванстве в целом, поэтому приношу извинения, если вопрос слишком наивен.

Я воспользуюсь Asp.Net Основной шаблон веб-Api в visual studio 2019, чтобы лучше объяснить мою проблему, поэтому, пожалуйста, рассмотрите эту среду в случае, если я пропустил некоторую информацию (или просто попросите недостающую часть, которую я приведу).

Там у нас есть WeatherForecastController класс с простым GET (который я включил в names параметр):

 [HttpGet]
public IEnumerable<WeatherForecast> Get(IEnumerable<string> names)
{
    //...
}
 

Когда я пытаюсь протестировать этот запрос с помощью страницы Swagger, он не распознает name параметр.

Я провел другие тесты, чтобы выяснить, что происходит, и обнаружил следующее:

  1. Swagger действительно работает с IEnumerable, так как он работает довольно хорошо, если параметр имеет тип IEnumerable<IFormFile> (он отображает список загруженных файлов, показывает диалоговое окно выбора файла и т. Д.);
  2. Я попытался инкапсулировать параметры в класс DTO, и, похоже, это нарушает еще больше вещей(даже IEnumerable<IFormFile> , похоже, не работает внутри класса DTO; он работает только в том случае, если передается непосредственно в списке параметров [HttpVerb] метода;
  3. Я пробовал с другими подобными типами, а также ICollection<string> , List<string> , string[] ; ни один из них, похоже, не работает;
  4. Эта же проблема возникает при использовании примитивных типов, таких как bool , int , и т.д. В качестве аргументов типа для IEnumerable<T> ;

Так что же происходит? Должен ли я установить какое-то значение конфигурации, чтобы оно могло работать с коллекциями примитивных типов?

Обновите изображения, показывающие проблему:

... Get(string names, IEnumerable<IFormFile> file) :
введите описание изображения здесь

... Get(IEnumerable<string> names, IFormFile file) :
введите описание изображения здесь

Как вы можете видеть, когда какой-либо параметр в списке параметров имеет значение IEnumerable, пользовательский интерфейс swagger неправильно отображает запрошенные поля, как на втором изображении.

Комментарии:

1. какую строку запроса вы пробовали использовать с этим?

2. @Ctznkane525 проблема не в строке запроса, проблема в использовании пользовательского интерфейса swagger для сборки строки запроса, я обновлю вопрос с помощью экрана печати, показывающего проблему через минуту.

3. @Ctznkane525 только что обновил вопрос с 2 изображениями, показывающими, когда все идет правильно, а когда неправильно.

4. Добавьте атрибут [FromBody] перед параметром массива. Я думаю, что пользовательский интерфейс Swagger неправильно обрабатывает параметры массива в FormData.

5. @AliReza, инкапсулировав его в класс DTO и используя [FromForm] , сделал свое дело, спасибо! Вы хотите включить это в ответ?

Ответ №1:

В вашем случае необходимо указать источники привязки модели. Ваш метод действий должен быть таким:

     [HttpPost("test/names")]
    public IEnumerable<string> PostNames([FromQuery]IEnumerable<string> names, IEnumerable<IFormFile> files)
    {
        //...some code
        return names;
    }
 

Вы не должны использовать два или более сложных параметра типа в качестве параметров действия, пока не укажете источник, из которого они привязываются. Это связано с тем, что сложные объекты по умолчанию привязаны к телу запроса, и только один параметр может быть привязан к телу запроса.

По состоянию на microsoft docs :

Не применяйте [FromBody] более чем к одному параметру для каждого метода действия. Как только поток запроса считывается средством форматирования ввода, он больше недоступен для повторного чтения для привязки других [FromBody] параметров.

Сложный тип означает переменные класса, массивы и те, которые не являются основными типами, такими как int , double , string и т. Д.

Swagger создает этот пользовательский интерфейс для действий, описанных выше:

введите описание изображения здесь

В качестве заключительного слова обратите внимание , что вы не можете отправить что-либо в теле запроса, когда используете GET http-запрос.