2017-10-16 162 views
3

我们正在使用Swashbuckle来记录我们的WebAPI项目(使用Owin)并试图修改Swashbuckle生成的Swagger文件。 随着DescribeAllEnumsAsStrings()和枚举属性类似下面,我们得到预期的结果:将字符串字段转换为Swashbuckle中的枚举字段

class MyResponseClass { 
    public Color color; 
} 

enum Color { 
    LightBlue, 
    LightRed, 
    DarkBlue, 
    DarkRed 
} 

扬鞭生成的结果:

"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 
} 

回答

0

取而代之的是自定义属性(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) 
       { 
        [email protected] = param.pattern 
         .Replace("^", "") 
         .Replace("(", "") 
         .Replace(")", "") 
         .Split('|'); 
       } 
      } 
     }     
    } 
} 

这里是一个工作示例:
http://swashbuckletest.azurewebsites.net/swagger/ui/index?filter=TestStringEnum#/TestStringEnum/TestStringEnum_Post

而后面的代码是在GitHub上:
TestStringEnumController.cs
SwaggerConfig.cs#L389

+0

感谢您更新了答案。听起来像一个解决方法。然而,你不能教给开发人员正则表达式来寻找一些实际上不是正则表达式的东西。另外,如果我们想要在同一领域真正使用正则表达式呢?我仍然希望可以使用自定义属性来执行此操作... – hosjay

+0

在我的测试中,我无法通过自定义属性实现它(不修改核心swashbuckle代码),问题是在IDocumentFilter上我无法反映该对象获取自定义属性。 – HelderSepu

+0

对于您提到的“为同一字段使用正则表达式”的情况,这是您场景的正确RegEx! _你能提供一个反例吗? – HelderSepu