Swagger генерирует неверный URL для словаря в ASP.CORE 3
Swagger генерирует неверный URL -адрес, когда модель, извлеченная из строки запроса, имеет словарь в качестве одного из свойств. Как указать Swagger изменить формат словаря в URL -адресе или определить схему входных параметров вручную, без автогенерации? Пробовал использовать Swashbuckle и NSwag.
Контроллер
public class RecordsController : ControllerBase
{
[HttpGet]
[Route("services/records")]
public async Task<IActionResult> Records([FromQuery] QueryModel queryModel)
{
return null;
}
}
Модель ввода - строка запроса
public class QueryModel
{
public int Page { get; set; }
public int Count { get; set; }
public Dictionary<Columns, string> Conditions { get; set; }
}
Пользовательский интерфейс Swagger показывает этот формат для свойства "Условия" в модели запроса.
{
"UserId": "string",
"GroupId": "string",
"RecordId": "string"
}
Созданный Swagger URL - Open API v2 - не будет привязан к "Условиям"
/services/records?Page=0&Count=5&Conditions={"UserId":"1"}
Созданный Swagger URL - Open API v3 - не будет привязан к "Условиям"
/services/records?Page=0&Count=5&UserId=1
Пользовательский URL - работает должным образом и инициализирует "Условия" с{ "UserId", "1" }
/services/records?Page=0&Count=5&Conditions[UserId]=1
Вопрос
Как заставить Swagger отображать URL как PropertyName[Key]=Value
для свойства типа Dictionary?
Альтернативный вопрос
Это не решение, но если я таким образом определю значение по умолчанию для своего входного параметра, Swagger создаст правильный URL.
{
"Conditions[UserId]": "1",
"Conditions[GroupId]": "2"
}
URL теперь правильный и правильно привязан к модели
/services/records?Page=0&Count=5&Conditions[UserId]=1&Conditions[GroupId]=2
Есть ли способ изменить значение по умолчанию, отображаемое в Swagger для типа ввода словаря?
1 ответ
Вам нужно будет установить стиль запроса deepObject
для определения запроса
В настоящее время это поддерживается NSwag через SwaggerParameterStyle, для которого вы установите значениеdeepObject
.
Мне также было любопытно, как это сделать без NSwag, поэтому я взглянул на https://editor.swagger.io/
Здесь вы можете предоставить ему свой статический json swagger, и он сгенерирует вам сервер, если вы хотите увидеть другой способ создания той же настройки.
Образец модели для словаря
[DataContract]
public partial class Dictionary : IEquatable<Dictionary>
{
/// <summary>
/// Gets or Sets Word
/// </summary>
[DataMember(Name="word")]
public string Word { get; set; }
/// <summary>
/// Gets or Sets Define
/// </summary>
[DataMember(Name="define")]
public string Define { get; set; }
Образец контроллера
/// <summary>
/// Get word definition
/// </summary>
/// <remarks>Get me the word definitions</remarks>
/// <param name="dictionary">Status values that need to be considered for filter</param>
/// <response code="200">successful operation</response>
[HttpGet]
[Route("/v2/book")]
[ValidateModelState]
[SwaggerOperation("BookGet")]
public virtual IActionResult BookGet([FromQuery][Required()]Dictionary dictionary)
Пример запроса Raw Swagger
/book:
get:
summary: Get word definition
description: Get me the word definitions
parameters:
- name: dictionary
in: query
description: Status values that need to be considered for filter
required: true
style: deepObject
schema:
type: object
properties:
word:
type: string
define:
type: string
Посмотрите на стиль deepObject в https://swagger.io/specification/