致命:所有操作都需要 OperationId。请为路径的'get'操作添加它

FATAL: OperationId is required for all operations. Please add it for 'get' operation of path

我正在使用 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 似乎不完整。没有提到自动休息。我想知道我是否应该尝试不同的代码生成器。

[更新]

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

示例 json 来自 .netcore3.1 分支

但是比较可能不公平,因为我可能在 netcore3.1 分支中更改了一些东西。

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

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

operationId is an optional unique string used to identify an operation. If provided, these IDs must be unique among all operations described in your API.

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

AutoRest uses operationId to determine the class name/method name for a given API.

如果您不想使用标签,或者您的标签不够独特,您可以要求 Swagger 在生成的 JSON 中添加操作 ID,方法是:

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);

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