问题
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