如何使Swashbuckle为字典参数生成正确的OpenAPI模式



我有一个ASP。定义为以下各项的 NetCore 操作方法:

[HttpGet]
public async Task<IActionResult> Get([FromQuery]Dictionary<string,string> values)
{
  return Ok(JsonConvert.SerializeObject(values));
}

预期的查询如下所示:

http://localhost:36541/api?values[someProperty]=123&values[someOther]=234

当我使用Swashbuckle时,生成的swagger.json文件最终会像:

{
    "swagger": "2.0",
    "info": {
        "version": "v1",
        "title": "Test API"
    },
    "paths": {
        "/api/Api": {
            "get": {
                "tags": [
                    "Api"
                ],
                "operationId": "ApiApiGet",
                "consumes": [],
                "produces": [],
                "parameters": [{
                    "name": "values",
                    "in": "query",
                    "required": false,
                    "type": "object"
                }],
                "responses": {
                    "200": {
                        "description": "Success"
                    }
                }
            }
        }
    },
    "definitions": {}
}

但这并不能使用自动休息或 http://editor.swagger.io/进行验证

错误是:

Schema error at paths['/api/Api'].get.parameters[0]
should NOT have additional properties
additionalProperty: type, name, in, required
Jump to line 14
Schema error at paths['/api/Api'].get.parameters[0].required
should be equal to one of the allowed values
allowedValues: true
Jump to line 14
Schema error at paths['/api/Api'].get.parameters[0].in
should be equal to one of the allowed values
allowedValues: body, header, formData, path
Jump to line 15
Schema error at paths['/api/Api'].get.parameters[0].type
should be equal to one of the allowed values
allowedValues: string, number, boolean, integer, array, file
Jump to line 17

根据 https://swagger.io/docs/specification/data-models/dictionaries/,它似乎缺少additionalProperties属性

如何使此查询参数成为有效的 OpenAPI/Swagger 定义?

跟进@Helen的评论

Swashbuckle 尚不支持 OpenAPI 规范 (OAS( 3.0,因此查询字符串上不应包含对象(如字典(。

我的建议将该操作更改为帖子并从正文中获取值,也因为您的回复IActionResult请考虑使用如下所示SwaggerResponse

[HttpPost]
[SwaggerResponse(200, typeof(Dictionary<string, string>), "This returns a dictionary.")]
public async Task<IActionResult> Post([FromBody]Dictionary<string,string> values)
{
  return Ok(JsonConvert.SerializeObject(values));
}


更新:
我也在研究用身体发送GET的可能性,似乎有很多关于它的争论:带有请求正文的 HTTP GET

最新更新