Повторяющийся вывод параметров в Swagger

Обновление: я начинаю задаваться вопросом, связано ли это с ошибкой:

https://github.com/domaindrivendev/Swashbuckle/issues/590

Но предложенный обходной путь, похоже, не решает мою проблему.


Я использую Swashbuckle для создания документации API для проекта C # ASP.NET Web API.

Моя цель - разрешить следующие допустимые URL:

/endpoint/items/123/foo?param2=bar

С обязательным параметром (param1), установленным на «foo», и необязательным параметром (param2), установленным на «bar». Я хотел бы, чтобы оба параметра содержались внутри одного объекта параметра C #. (с другими необязательными параметрами, такими как param3 и т. д.). Несколько конечных точек будут использовать идентичные параметры, и я хотел бы иметь один объект, представляющий параметры.

Детали Swagger / Swashbuckle - это в основном черный ящик, и я не могу понять этого. Я получаю дубликаты в списке параметров.

Пример кода для воспроизведения проблемы:

    // This endpoint is generating documentation the way I would like.
    [HttpGet]
    [Route("endpoint1/items/{id}/{param1}")]
    public string GetDataForParameters(int id, string param1, string param2 = null, string param3 = null)
    {
        return string.Format("Params: {1}, {2}, {3}", id, param1, param2, param3);
    }

    // This endpoint has the structure I would like, but I get duplicates for param1 in the documentation.
    [HttpGet]
    [Route("endpoint2/items/{id}/{param1}")]
    public string GetDataForParameters(int id, [FromUri(Name = "")]MyParams myParams)
    {
        return string.Format("Params: {1}, {2}, {3}", id, myParams.Param1, myParams.Param2, myParams.Param3);
    }

    public class MyParams
    {
        public string Param1 { get; set;}
        public string Param2 { get; set;}
        public string Param3 { get; set;}
    }

Во втором методе я получаю параметры внутри одного объекта. Но Swagger отображает повторяющуюся запись для «param1».

Снимок экрана: повторяющийся параметр Swagger

Как я могу заставить Swagger / Swashbuckle не отображать вторую запись для "param1"?


Причина наличия этой структуры в том, что у меня есть несколько конечных точек, которые возвращают разные типы данных, но используют общие параметры. Некоторые параметры являются обязательными (и частью идентификатора), поэтому мы хотели бы включить их в URL-адрес с дополнительными параметрами в строке запроса. Я бы предпочел, чтобы объект общего параметра содержал как обязательные, так и необязательные параметры.

Пример кода, созданный с обновлением Visual Studio 2015 1. Проект веб-API ASP.NET по умолчанию. Добавление приведенного выше кода в созданный ValuesController.cs. Установлен пакет Swashbuckle 5.3.1 + зависимости.


person PMBjornerud    schedule 18.02.2016    source источник
comment
второй маршрутизатор содержит param1 как строку запроса, а также член MyParams. Может быть, в этом причина.   -  person Amit Kumar Ghosh    schedule 18.02.2016
comment
Это правильно - я бы хотел, чтобы param1 был указан в пути URL, а param2 - в строке запроса. Обновим вопрос, чтобы прояснить это.   -  person PMBjornerud    schedule 18.02.2016
comment
Обновление: удален мой собственный ответ, предлагающий JsonIgnore в качестве обходного пути. Из-за этого Swagger выглядел правильно, но при дальнейшем осмотре я заметил, что сгенерированный URL-адрес становится /endpoint2/items/123/{Param1}?param1=foo&param2=bar, что недопустимо. Я все еще ищу решение этой проблемы.   -  person PMBjornerud    schedule 18.02.2016
comment
Вы столкнулись с проблемой из-за дублирования маршрутов. Почему у вас есть параметр маршрута param1 и параметр запроса param1 в одном маршруте?   -  person VisualBean    schedule 23.02.2016
comment
Я полагаю, это будет исправлено, если вы измените имя параметра запроса param1 на фактически param2, поскольку param1 уже указан в маршруте   -  person VisualBean    schedule 23.02.2016
comment
@VisualBean: Спасибо за ответ. Обратите внимание, что маршрутизация работает нормально, но документация не такая, как я ожидал. Если вы имеете в виду URL-адрес в моем комментарии выше, это часть моей проблемы: недопустимый маршрут, созданный Swagger / Swashbuckle.   -  person PMBjornerud    schedule 23.02.2016
comment
Не обращайте внимания на мой предыдущий комментарий, я неправильно прочитал код :) Вы пробовали установить param1 из класса MyParams на [required]? swagger ищет аннотации json, чтобы увидеть, требуется ли параметр или нет при использовании объекта ввода, так сказать   -  person VisualBean    schedule 23.02.2016
comment
Пытался использовать [Обязательно] сейчас, дубликат тоже стал обязательным - но все равно дубликат.   -  person PMBjornerud    schedule 23.02.2016
comment
Я обнаружил, что это работает. Мне нужно было только настроить его для нечувствительности к регистру.   -  person Arne    schedule 08.06.2017


