Convert string fields to enum fields in Swashbuckle

两盒软妹~` 提交于 2019-12-10 19:36:37

问题


We are using Swashbuckle to document our WebAPI project (using Owin) and are trying to modify the generated Swagger file of Swashbuckle. With the DescribeAllEnumsAsStrings() and an enum property like below, we get an expected result:

class MyResponseClass {
    public Color color;
}

enum Color {
    LightBlue,
    LightRed,
    DarkBlue,
    DarkRed
}

Swagger generated result:

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

The challenge for us is that we have some properties that are of type string but we are actually treating them as enum types. For example:

class MyResponseClass {
    public string color;
}

The only possible values for this property are dark-blue, dark-red, light-blue, light-red.

So, we want something like below as the result:

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

We have lots of these properties with different values in different classes. It would be great to have a custom attribute like below to make it generic. I can't figure out how to create such an attribute and use it in Swashbuckle DocumentFilters or OperationFilters:

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:


Instead of a custom attribute (StringEnum) use an attribute that swagger already knows about, a little know attribute (I've never used it before):

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

That will inject into the parameter.pattern and then we can read it from the IDocumentSchema and transform it into an enum, here is my code:

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('|');
                }
            }
        }                
    }
}

Here is a working example:
http://swashbuckletest.azurewebsites.net/swagger/ui/index?filter=TestStringEnum#/TestStringEnum/TestStringEnum_Post

And the code behind that is on GitHub:
TestStringEnumController.cs
SwaggerConfig.cs#L389



来源:https://stackoverflow.com/questions/46761285/convert-string-fields-to-enum-fields-in-swashbuckle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!