从Swagger文档生成的AutoRest - IEnumerable<long> 生成为IEnumerable<long?>。

4

我有一个项目使用ASP.NET MVC 5、Swashbuckle和AutoRest。当我使用Autorest为我的API生成客户端时,我的参数从IEnumerable<long>转换为IEnumerable<long?>

Controller方法

[HttpPost]
public IHttpActionResult Foo([FromBody] IEnumerable<long> ids)
{
    // do work
}

生成的 AutoRest 签名

Task<HttpOperationResponse<IList<ResponseModel>> FoWithMessageAsync(IList<long?> ids, ...)

我尝试过的方法

  • 使用Get方法。结果是“multi”类型,这是Autorest中已知的一个错误(AutoRest已知的错误)
  • 消除[FromBody]属性
  • 将IEnumerable包装在自定义模型中

这是一个奇怪的错误,但我已经使用Swagger和Autorest一段时间了,所以我只能假设它要么是一个晦涩的错误/配置(可能),要么是我漏掉了一些愚蠢的东西(很可能)。提前感谢任何帮助。

更新

这是Swashbuckle生成的Swagger规范。

{
    "swagger": "2.0",
    "info": {
        "version": "v1",
        "title": "FooBar",
    },
    "host": "localhost:5000",
    "schemes": [
        "http"
    ],
    "paths": {
        "/api/v1/Foo": {
            "post": {
                "operationId": "foo",
                "consumes": [
                    "application/json",
                    "text/json"
                ],
                "produces": [
                    "application/json",
                    "text/json"
                ],
                "parameters": [
                    {
                        "name": "ids",
                        "in": "body",
                        "description": "",
                        "required": true,
                        "schema": {
                            "type": "array",
                            "items": {
                                "format": "int64",
                                "type": "integer"
                            }
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "type": "array",
                            "items": {
                                "$ref": "#/definitions/Foo"
                            }
                        }
                    },
                    "404": {
                        "description": "NotFound"
                    },
                    "500": {
                        "description": "InternalServerError"
                    }
                },
                "deprecated": false
            }
        }
    }
}

如果您能够粘贴您正在生成此内容的API规范的相关部分,那么将有助于获取答案。 - Sumit Maingi
@SumitMaingi,我已经添加了Swashbuckle生成的Swagger规范。 - Kevin R.
抱歉,Kevin。我尝试了15分钟(已经是我的极限),但无法让它正常工作。 - Sumit Maingi
好的,没关系。无论如何还是谢谢你。 - Kevin R.
1个回答

0

我可以告诉你如何在Swagger文件中使用最新版的AutoRest(https://github.com/Azure/autorest)来解决你的问题,但我不知道Swashbuckle,即它是否能够生成以下内容:

"200": {
    "description": "OK",
    "schema": {
        "type": "array",
        "items": {
          "x-nullable": false,
          "type": "integer",
          "format": "int64"
        }
    }
},

请注意,我已经拼写出了内联模式,而不是引用"$ref": "#/definitions/Foo",以保持简单。 重要的是设置"x-nullable": false,这将覆盖默认行为(从服务器响应中期望最坏的情况)。 在您的情况下,必须将该属性添加到引用模式.../Foo中。
此功能仅有几天的历史,因此请确保拉取最新的AutoRest。

不幸的是,Autorest正在作为持续集成步骤的一部分生成我的客户端。问题更多地涉及如何让Autorest生成swagger而不是swagger本身。 - Kevin R.
你是说Swashbuckle如何生成swagger?AutoRest只是遵循Swagger规范(或者至少试图遵循)。正如我之前提到的,我从未使用过Swashbuckle,但可能有一种方法可以说服它生成“x-nullable:false”,至少在他们的存储库中找到了一些提及(https://github.com/domaindrivendev/Swashbuckle/blob/e0053e1864defa3c4f73ca2a960eb876e257cc9e/Swashbuckle.Dummy.Core/SwaggerExtensions/ApplySchemaVendorExtensions.cs). - olydis
是的,问题归结于语言之间存在可空原始类型的概念或假设的差异。Swashbuckle通过使用[Required]属性标记属性来解决原始类型的问题。然而,原始类型的IEnumerable却让AutoRest陷入了困境。这只是AutoRest和Swashbuckle之间的问题,但它发生在C#领域的某个地方,在Swagger生成之前。 - Kevin R.
是的,Container<SomeType> 是一个真正的问题,不幸的是我们不能将 内部 的东西标记为必需的(只能标记容器本身,但谁在乎呢),这也是 x-nullable 被添加的原因之一 :/ 希望很快就会有 Swashbuckle 的支持。 - olydis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接