FATAL:所有操作都需要 OperationId。请添加它以进行路径的“获取”操作

Posted

技术标签:

【中文标题】FATAL:所有操作都需要 OperationId。请添加它以进行路径的“获取”操作【英文标题】:FATAL: OperationId is required for all operations. Please add it for 'get' operation of path 【发布时间】: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 包提供,让我使用流畅的模板编写自己的代码生成。 【参考方案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);

【讨论】:

感谢您解决这个问题。现在的错误是***.com/questions/60861020/…【参考方案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);
);

【讨论】:

以上是关于FATAL:所有操作都需要 OperationId。请添加它以进行路径的“获取”操作的主要内容,如果未能解决你的问题,请参考以下文章

Sanic OpenAPI Swagger文档生成抛出属性路径operationId重复

fatal: Authentication failed

fatal singal 11

fatal error LNK1104: 无法打开文件"libExtensions.lib"

虚拟机linux ubuntu中fatal error啥意思

git中fatal: Authentication failed for 的问题