引言
在现代API开发中,良好的文档是确保API易用性和可维护性的关键。Swagger(现在也称为OpenAPI)是一个强大的工具,可以自动生成、可视化和测试API文档。本文将详细介绍如何在.NET 9.0项目中集成Swagger,构建专业的API文档。
一、准备工作
1. 创建项目并安装Swashbuckle.AspNetCore包
在.NET 9.0中,我们需要安装以下Swagger相关包:
bash
dotnet add package Swashbuckle.AspNetCore
二、基本Swagger配置
1. 配置Swagger服务
在.NET 9.0中,我们可以在Program.cs文件中配置Swagger服务。以下是基本配置:
csharp
// Program.cs
if (env.IsDevelopment() || appConfig.Swagger.Enable)
{
// 注册Swagger生成器和端点资源管理器
services.AddEndpointsApiExplorer();
services.AddSwaggerGen(options =>
{
// 配置Swagger文档
options.SwaggerDoc("v1", new OpenApiInfo
{
Title = "API文档",
Version = "v1",
Description = "这是一个.NET 9.0 Web API项目"
});
});
}
2. 配置Swagger中间件
接下来,我们需要在请求管道中添加Swagger中间件:
csharp
// Program.cs
if (env.IsDevelopment() || appConfig.Swagger.Enable)
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "API文档 v1");
c.DocumentTitle = "接口文档";
});
}
三、高级Swagger配置
1. Swagger分组配置
为了更好地组织API文档,我们可以使用Swagger分组功能。首先,创建一个扩展方法来配置Swagger分组:
csharp
// SwaggeServiceExtension.cs
public static void AddSaggerGroup(this SwaggerGenOptions options)
{
// 配置接口阐述文档
options.SwaggerDoc("PrefaceGroup", new OpenApiInfo
{
Title = "接口阐述",
Description = "详细的API使用说明",
Version = "V1"
});
// 从程序集中扫描SwaggeGroupAttribute属性,自动生成API分组
GetSwaggerGroupInfo().ForEach(f =>
{
options.SwaggerDoc(f.GroupName, new OpenApiInfo
{
Title = f.Title,
Version = f.Version,
Description = f.Description
});
});
// 配置文档包含规则
options.DocInclusionPredicate((docName, apiDescription) =>
{
if (docName == "NoGroup")
{
// 当分组为NoGroup时,只要没加特性的都属于这个组
return string.IsNullOrEmpty(apiDescription.GroupName);
}
else
{
return apiDescription.GroupName == docName;
}
});
}
2. 配置Swagger UI分组
接下来,创建一个扩展方法来配置Swagger UI分组:
csharp
// SwaggeServiceExtension.cs
public static void UseGroupSagger(this IApplicationBuilder app)
{
app.UseSwaggerUI(c =>
{
c.DocumentTitle = "接口文档";
c.SwaggerEndpoint("/swagger/PrefaceGroup/swagger.json", "接口阐述");
// 添加自动生成的API分组端点
GetSwaggerGroupInfo().ForEach(f =>
{
c.SwaggerEndpoint($"/swagger/{f.GroupName}/swagger.json", f.Title ?? f.GroupName);
});
// 配置文档折叠方式
c.DocExpansion(DocExpansion.None);
});
}
3. 使用Swagger分组属性
创建一个SwaggeGroupAttribute属性,用于标记控制器所属的分组:
csharp
// SwaggeGroupAttribute.cs
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class SwaggeGroupAttribute : Attribute, IApiDescriptionGroupNameProvider
{
public string GroupName { get; set; }
public string Title { get; set; }
public string Version { get; set; }
public string Description { get; set; }
public SwaggeGroupAttribute(string groupName, string title, string version, string description = "")
{
GroupName = groupName;
Title = title;
Version = version;
Description = description;
}
}
然后,在控制器上使用该属性:
csharp
[ApiController]
[Route("[controller]")]
[SwaggeGroup("UserGroup", "用户管理", "v1", "用户相关API")]
public class UserController : ControllerBase
{
// API方法
}
4. Swagger过滤器
Swagger提供了多种过滤器,可以自定义API文档的生成。以下是一些常用的过滤器:
4.1 枚举架构过滤器
增强枚举类型的描述:
csharp
// EnumSchemaFilter.cs
public class EnumSchemaFilter : ISchemaFilter
{
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
if (context.Type.IsEnum)
{
schema.Enum.Clear();
Enum.GetNames(context.Type).ToList().ForEach(name =>
{
var enumMember = context.Type.GetMember(name).First();
var descriptionAttribute = enumMember.GetCustomAttribute<DescriptionAttribute>();
var enumValue = Enum.Parse(context.Type, name);
schema.Enum.Add(new OpenApiString($"{enumValue} - {descriptionAttribute?.Description ?? name}"));
});
}
}
}
4.2 路径驼峰命名过滤器
将API路径转换为驼峰命名格式:
csharp
// PathCamelCasenFilter.cs
public class PathCamelCasenFilter : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
var paths = swaggerDoc.Paths.ToDictionary(entry => entry.Key, entry => entry.Value);
swaggerDoc.Paths.Clear();
foreach (var path in paths)
{
var newPath = string.Join("/", path.Key.Split('/').Select(segment =>
{
if (segment.StartsWith("{") && segment.EndsWith("}"))
{
var paramName = segment.Substring(1, segment.Length - 2);
return "{" + char.ToLower(paramName[0]) + paramName.Substring(1) + "}";
}
return segment;
}));
swaggerDoc.Paths[newPath] = path.Value;
}
}
}
4.3 Swagger忽略属性
用于标记不需要在文档中显示的属性:
csharp
// SwaggerIgnoreAttribute.cs
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class SwaggerIgnoreAttribute : Attribute
{
}
5. 注册Swagger过滤器
在Program.cs中注册这些过滤器:
csharp
// Program.cs
services.AddSwaggerGen(options =>
{
// 添加Swagger分组
options.AddSaggerGroup();
// 注册过滤器
options.OperationFilter<SwaggerIgnoreFilter>();
options.OperationFilter<AddHeaderParameterOperationFilter>();
options.SchemaFilter<EnumSchemaFilter>();
options.OperationFilter<ValidateRequiredOperationFilter>();
options.DocumentFilter<PathCamelCasenFilter>();
// 配置自定义操作ID
options.CustomOperationIds(apiDesc =>
{
var controllerAction = apiDesc.ActionDescriptor as ControllerActionDescriptor;
return controllerAction!.ControllerName + "-" + controllerAction.ActionName;
});
// 包含XML注释
string[] xmlFiles = Directory.GetFiles(AppContext.BaseDirectory, "*.xml");
if (xmlFiles.Length > 0)
{
foreach (var xmlFile in xmlFiles)
{
options.IncludeXmlComments(xmlFile, true);
}
}
// 配置参数驼峰命名
options.DescribeAllParametersInCamelCase();
});
四、条件启用Swagger
在实际项目中,我们可能只希望在特定环境或特定条件下启用Swagger。可以通过以下方式实现:
csharp
// Program.cs
// 仅在开发环境或配置文件中启用Swagger时启用
if (env.IsDevelopment() || appConfig.Swagger.Enable)
{
// 配置Swagger服务
services.AddSwaggerGen(options =>
{
// Swagger配置
});
// 配置Swagger中间件
app.UseSwagger();
app.UseGroupSagger();
}
五、配置文件管理
为了更好地管理Swagger配置,我们可以将Swagger配置添加到appsettings.json文件中:
json
// appsettings.json
{
"Swagger": {
"Enable": true,
"Title": "API文档",
"Version": "v1"
}
}
然后,创建一个配置类来映射这些配置:
csharp
// AppConfig.cs
public class AppConfig
{
public SwaggerConfig Swagger { get; set; } = new SwaggerConfig();
}
public class SwaggerConfig
{
public bool Enable { get; set; } = false;
public string Title { get; set; } = "API文档";
public string Version { get; set; } = "v1";
}
六、测试和验证
配置完成后,我们可以运行项目并访问Swagger UI界面。默认情况下,Swagger UI的地址是http://localhost:5000/swagger。
在Swagger UI中,我们可以:
- 查看API文档的分组结构
- 查看每个API的详细信息,包括请求参数、响应参数等
- 直接在界面上测试API