Swagger 在 ASP.CORE 3 中为字典生成不正确的 URL

Posted

技术标签:

【中文标题】Swagger 在 ASP.CORE 3 中为字典生成不正确的 URL【英文标题】:Swagger generates incorrect URL for dictionary in ASP.CORE 3 【发布时间】:2020-05-12 12:42:40 【问题描述】:

当从查询字符串中提取的模型具有字典作为其属性之一时,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 UI 显示查询模型上“条件”属性的这种格式


  "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 为 Dictionary 类型的属性呈现像 PropertyName[Key]=Value 这样的 URL?

备选问题

不是解决方案,但如果我以这种方式为输入参数定义默认值,Swagger 会创建正确的 URL。


  "Conditions[UserId]": "1",
  "Conditions[GroupId]": "2"

URL 现在正确并且正确绑定到模型

/services/records?Page=0&Count=5&Conditions[UserId]=1&Conditions[GroupId]=2 

有没有办法更改 Swagger 中为 Dictionary 输入类型显示的默认值?

【问题讨论】:

【参考方案1】:

您需要为查询定义设置查询样式deepObject

NSwag 目前通过 SwaggerParameterStyle 支持此功能,您将为其设置值 deepObject

我也很好奇如何在没有 NSwag 的情况下做到这一点,所以我看了一下https://editor.swagger.io/

在这里,您可以为它提供静态 json 招摇,如果您想查看创建相同设置的不同方式,它将为您生成服务器

字典样本模型

[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)

原始 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

看https://swagger.io/specification/中的deepObject风格

【讨论】:

当你说你试过时,你从上面的例子中尝试了哪一部分。这样我就可以帮助缩小为什么它不适合你

以上是关于Swagger 在 ASP.CORE 3 中为字典生成不正确的 URL的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Gradle 中为 OpenAPI 3.0 使用 Swagger Codegen?

在 Swagger 中为请求参数提供示例值

如何在 Swagger 中为具有简单对象的数组描述模型?

如何在 Lumen/Laravel 中为 REST API 集成 Swagger?

如何在 OpenAPI (Swagger) 中为同一路径定义不同的查询参数?

如何使用 Quarkus 在 RestEasy 中为 MultipartFormDataInput 提供 swagger 注释