首页 > 解决方案 > Swagger 在 ASP.CORE 3 中为字典生成不正确的 URL

问题描述

当从查询字符串中提取的模型具有字典作为其属性之一时,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 为PropertyName[Key]=ValueDictionary 类型的属性呈现 URL?

替代问题

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

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

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

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

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

标签: c#swaggerasp.net-core-webapiswashbuckleswashbuckle.aspnetcore

解决方案


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

NSwag 目前通过SwaggerParameterStyle支持这一点,您将为其设置 value 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 样式


推荐阅读