首页 文章

Autorest Swagger无法正确生成ENUM

提问于
浏览
2

我有两个应用程序 AB . 在 A 我使用swagger来描述API . 在 A 我还有一些枚举属性的类的定义 . 我想在 B 上生成客户端API . 为此,我使用Autorest . 一切都很好,除了一件事 - 枚举 . 由于某种原因,枚举没有正确生成,一种属性(最初是枚举)是string或int的类型(取决于DescribeAllEnumsAsStrings()的使用 . 我在下面的例子中使用它,所以在这种情况下它是字符串) .

枚举定义由swagger生成JSON:

"Car": {
        "properties": {
            "color": {
                "enum": [
                    "Red",
                    "Blue",
                    "Green"
                ],
                "type": "string"
            }
        },
        "type": "object"
    }

Startup.cs中的Swagger注册

// Register the Swagger generator, defining one or more Swagger documents
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new Info { Title = "Car API", Version = "v1" });
            c.AddSecurityDefinition("Bearer", new ApiKeyScheme { In = "header", Description = "description", Name = "Authorization", Type = "apiKey" });
            c.DescribeAllEnumsAsStrings();
        });

自动恢复命令:

autorest --input-file=http://localhost:55448/swagger/v1/swagger.json --csharp --namespace=Online.Integrations.Api.Service.Car --output-folder=.

生成的类(字符串而不是枚举):

public partial class Car
{
    /// <summary>
    /// Initializes a new instance of the Car class.
    /// </summary>
    public Car()
    {
      CustomInit();
    }

    /// <summary>
    /// Initializes a new instance of the Car class.
    /// </summary>
    /// <param name="application">Possible values include: 'Any', 'Web'
    /// ...
    /// </param>
    public Car(string color = default(string))
    {
        Color = color;
    }

    /// <summary>
    /// An initialization method that performs custom operations like setting defaults
    /// </summary>
    partial void CustomInit();

    /// <summary>
    /// </summary>
    [JsonProperty(PropertyName = "color")]
    public string Color { get; set; }
}

我发现了这个:https://github.com/Azure/autorest/tree/master/docs/extensions#x-ms-enum

有一些x-ms-enum扩展但我不知道如何使用它 . 我尝试手动编辑JSON定义(我在下面的例子中做了什么),但它也没有成功 . 生成的类包含对象颜色=默认(对象)而不是第一个示例中的字符串,而不是枚举 .

"color": {
            "type": "string",
            "enum": [
                "Red",
                "Blue",
                "Green"
            ],
            "x-ms-enum": {
                "name": "Color",
                "modelAsString": false
     },

我会很高兴得到任何帮助 . 谢谢!

编辑: 1) Full Swagger definition (result type : Sting):

在swagger def . 在枚举定义之后是"type":"string"

{"swagger":"2.0","info":{"version":"v1","title":"Audit Overseer API"},"basePath":"/","paths":{"/api/Audit":{"get":{"tags":["Audit"],"operationId":"ApiAuditGet","consumes":[],"produces":["text/plain","application/json","text/json"],"parameters":[{"name":"Id","in":"query","required":false,"type":"string"},{"name":"Application","in":"query","required":false,"type":"string","enum":["Any","Alfa","Beta"]},{"name":"DatabaseName","in":"query","required":false,"type":"string"}],"responses":{"200":{"description":"Success","schema":{"type":"array","items":{"$ref":"#/definitions/Transaction"}}}}}}},"definitions":{"Transaction":{"type":"object","properties":{"callId":{"type":"string"},"actionName":{"type":"string"},"application":{"enum":["Any","Alfa","Beta"],"type":"string"},"httpStatusCode":{"type":"string"},"dateTime":{"format":"date-time","type":"string"}}}},"securityDefinitions":{"Bearer":{"name":"Authorization","in":"header","type":"apiKey","description":"Please insert JWT with Bearer into field"}}}

自动恢复执行:

autorest execution
结果:

result

2) Full Swagger definition (result type : Object):

在swagger def . 我在枚举定义后的实验"x-ms-enum"

