如何使Swashbuckle为Dictionary参数生成正确的OpenAPI模式?

时间:2018-04-18 10:35:43

标签: 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": {}
}

但这不会使用autorest或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定义?

1 个答案:

答案 0 :(得分:1)

跟进@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 with request body