Is there an option to dynamically set the OperationId for paths that are generated by MapIdentityApi in .NET 8?

我注意到我可以用WithOpenApi设置操作ID,但它似乎只对静态设置有效.或者有没有办法使用OpenApi动态设置操作ID?:

app.MapGroup("/auth").MapIdentityApi<User>().WithOpenApi(operation => new OpenApiOperation(operation)
{
    // Sets it to a static value
    OperationId = "Test"
});

我的目标是最终得到如下所示的操作ID:

"paths": {
    "/auth/register": {
      "post": {
        "operationId": "Auth_Register_Post",
      }
    },
    "/auth/login": {
      "post": {
        "operationId": "Auth_Login_Post",
      }
    },
    "/auth/refresh": {
      "post": {
        "operationId": "Auth_Refresh_Post",
      }
    },

推荐答案

我发现的一个可能的解决方案是将实现IOperationFilter接口的SwaggerOperationIdFilter添加到AddSwaggerGen.此过滤器用于动态设置Swagger操作的OperationId.

Program.cs(启动)

在Swagger生成过程中,将SwaggerOperationIdFilter注册为操作筛选器.

services.AddSwaggerGen(options =>
{
  options.OperationFilter<SwaggerOperationIdFilter>();
  // ... other SwaggerGen configurations
}

SwaggerOperationIdFilter.cs的实现

public class SwaggerOperationIdFilter : IOperationFilter
{
  public void Apply(OpenApiOperation operation, OperationFilterContext context)
  {
    // Check if it's a MapIdentityApi action
    if (context.ApiDescription.ActionDescriptor is not ControllerActionDescriptor controllerActionDescriptor)
    {
      var relativePath = context.ApiDescription.RelativePath ?? "";
      operation.OperationId = $"{GenerateOperationIdBaseString(relativePath)}_{context.ApiDescription.HttpMethod}";
      return;
    }

    // For other controller actions, set OperationId based on controller and action names
    operation.OperationId = $"{controllerActionDescriptor.ControllerName}_{controllerActionDescriptor.ActionName}_{context.ApiDescription.HttpMethod}";
  }

  // Helper Method to extract the controller and the action name
  private static string GenerateOperationIdBaseString(string inputString)
  {
    var input = inputString.Split('/');
    if (input.Length == 0)
    {
      return string.Empty;
    }

    var controllerName = input[0].FirstCharToUpper();
    var actionName = string.Join("", input.Skip(1).Select(word => word.FirstCharToUpper()));
        
    return $"{controllerName}_{actionName}";
  }
}

.net相关问答推荐

Azure管道-使用.NET 8 RC2 SDK生成C#项目失败

在生产中使用实体框架(代码优先)迁移

在 C# 中获取 log4net 日志(log)文件

单击关闭按钮时隐藏表单而不是关闭

设置日志(log)文件名以在 Log4j 中包含当前日期

抛出 ArgumentNullException

使用 Windows 服务和 C# 检测 USB 驱动器插入和移除

IEnumerable Count() 和 Length 的区别

多个等待与 Task.WaitAll - 等效?

属性应该与其类型同名吗?

C# 的 Actors 有什么好的实现吗?

将属性序列化为元素中的 Xml 属性

C#中的T是什么意思?

获取 .NET 程序集的 AssemblyInformationalVersion 值?

有没有办法从方法返回匿名类型?

清除文件内容

如何使用通用扩展方法中的字符串列名在 IQueryable 上应用 OrderBy?

多个列表与 IEnumerable.Intersect() 的交集

如何为 Dapper 查询动态创建参数

如何使用 XmlSerializer 将字符串序列化为 CDATA?