{"basePath":"/","definitions":{"Transaction":{"properties":{"actionName":{"type":"string"},"application":{"enum":["Any","Alfa","Beta"],"x-ms-enum":{"modelAsString":false,"name":"Application"}},"callId":{"type":"string"},"dateTime":{"format":"date-time","type":"string"},"httpStatusCode":{"type":"string"}},"type":"object"}},"info":{"title":"Audit Overseer API","version":"v1"},"paths":{"/api/Audit":{"get":{"consumes":[],"operationId":"ApiAuditGet","parameters":[{"in":"query","name":"Id","required":false,"type":"string"},{"enum":["Any","Alfa","Beta"],"in":"query","name":"Application","required":false,"type":"string"},{"in":"query","name":"DatabaseName","required":false,"type":"string"}],"produces":["text/plain","application/json","text/json"],"responses":{"200":{"description":"Success","schema":{"items":{"$ref":"#/definitions/Transaction"},"type":"array"}}},"tags":["Audit"]}}},"securityDefinitions":{"Bearer":{"description":"Please insert JWT with Bearer into field","in":"header","name":"Authorization","type":"apiKey"}},"swagger":"2.0"}

......或者我可以保持空虚 . 结果是一样的

{"basePath":"/","definitions":{"Transaction":{"properties":{"actionName":{"type":"string"},"application":{"enum":["Any","Alfa","Beta"]},"callId":{"type":"string"},"dateTime":{"format":"date-time","type":"string"},"httpStatusCode":{"type":"string"}},"type":"object"}},"info":{"title":"Audit Overseer API","version":"v1"},"paths":{"/api/Audit":{"get":{"consumes":[],"operationId":"ApiAuditGet","parameters":[{"in":"query","name":"Id","required":false,"type":"string"},{"enum":["Any","Alfa","Beta"],"in":"query","name":"Application","required":false,"type":"string"},{"in":"query","name":"DatabaseName","required":false,"type":"string"}],"produces":["text/plain","application/json","text/json"],"responses":{"200":{"description":"Success","schema":{"items":{"$ref":"#/definitions/Transaction"},"type":"array"}}},"tags":["Audit"]}}},"securityDefinitions":{"Bearer":{"description":"Please insert JWT with Bearer into field","in":"header","name":"Authorization","type":"apiKey"}},"swagger":"2.0"}

(现在让我们像以前一样执行相同的autorest命令)

结果是:

enter image description here

2 回答

  • 1

    看起来你可以使用 SchemaFilter<TFilter> 选项方法自动添加 x-ms-enum 扩展名 .

    在Startup.cs中调用Swagger

    // Register the Swagger generator, defining one or more Swagger documents
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info { Title = "Car API", Version = "v1" });
                c.AddSecurityDefinition("Bearer", new ApiKeyScheme { In = "header", Description = "description", Name = "Authorization", Type = "apiKey" });
                c.DescribeAllEnumsAsStrings();
                c.SchemaFilter<EnumFilter>();
            });
    

    然后使用以下代码定义 EnumFilter

    public class EnumFilter : ISchemaFilter
    {
        public void Apply(Schema model, SchemaFilterContext context)
        {
            if (model == null)
                throw new ArgumentNullException("model");
    
            if (context == null)
                throw new ArgumentNullException("context");
    
            if (context.SystemType.IsEnum)
                model.Extensions.Add("x-ms-enum", new
                {
                    name = context.SystemType.Name,
                    modelAsString = false
                });
        }
    }
    
  • 4

    看了几个小时找到 nullable enumerations 的解决方案!

    public class EnumFilter : ISchemaFilter
    {
    
        public void Apply(Schema model, SchemaRegistry schemaRegistry, Type type)
        {
            if (model == null)
            {
                throw new ArgumentNullException("model");
            }
    
            if (schemaRegistry == null)
            {
                throw new ArgumentNullException("schemaRegistry");
            }
    
            if (IsEnum(type, out var enumName))
            {
                model.vendorExtensions.Add("x-ms-enum", new
                                                  {
                                                      name = enumName ?? type.Name,
                                                      modelAsString = false
                                                  });
    
            }
        }
    
        public static bool IsEnum(Type t, out string enumName)
        {
            if (t.IsEnum)
            {
                enumName = t.Name;
                return true;
            }
            Type u = Nullable.GetUnderlyingType(t);
            enumName = u?.Name;
            return (u != null) && u.IsEnum;
        }
    }
    

相关问题