在编写API时,很多时候会用到API版本控制和API文档编写及测试调试。本文主要记录如何使用Microsoft.AspNetCore.Mvc.Versioning进行API版本控制以及Swagger API书写框架的使用。
一、JSON 配置
从asp.net core 3.0开始,默认使用微软新的 JSON组件(System.Text.Json),尽管据微软实验室测试性能高于Newtonsoft.Json ,但是推荐还是用 Newtonsoft.Json,比较成熟而且对很多比较特殊的情况都有处理,使用方式如下:
1、引用 nuget 包 Microsoft.AspNetCore.Mvc.NewtonsoftJson
2、配置使用 Newtonsoft.Json
services.AddControllers()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
});
当然,对于是使用System.Text.Json还是Newtonsoft.Json全凭个人喜好和项目需求。
二、Api版本控制
在编写RESTFUL API时可能时常会进行更新和修改,但如果遇到API是开放给其它系统使用的情况时,我们不可能在启用下个版本时将上一个版本的去掉。因此就需要引入API的版本控制,操作时根据不同的版本去请求即可。
1、使用Nuget安装Api版本控制库
.NET Core Mvc中,微软官方提供了一个可用的Api版本控制库Microsoft.AspNetCore.Mvc.Versioning。 这里我们可以使用Nuget安装这个包。
2、修改Startup类
Microsoft.AspNetCore.Mvc.Versioning库安装完成之后,下一步我们来添加Api版本控制服务。这里我们需要在Startup类的ConfigureService方法中添加以下代码。
services.AddApiVersioning(o => {
o.ReportApiVersions = true;
o.AssumeDefaultVersionWhenUnspecified = true;
o.DefaultApiVersion = new ApiVersion(1, 0);
});
3、创建多版本Api
我们在项目的Controller文件夹下面创建两个文件夹,分别是v1和v2。对应v1和v2两个版本。
当文件夹创建好之后,在v1和v2文件夹下面均创建一个UserController的RESTful API控制器。
创建好后此时项目结构如下:
然后修改v1和v2版本的Attribute,将v1下面的UserController Attribute替换为:
[ApiVersion("1")]
[Route("v{version:apiVersion}/[controller]")]
[ApiController]
将v2下面的UserController Attribute替换为:
[ApiVersion("2")]
[Route("v{version:apiVersion}/[controller]")]
[ApiController]
请注意:不同版本的Controller不同之处仅为ApiVersion中的值不同。
此时你的Control应该是这样的↓↓↓↓
[ApiVersion("2")]
[Route("v{version:apiVersion}/[controller]")]
[ApiController]
public class UserController : ControllerBase
{
//....
}
然后分别修改Controller下的GET方法,让我们可以在浏览器中直接看到结果。修改获取单个信息的方法为:
[HttpGet("{id}", Name = "Get")]
public string Get(int id)
{
return "this is v1 api"; //V2:this is v2 api
}
4、运行测试
F5运行项目,然后在浏览器中输入对应版本的API URL即可通过既定的版本请求不同版本的API。
此时你已经完成了最简单的API版本控制方法,接下来是使用swagger来描述我们不同版本的API。
三、使用Swagger
1、安装依赖
首先我们还是通过Nuget安装Swashbuckle.AspNetCore。
(已经更新正式版)注意:当前支持ASP.NET Core3.1的Swagger还是预览版,在安装之前请勾选“包括预览版项目”,并安装最新的预览版。截止本篇文章,最新预览版为Swashbuckle.AspNetCore 5.0.0-rc5(2019年12月16日)
2、生成项目XML
右键项目,选择“属性”,切换到生成选项卡,勾选“XML文档文件”。 Swagger将根据生成的XML构建API文档。
3、Swagger服务注册
在ConfigureServices方法中注册以下服务:
services.AddSwaggerGen(option =>
{
//分别注册v1和v2
option.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "WithsaltWebApiDemo API",
Description = "API for WithsaltWebApiDemo",
Contact = new OpenApiContact() { Name = "withsalt", Email = "withsalt@geeiot.net" }
});
option.SwaggerDoc("v2", new OpenApiInfo
{
Version = "v2",
Title = "WithsaltWebApiDemo API",
Description = "API for WithsaltWebApiDemo",
Contact = new OpenApiContact() { Name = "withsalt", Email = "withsalt@geeiot.net" }
});
option.DocInclusionPredicate((docName, apiDesc) =>
{
var versions = apiDesc.CustomAttributes()
.OfType<ApiVersionAttribute>()
.SelectMany(attr => attr.Versions);
return versions.Any(v => $"v{v.ToString()}" == docName);
});
option.OperationFilter<RemoveVersionParameterOperationFilter>();
option.DocumentFilter<SetVersionInPathDocumentFilter>();
//项目xml文档
//注意:这里包含了一个Demo.Model.xml,是因为我要显示实体类。
option.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, $"{typeof(Startup).Assembly.GetName().Name}.xml"), true);
option.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, $"Demo.Model.xml"), true);
});
其中包含了两个自定义的 OperationFilter :
public class SetVersionInPathDocumentFilter : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
var updatedPaths = new OpenApiPaths();
foreach (var entry in swaggerDoc.Paths)
{
updatedPaths.Add(
entry.Key.Replace("v{version}", swaggerDoc.Info.Version),
entry.Value);
}
swaggerDoc.Paths = updatedPaths;
}
}
public class RemoveVersionParameterOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
// Remove version parameter from all Operations
var versionParameter = operation.Parameters.Single(p => p.Name == "version");
operation.Parameters.Remove(versionParameter);
}
}
配置中间件。在Configure中添加以下代码:
//Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
//Enable middleware to serve swagger-ui (HTML, JS, CSS etc.), specifying the Swagger JSON endpoint
app.UseSwaggerUI(option =>
{
option.SwaggerEndpoint("/swagger/v2/swagger.json", "V2 Docs");
option.SwaggerEndpoint("/swagger/v1/swagger.json", "V1 Docs");
option.RoutePrefix = string.Empty;
option.DocumentTitle = "WithsaltWebApiDemo API";
});
4、运行测试
配置到这里,可以直接运行看下效果了。
可以在属性,调试选项卡中修改默认的启动页为Swagger Api页面。将启动浏览器参数设置为Swagger默认页面即可。ASP.NET Core WebApi中默认为空。
也可以点击Try it out来进行接口的测试!
Demo
本文Demo下载:点此下载
参考
1、.Net Core中的Api版本控制
2、asp.net core 3.0 中使用 swagger
3、SparkTodo
文章评论