ASP.NET Core Web API 入門心得 - 改善 Enum 註解
TLDR
- 預設的
Swashbuckle.AspNetCore無法自動解析並顯示 Enum 成員的 XML 註解。 - 使用
JsonStringEnumConverter可讓 API 支援字串格式的 Enum 輸入與輸出,但無法解決 Swagger 文件可讀性問題。 - 實作自定義
ISchemaFilter是解決此問題的最佳方案,可將 XML 文件中的註解注入到 OpenAPI Schema 的Description欄位中。 - 透過
ISchemaFilter處理 Enum 描述,能同時保留數值傳遞的嚴謹性與文件說明的高可讀性。
問題情境:Swagger 無法顯示 Enum 成員註解
在 ASP.NET Core Web API 專案中,即使在 Enum 定義中撰寫了完整的 XML 註解,Swagger UI 預設仍無法將這些資訊呈現出來。這導致開發者在使用 API 時,無法直接從文件中得知各個 Enum 數值所代表的業務邏輯含義。
什麼情況下會遇到這個問題:當專案使用 Swashbuckle.AspNetCore 產生 OpenAPI 文件,且 API 的 DTO 中包含 enum 型別屬性時。
嘗試方案:使用 JsonStringEnumConverter
部分開發者會嘗試透過 JsonStringEnumConverter 將 Enum 轉換為字串,以提升 API 的可讀性。
- 設定方式:在 DTO 屬性上標註
[JsonConverter(typeof(JsonStringEnumConverter))]或在Program.cs的AddJsonOptions中全域設定。 - 結果分析:雖然 API 的輸入與輸出變成了字串(例如
Sunday而非0),但 Swagger UI 的說明欄位依然保持空白或僅顯示數值陣列,並未顯示 XML 中的註解內容。此外,將 Enum 改為字串傳遞可能增加使用端拼寫錯誤的風險。
解決方案:實作自定義 ISchemaFilter
為了在不改變 API 傳輸格式的前提下提升文件可讀性,建議實作 ISchemaFilter 來解析 XML 文件,並將註解動態注入至 Swagger 的 Schema 描述中。
實作步驟
- 建立
EnumSchemaFilter類別,負責讀取 XML 文件並將成員描述附加至schema.Description。 - 在
Program.cs的AddSwaggerGen設定中,註冊該 Filter 並傳入 XML 文件內容。
csharp
public class EnumSchemaFilter : ISchemaFilter {
private readonly XDocument xmlComments;
public EnumSchemaFilter(XDocument xmlComments) {
this.xmlComments = xmlComments;
}
public void Apply(OpenApiSchema schema, SchemaFilterContext context) {
Type enumType = context.Type;
if (!enumType.IsEnum) {
return;
}
// 避免重複加入描述
if (schema.Description?.Contains("<p>Possible values:</p>") == true) {
return;
}
StringBuilder sb = new(schema.Description);
sb.AppendLine("<p>Possible values:</p>");
sb.AppendLine("<ul>");
foreach (string enumMemberName in Enum.GetNames(enumType)) {
string fullEnumMemberName = $"F:{enumType.FullName}.{enumMemberName}";
string enumMemberDescription = xmlComments.XPathEvaluate(
$"normalize-space(//member[@name = '{fullEnumMemberName}']/summary/text())"
) as string;
if (string.IsNullOrEmpty(enumMemberDescription)) {
continue;
}
long enumValue = Convert.ToInt64(Enum.Parse(enumType, enumMemberName));
sb.AppendLine($"<li><b>{enumValue}[{enumMemberName}]</b>: {enumMemberDescription}</li>");
}
sb.AppendLine("</ul>");
schema.Description = sb.ToString();
}
}註冊至 Swagger
在 Program.cs 中進行配置:
csharp
builder.Services.AddSwaggerGen(options => {
foreach (string xmlFile in Directory.GetFiles(AppContext.BaseDirectory, "*.xml")) {
XDocument xmlDoc = XDocument.Load(xmlFile);
options.IncludeXmlComments(() => new XPathDocument(xmlDoc.CreateReader()), true);
options.SchemaFilter<EnumSchemaFilter>(xmlDoc);
}
});執行結果
透過此方式,Swagger UI 的 Schema 描述區塊將會自動列出所有 Enum 成員及其對應的數值、名稱與註解說明,大幅提升 API 文件的參考價值。

異動歷程
- 2024-04-10 初版文件建立。
- 2025-01-16 修正 EnumSchemaFilter 會重複加入 enum 專案描述的錯誤。
