【问题标题】:FATAL: OperationId is required for all operations. Please add it for 'get' operation of pathFATAL:所有操作都需要 OperationId。请添加它以进行路径的“获取”操作
【发布时间】:2020-03-23 18:02:45
【问题描述】:

我正在使用 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()
    {

[更新]

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

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

[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

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

[更新]

.netcore2.1 分支的 json 示例

.netcore3.1 分支的 json 示例

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

我已经为this related question 设置了一个示例存储库,并将为此设置一个 netcore2.1 分支。

【问题讨论】:

  • 我想知道我是否应该尝试使用不同于 Autorest 的生成器
  • 您介意发布您的swagger.json 的样本吗?
  • 如果您正在寻找替代工具,请尝试 NSwag - github.com/RicoSuter/NSwag
  • Autorest 对我来说效果很好。谷歌搜索“Autrest vs”打开了一个调查的兔子洞。
  • 我从未尝试过 AutoRest,因为我的主要编程语言是 C#,所以我使用 NSwag,它也可以作为一个 nuget 包提供,让我使用流畅的模板编写自己的代码生成。

标签: c# autorest swashbuckle.aspnetcore


【解决方案1】:

我认为最新的 Swagger (5.2.1) 默认不会为操作生成 OperationId,因为它是 optional identifier as per their docs

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

但是,AutoRest 似乎使用它来识别每种方法。我找到了Github question / issue,人们通过将 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);

【讨论】:

【解决方案2】:

虽然这对于帮助 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);
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-07
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    • 2014-10-25
    • 1970-01-01
    • 2016-06-11
    • 2011-03-08
    相关资源
    最近更新 更多