2

我正在使用 AutoRest 从 swagger.json 生成 api 的客户端

输出是

AutoRest code generation utility [cli version: 3.0.6187; node: v10.16.3, max-memory: 8192 gb]
(C) 2018 Microsoft Corporation.
https://aka.ms/autorest
NOTE: AutoRest core version selected from configuration: ~2.0.4413.
   Loading AutoRest core      'C:\Users\kirst\.autorest\@microsoft.azure_autorest-core@2.0.4417\node_modules\@microsoft.azure\autorest-core\dist' (2.0.4417)
   Loading AutoRest extension '@microsoft.azure/autorest.csharp' (~2.3.79->2.3.82)
   Loading AutoRest extension '@microsoft.azure/autorest.modeler' (2.3.55->2.3.55)
FATAL: OperationId is required for all operations. Please add it for 'get' operation of '/api/Test' path.
FATAL: AutoRest.Core.Logging.CodeGenerationException: OperationId is required for all operations. Please add it for 'get' operation of '/api/Test' path.
   at AutoRest.Modeler.SwaggerModeler.Build(ServiceDefinition serviceDefinition) in /opt/vsts/work/1/s/src/SwaggerModeler.cs:line 96
   at AutoRest.Modeler.Program.<ProcessInternal>d__2.MoveNext() in /opt/vsts/work/1/s/src/Program.cs:line 60
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at NewPlugin.<Process>d__15.MoveNext()
FATAL: csharp/imodeler1 - FAILED
FATAL: Error: Plugin imodeler1 reported failure.
Process() cancelled due to exception : Plugin imodeler1 reported failure.
  Error: Plugin imodeler1 reported failure.

我注意到 swagger.json 没有提到 operationId

但是我确实在api中提到了它

    [AllowAnonymous]
    [HttpGet("Test")]
    [SwaggerOperation(OperationId = "Test")]

    public IActionResult Test()
    {

[更新]

当我尝试升级我的解决方案以使用 netcore3.1 和 AutoRest 3 时,我在 Swagger Attribute Hell 中度过了 2 天

这将帮助我知道我需要在值控制器上放置哪些属性才能生成客户端代码。

[Route("api/[controller]")]
[Produces("application/json")]
public class ValuesController : Controller
{
    public ValuesController()
    {
    }

    [HttpGet()]
    [Produces("application/json")]
    public IEnumerable<string> Get()
    {
        return new string[] {"value1", "value2"};
    }

    [Produces("application/json")]
    [HttpGet("{id}")]
    public string Get(int id)
    {
        return "value";
    }

    [HttpPost()]
    public void Post([FromBody] string value)
    {
    }

    // PUT api/values/5
    [HttpPut("{id}")]
    public void Put(int id, [FromBody] string value)
    {
    }

    // DELETE api/values/5
    [HttpDelete("{id}")]
    public void Delete(int id)
    {
    }
}

我在用

autorest --v3 --input-file=https://mywebsite/myapi/v1/swagger.json --output-folder=generated --csharp --namespace=myconnector

输出是

AutoRest code generation utility [cli version: 3.0.6187; node: v12.16.1, max-memory: 8192 gb]
(C) 2018 Microsoft Corporation.
https://aka.ms/autorest
   Loading AutoRest core      'C:\Users\kirst\.autorest\@autorest_core@3.0.6262\node_modules\@autorest\core\dist' (3.0.6262)
   Loading AutoRest extension '@microsoft.azure/autorest.csharp' (~2.3.79->2.3.84)
   Loading AutoRest extension '@microsoft.azure/autorest.modeler' (2.3.55->2.3.55)
FATAL: OperationId is required for all operations. Please add it for 'get' operation of '/api/Values' path.
FATAL: AutoRest.Core.Logging.CodeGenerationException: OperationId is required for all operations. Please add it for 'get' operation of '/api/Values' path.
   at AutoRest.Modeler.SwaggerModeler.Build(ServiceDefinition serviceDefinition) in /opt/vsts/work/1/s/src/SwaggerModeler.cs:line 96
   at AutoRest.Modeler.Program.<ProcessInternal>d__2.MoveNext() in /opt/vsts/work/1/s/src/Program.cs:line 60
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at NewPlugin.<Process>d__15.MoveNext()
  Error: Plugin imodeler1 reported failure.

在 api 代码中,我有 TargetFramework netcoreapp3.1、Swashbuckle.AspNetCore 5.2.0、FluentValidation 8.6.2

当我的 api 在 .net core 2.1 中时,我一切正常但是我想调用一个 .netstandard2 库,所以我将我的 api 升级到 netcore3.1

文档似乎不完整。没有提到Autorest。我是否应该尝试不同的代码生成器,我想知道。

[更新]

来自 .netcore2.1 分支的示例 json api测试

来自 .netcore3.1 分支的示例 json

netcore3.1 分支

但是,比较可能不公平,因为我可能已经更改了 netcore3.1 分支中的内容。

我已经为 这个相关问题设置了一个示例存储库,并将为此设置一个 netcore2.1 分支。

4

2 回答 2

10

我认为默认情况下最新的 Swagger (5.2.1) 不会OperationId为操作生成,因为根据他们的 docs ,它是一个可选标识符

operationId 是用于标识操作的可选唯一字符串。如果提供,这些 ID 在您的 API 中描述的所有操作中必须是唯一的。

但是,AutoRest 似乎使用它来识别每种方法。我发现了一个Github 问题/问题,人们通过将 AutoRest 配置为使用标签而不是操作 ID 来识别方法来解决这个问题。

AutoRest 使用 operationId 来确定给定 API 的类名/方法名。

如果您不想使用标签,或者您的标签不够唯一,您可以要求 Swagger 将操作 ID 添加到生成的 JSON,方法是:

options.SwaggerDoc(...);

// Tell Swagger where to find operation ID.
// In this example, use the controller action name.
options.CustomOperationIds(
    d => (d.ActionDescriptor as ControllerActionDescriptor)?.ActionName);
于 2020-03-26T20:24:00.670 回答
3

虽然这对于帮助 OP 来说可能有点太晚了,但这是 CustomOperationIds() 的另一种用法,可以解决问题:

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo {Title = "Your API", Version = "v1"});
    c.CustomOperationIds(apiDesc => apiDesc.TryGetMethodInfo(out MethodInfo methodInfo) ? methodInfo.Name : null);
});
于 2020-10-29T16:54:49.523 回答