ASP.NET Core Web API 入門心得 - 改善 Enum 註解
TLDR
- Swashbuckle.AspNetCore 預設無法顯示 Enum 成員的 XML 註解,導致 API 文件可讀性不佳。
- 透過實作
ISchemaFilter介面,可以解析專案產出的 XML 文件,並將 Enum 成員的註解注入至 OpenAPI Schema 的Description欄位中。 - 建議將
JsonStringEnumConverter設定於Program.cs的全域設定中,而非個別 DTO 屬性,以維持 API 輸入與輸出的統一性。 - 實作
EnumSchemaFilter時,需注意檢查schema.Description是否已存在內容,避免重複加入描述。
問題情境:Swagger 無法顯示 Enum 成員註解
在 ASP.NET Core Web API 專案中,即使在 Enum 定義與 DTO 屬性上撰寫了完整的 XML 註解,Swagger UI 預設仍無法將這些註解呈現出來。這會造成開發者在使用 API 時,難以理解 Enum 參數的具體含意與對應數值。
什麼情況下會遇到這個問題:當專案使用 Swashbuckle.AspNetCore 作為 OpenAPI 文件產生工具,且 API 介面包含 enum 型別參數時。

解決方案:實作 ISchemaFilter 注入 XML 註解
為了讓 Swagger 能正確顯示 Enum 的詳細說明,可以透過實作 ISchemaFilter 來攔截 Schema 產生過程,並讀取編譯產生的 XML 文件進行內容注入。
實作 EnumSchemaFilter
此 Filter 會檢查目標型別是否為 Enum,並從 XML 文件中提取對應的 <summary> 內容,最後將其格式化後寫入 schema.Description。
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 中,將上述 Filter 加入 AddSwaggerGen 的設定流程:
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);
}
});小結論:透過自定義 ISchemaFilter,可以有效解決 Swagger 無法讀取 Enum 註解的問題,並提供開發者更友善的 API 文件參考。

關於 JsonStringEnumConverter 的使用建議
什麼情況下會遇到這個問題:當開發者希望 API 傳輸時使用 Enum 的字串名稱而非數值,但又不希望破壞 Swagger 的顯示格式。
若直接在 DTO 屬性上使用 [JsonConverter(typeof(JsonStringEnumConverter))],會導致 Swagger 文件顯示混亂。建議改為在 Program.cs 中進行全域設定:
builder.Services.AddControllers()
.AddJsonOptions(options => {
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});小結論:將轉換器設定於全域,能確保 API 行為的一致性,並避免在每個 DTO 屬性重複宣告,同時配合上述的 EnumSchemaFilter,即可在 Swagger 中同時呈現 Enum 的數值與名稱對應關係。
異動歷程
- 初版文件建立。
- 修正 EnumSchemaFilter 會重複加入 enum 專案描述的錯誤。