将字符串字段转换为Swashbuckle

时间:2017-10-16 00:07:05

标签: asp.net-web-api enums swagger swashbuckle

我们正在使用Swashbuckle来记录我们的WebAPI项目(使用Owin),并且正在尝试修改生成的Swashbuckle的Swagger文件。 使用DescribeAllEnumsAsStrings()和如下所示的枚举属性,我们得到预期的结果:

class MyResponseClass {
    public Color color;
}

enum Color {
    LightBlue,
    LightRed,
    DarkBlue,
    DarkRed
}

Swagger生成结果:

"color": {
  "enum": [
    "LightBlue",
    "LightRed",
    "DarkBlue",
    "DarkRed"
  ],
  "type": "string"
},

我们面临的挑战是我们有一些string类型的属性,但实际上我们将它们视为enum类型。例如:

class MyResponseClass {
    public string color;
}

此属性的唯一可能值包括dark-bluedark-redlight-bluelight-red

所以,我们想要结果如下:

"color": {
  "enum": [
    "light-blue",
    "light-red",
    "dark-blue",
    "dark-red"
  ],
  "type": "string"
},

我们有很多这些属性在不同的类中具有不同的值。拥有像下面这样的自定义属性以使其通用是很棒的。我无法弄清楚如何创建这样的属性并在Swashbuckle DocumentFiltersOperationFilters中使用它:

public MyEndpointResponseClass {

    [StringEnum("booked", "confirmed", "reserved")]
    public string status;

    // Other properties
}

public MyEndpointRequestClass {

    [StringEnum("dark-blue", "dark-red", "light-blue", "light-red")]
    public string color;

    // Other properties
}

1 个答案:

答案 0 :(得分:0)

使用swagger已经知道的属性而不是自定义属性(StringEnum),使用一点知道属性(我之前从未使用过它):

[RegularExpression("^(dark-blue|dark-red|light-blue|light-red)")]

这将注入parameter.pattern,然后我们可以从IDocumentSchema中读取它并将其转换为枚举,这是我的代码:

private class StringEnumDocumentFilter : IDocumentFilter
{
    public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry s, IApiExplorer a)
    {                
        if (swaggerDoc.paths != null)
        {
            foreach (var path in swaggerDoc.paths)
            {
                ProcessOperation(path.Value.get);
                ProcessOperation(path.Value.put);
                ProcessOperation(path.Value.post);
                ProcessOperation(path.Value.delete);
                ProcessOperation(path.Value.options);
                ProcessOperation(path.Value.head);
                ProcessOperation(path.Value.patch);
            }
        }
    }

    private void ProcessOperation(Operation op)
    {
        if (op != null)
        {
            foreach (var param in op.parameters)
            {
                if (param.pattern != null)
                {
                    param.@enum = param.pattern
                        .Replace("^", "")
                        .Replace("(", "")
                        .Replace(")", "")
                        .Split('|');
                }
            }
        }                
    }
}

这是一个有效的例子:
http://swashbuckletest.azurewebsites.net/swagger/ui/index?filter=TestStringEnum#/TestStringEnum/TestStringEnum_Post

背后的代码在GitHub上:
TestStringEnumController.cs
SwaggerConfig.cs#L389