Ответы (2)


Обновление: найдено обходное решение. Это ужасно:

  1. Добавьте в метод явный повторяющийся параметр.
  2. Добавьте атрибут JsonIgnore к повторяющимся свойствам в объекте параметра.

Затем Swagger выберет параметр метода и документацию для этого. ASP.Net назначит параметры ОБА параметру метода и объекту параметра, позволяя коду использовать объект параметра.

    /// <param name="param1">URL parameters must be documented on this level.</param>
    [HttpGet]
    [Route("endpoint2/items/{id}/{param1}")]
    public string GetDataForParameters(int id, string param1, [FromUri(Name = "")]MyParams myParams)
    {
        // the param1 method parameter is a dummy, and not used anywhere.
        return string.Format("Params: {1}, {2}, {3}", id, myParams.Param1, myParams.Param2, myParams.Param3);
    }

    public class MyParams
    {
        /// <summary>
        /// Cannot add documentation here, it will be ignored.
        /// </summary>
        [JsonIgnore]
        public string Param1 { get; set;}
        /// <summary>
        /// This is included. Querystring parameters can be documented in this class.
        /// </summary>
        public string Param2 { get; set;}
        public string Param3 { get; set;}
    }

Я не буду использовать этот подход, он будет слишком запутанным для любого другого разработчика, читающего код. К сожалению, Swagger / Swashbuckle на практике заставили меня изменить мой (полностью рабочий) код для создания документации.

Если никто не может предложить правильное решение, я думаю, что лучшим решением будет иметь простые параметры метода.

person PMBjornerud    schedule 18.02.2016
comment
Ваш обходной путь сработал для меня. Чтобы документация по swashbuckle работала, в параметрах учитывается регистр. Значение вашего маршрута для действия должно быть изменено на это [Route (endpoint2 / items / {id} / {Param1})] - person Emma Middlebrook; 02.09.2016

Когда Swashbuckle генерирует свой файл swagger.json, он смотрит на параметры маршрутизации и запроса. Поэтому, когда вы используете Get(string param1, string param2 ..), который автоматически сообщает Swashbuckle, что эти параметры являются обязательными (потому что они НЕ установлены на = null)

При использовании Get([FromUri(Name = "")]MyParams myParams) Swashbuckle ищет аннотации данных (System.ComponentModel.DataAnnotations) в вашей модели, чтобы указать, требуется ли параметр или нет.

Установите Param1 как обязательный

public class MyParams
    {
        [Required]
        public string Param1 { get; set;}
        public string Param2 { get; set;}
        public string Param3 { get; set;}
    }
person VisualBean    schedule 23.02.2016
comment
Это заставляет дубликат также отображаться по мере необходимости, но Swagger по-прежнему отображает его как дубликат и генерирует маршрут, аналогичный /{Param1}?param1=bar&param1=bar - person PMBjornerud; 23.02.2016
comment
начинаю беспокоиться, что это более глубокая проблема, обновляя свой вопрос ссылками. - person PMBjornerud; 23.02.2016
comment
@PMBjornerud, почему param1 является частью модели, если он уже указан в параметрах маршрутизации? если ты не возражаешь, если я спрошу - person VisualBean; 23.02.2016
comment
Я хочу, чтобы параметр маршрута был привязан к свойству объекта параметра. Если я привяжу его к переменной параметра, он сработает. Но через объект-параметр документация становится странной. Обратите внимание на мое обновление и ссылку, похоже, у кого-то был сломанный рабочий API (в январе). Завтра я займусь этим дополнительно. - person PMBjornerud; 23.02.2016