2017-10-16 164 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