使用Swagger为ASP.NET Core WebApi生成API文档
团队工作中每一个项目都能提供一份详尽的说明文档的话,自行脑补“这个就叫专业.jpg”。但是利用本来就有限的时间编写一份让别人看起来舒服的文档可不是一份美差。故,很多自动化的文档生成器便应运而生,这里简单介绍一个很受欢迎的API文档工具Swagger在ASP.NET Core上的应用,其开源在GitHub。
Swagger可以为ASP.NET Core项目生成一份美观的API文档,并附带测试功能的UI界面。从实践出发,接下来介绍如何将Swagger应用在ASP.NET Core WebApi项目中。首先创建ASP.NET Core WebApi的过程这里就不在赘述了。使用NuGet为项目添加“Swashbuckle.AspNetCore”的引用。本文撰写时“Swashbuckle.AspNetCore”已经是5.4.1版本了。
来到Startup.cs文件中的ConfigureServices方法中,向服务容器中注册Swagger生成器(Swagger generator)从而定义Swagger文档。具体写法可以参考下面的写法
1 services.AddSwaggerGen(setup => 2 { 3 setup.SwaggerDoc("DemoApi", //定义文档的名称 4 new OpenApiInfo 5 { 6 Title = "DemoApi", 7 Version = "v1.0", 8 Contact = new OpenApiContact { Name = "xuhy", Email = "hyxu0826@gmail.com" }, 9 Description = "Demo Api 的描述信息" 10 }); 11 });
这里定义要生成文档的名称,及其一些附加的版本信息,联系人信息和描述信息等,这些信息都会在最后创建出的UI界面上有所显示。
来到Startup.cs文件中的Configure方法,插入swaggerswagger.ui中间件来显示我们生成的Swagger界面。
1 // 启用Swagger中间件 2 app.UseSwagger(); 3 // 配置SwaggerUI 4 app.UseSwaggerUI(c => 5 { 6 c.SwaggerEndpoint("/swagger/DemoApi/swagger.json", "DemoApi项目文档"); 7 c.RoutePrefix = string.Empty; 8 9 });
到目前为止,最简单的Swagger配置便已经完成了。值得注意的一点是,我们在开发WebApi项目时,需要显式的为Action指定Http方法和参数的来源,否则将会都被默认描述成FromQuery。
接下来测试下是否能够正常显示,运行项目打开浏览器,如果不出意外便可以看到类似下面的界面。在其中我们可以看到项目中定义的所有Controller和Action。自定义标题及版本信息也都一一呈现,如下图。并且在controller的下方,还有一个Schemas模块。在Swashbuckle 的5.0版本后,便可以在Schemas中看到API暴露出来的所有数据类型的具体信息。
针对Schemas,是基于Newtonsoft 的json序列化器生成的,如果我们ASP.NET Core项目中所用的Json序列化器是默认的System.Text.Json,则就需要为此增加一些配置了。首先利用Nuget添加“Swashbuckle.AspNetCore.Newtonsoft”,并在 services.AddSwaggerGen 方法之后添加 services.AddSwaggerGenNewtonsoftSupport();
在项目的开发过程中,对方法、参数和属性添加完备的注释信息是一个好习惯,Swagger也支持将这些注释信息显示到适当的位置从而更好的起到文档的用途。
首先我们需要对AspNetCore项目进行设置,使其生成XML文档文件。简单的设置方法是在项目上右键→属性→生成,将其中的“XML文档文件”勾选上。但是勾选上之后,项目中所有未进行注释的方法都会报出警告信息,有强迫症的同学肯定不能忍。这时只需要在勾选“XML文档文件”的同时,为“取消显示警告”中添加“1591”,便可以取消这些警告了。
设置好之后来带注册Swagger生成器的 AddSwaggerGen 方法中,指定的xml文件的路径并添加进去即可。
1 //在界面中显示项目中的注释 2 var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location); 3 var commentsFileNameMain = typeof(Program).Assembly.GetName().Name + ".XML"; 4 setup.IncludeXmlComments(Path.Combine(basePath, commentsFileNameMain)); 5 setup.DocInclusionPredicate((docName, description) => true);
接下来重新编译启动项目,便可以看到项目中的注释信息了。
为了达到更多自定义的需求,Swagger为我们提供了3种过滤器(Operation Filter,Schema Filter,Document Filter)来分别过滤不同的部分。举个例子,有些情况下,Action的方法参数是一个“复杂”类型,但是我们不希望将请求参数中的所有属性都暴露出来,只想暴露实际需要的属性到文档中。
首先创建一个自定义的特性,用来标注我们不想在文档中暴露的属性。
1 [AttributeUsage(AttributeTargets.Property)] 2 public class SwaggerExcludeAttribute : Attribute 3 { 4 }
接下来创建过滤器。
1 public class SwaggerExcludePropFilter : IOperationFilter 2 { 3 public void Apply(OpenApiOperation operation, OperationFilterContext context) 4 { 5 if (context.MethodInfo.DeclaringType == null) return; 6 var parms = context.MethodInfo.GetParameters(); 7 foreach (var parameterInfo in parms) 8 { 9 foreach (var property in parameterInfo.ParameterType.GetProperties()) 10 { 11 var excludeAttributes = property.GetCustomAttribute<SwaggerExcludeAttribute>(); 12 if (excludeAttributes == null) continue; 13 var prop = operation.Parameters.FirstOrDefault(p => p.Name == property.Name); 14 if (prop != null) 15 { 16 operation.Parameters.Remove(prop); 17 } 18 } 19 } 20 } 21 }
注意别忘了在注册Swagger生成器时将过滤器添加上。
1 //注册过滤器 2 setup.OperationFilter<SwaggerExcludePropFilter>();
如果此时我们将 EmployeeQueryDto 的 Gender 属性标注上 [SwaggerExclude] 特性,重新编译后运行,属性消失了。
最后,Swagger中还包含更多高级的用法,具体可以参考GitHub。