在Asp.Net WebApi中添加版本控制,同時在swagger中按版本顯示接口
引用版本控制包
<package id="Microsoft.AspNet.WebApi.Versioning" version="4.0.0" targetFramework="net46" />
<package id="Microsoft.AspNet.WebApi.Versioning.ApiExplorer" version="4.0.0" targetFramework="net46" />
添加版本控制代碼
按如下修改App_Start中的WebApiConfig文件
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new ApiExceptionFilter());
config.MessageHandlers.Add(new WrapperHandler());
// Web API 配置和服務
config.AddApiVersioning(o =>
{
o.AssumeDefaultVersionWhenUnspecified = true;//沒有標記版本的action默認未1.0版本
o.ReportApiVersions = true;//返回版本可使用的版本
o.ApiVersionReader = ApiVersionReader.Combine(new HeaderApiVersionReader("api-version"), new QueryStringApiVersionReader("api-version"));//通過Header或QueryString進行傳值來判斷api的版本
o.DefaultApiVersion = new ApiVersion(1, 0);//默認版本號
});
var apiExplorer = config.AddVersionedApiExplorer(
options =>
{
options.GroupNameFormat = "'v'VVV";
// note: this option is only necessary when versioning by url segment. the SubstitutionFormat
// can also be used to control the format of the API version in route templates
options.SubstituteApiVersionInUrl = true;
});
// Web API 路由
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
//注意啟用swagger的代碼一定要放到路由之后
SwaggerConfig.Register(config, apiExplorer);
}
引用swagger包
<package id="Swashbuckle" version="5.6.0" targetFramework="net46" />
<package id="Swashbuckle.Core" version="5.6.0" targetFramework="net46" />
修改swagger為多版本api
在引用swagger包后,會自動在App_Start添加一個SwaggerConfig文件,需要修改部分代碼,如下:
//由自動注冊改為手動注冊swagger,因為版本控制需要Web.Http.Description.VersionedApiExplorer apiExplorer參數
//[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]
namespace WebApplication1
{
public class SwaggerConfig
{
public static void Register(HttpConfiguration Configuration, Microsoft.Web.Http.Description.VersionedApiExplorer apiExplorer)
{
var thisAssembly = typeof(SwaggerConfig).Assembly;
Configuration
.EnableSwagger(c =>
{
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
c.MultipleApiVersions(
(apiDescription, version) => apiDescription.GetGroupName() == version,
info =>
{
foreach (var group in apiExplorer.ApiDescriptions)
{
//如果出現中文亂碼問題,可以用vs新建一個SwaggerConfig,把原來SwaggerConfig中的內容拷過去,再刪除自動創建的SwaggerConfig文件,
var description = "A sample application with Swagger, Swashbuckle, and API versioning.";
if (group.IsDeprecated)
{
description += " This API version has been deprecated.";
}
info.Version(group.Name, $"Create Wordreprot API {group.ApiVersion}");
}
});
//獲取目錄下的XML文件 顯示注釋等信息
var basePath1 = Path.GetDirectoryName(System.AppDomain.CurrentDomain.BaseDirectory);//獲取應用程序所在目錄(絕對,不受工作目錄(平台)影響,建議采用此方法獲取路徑)
var xmlComments = Directory.GetFiles(basePath1, "*.xml", SearchOption.AllDirectories).ToList();
foreach (var xmlComment in xmlComments)
{
c.IncludeXmlComments(xmlComment);
}
#region MyRegion
#endregion
// 應用Controller的API文檔描述信息
//c.DocumentFilter<SwaggerDocumentFilter>();
})
.EnableSwaggerUi(
swagger =>
{
//顯示api版本多個版本選擇,選擇版本后要切換失去選擇焦點然后回車才會觸發刷新,不然始終顯示默認版本
swagger.EnableDiscoveryUrlSelector();
}
);
}
}
}
在controller中標記版本
現在可以再controller或者action上添加版本標記來標記版本了,如果沒有標記的默認1.0,默認版本設置見代碼
public class Controller1 : ApiController
{
[ApiVersion("1.0")]
public async Task<string> Get(){
returt "1.0"
}
public async Task<string> Get2(){
returt "1.0"
}
}
public class Controller2 : ApiController
{
[ApiVersion("2.0")]
public async Task<string> Get(){
returt "2.0"
}
}
發送請求
在請求中帶上版本號標記,如果沒有帶版本則默認1.0,請求可以通過query參數或者header方式,名稱為api-version,這個名稱是在前述代碼中配置的
可能遇到的問題
- swagger描述中的中文亂碼,可以用vs新建一個SwaggerConfig,把原來SwaggerConfig中的內容拷過去,再刪除自動創建的SwaggerConfig文件
- 啟動報錯"This XML file does not appear to have any style information associated with it. The document tree is shown below.",這是注冊swagger的順序錯誤,要把SwaggerConfig.Register(config, apiExplorer);放到路由注冊之后。
- 選擇api版本后swagger ui頁面沒有刷新,還是顯示上一個版本,選擇版本后需要失去焦點再回車,不然會彈出選擇框繼續選擇
參考資料