一、前言
自從之前寫了一篇《Webapi文檔描述-swagger優化》這篇文章后,欠了大家一篇使用文檔的說明,現在給大家補上哈。
二、環境
- .Net Framework 4.5
- WebApi 2
- SwashbuckleEx 1.1.2:個人修改后的版本
三、SwashbuclkeEx 優化說明
- 漢化:支持中、英文。
- 接口搜索:模塊名、注釋名、接口名
- 注釋:控制器備注、開發進度說明、開發人員注釋
- 區域文檔分組:支持多種文檔切換、並分組顯示在左側,可通過點擊進行切換文檔
- 接口數量統計
展示如下:



三、SwashbuckleEx 使用文檔
4.1 安裝SwashbuckleEx
Install-Package SwashbuckleEx
4.2 包含指定XML注釋文件
- 設置庫生成Xml文件:右鍵點擊
項目屬性->生成->輸出勾選Xml文檔文件

- 配置注釋文件:
IncludeXmlComments('絕對路徑'),可配置多個,但是發布服務器的時候需要將XML帶上,如果沒有則會訪問報錯。
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
c.IncludeXmlComments(string.Format("{0}/bin/SwashbuckleEx.WebApiTest.XML", AppDomain.CurrentDomain.BaseDirectory));
}
4.3 簡單Api文檔信息配置-單文檔
- 配置Api版本信息:
SingleApiVersion('版本','文檔標題') - 配置聯系方式:
Contarct- 郵箱:
Email - 創建人:
Name - 聯系地址:
Url
- 郵箱:
- 配置許可證:
Lincese- 許可證名稱:
Name - 地址:
Url
- 許可證名稱:
- 配置備注:
Description('自定義內容') - 配置服務條款:
TermsOfService('條款內容')。這個方法沒看到在界面哪個地方展示。
配置代碼如下:
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
c.SingleApiVersion("v1", "Test.WebApi").Contact(x =>
{
x.Email("jianxuanhuo1@126.com");
x.Name("jian玄冰");
x.Url("https://www.cnblogs.com/jianxuanbing");
}).TermsOfService("jian玄冰").License(x =>
{
x.Name("MIT");
x.Url("https://www.cnblogs.com/jianxuanbing");
}).Description("自定義文案內容,可以隨便輸入內容");
}
效果圖如下:

4.4 多版本Api文檔信息配置-多文檔
該方式主要用於API版本處理使用,但是本人用區域進行划分,用於分隔多個系統的接口。
- 路由配置:WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API 路由
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "AdminApi",
routeTemplate: "api/Admin/{controller}/{action}/{id}",
defaults: new { action = RouteParameter.Optional, id = RouteParameter.Optional, namespaces = new string[] { "SwashbuckleEx.WebApiTest.Areas.Admin.Controllers" } });
config.Routes.MapHttpRoute(
name: "ClientApi",
routeTemplate: "api/Client/{controller}/{action}/{id}",
defaults: new { action = RouteParameter.Optional, id = RouteParameter.Optional, namespaces = new string[] { "SwashbuckleEx.WebApiTest.Areas.Client.Controllers" } });
config.Routes.MapHttpRoute(
name: "CommonApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { action = RouteParameter.Optional, id = RouteParameter.Optional, namespaces = new string[] { "SwashbuckleEx.WebApiTest.Controllers" } }
);
}
}
- 配置Api版本信息:
MultipleApiVersions()
Version進行了修改,提供支持默認路由
public static void Register()
{
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
c.MultipleApiVersions(ResolveAreasSupportByRouteConstraint, (vc) =>
{
vc.Version("Admin", "中文后台 API").Description("這個用於測試一下備注信息").TermsOfService("jian玄冰").License(
x =>
{
x.Name("jian玄冰");
x.Url("https://www.cnblogs.com/jianxuanbing");
})
.Contact(x =>
{
x.Name("2017").Email("jianxuanhuo1@126.com").Url("www.baidu.xxxx");
});
vc.Version("v1", "Common API", true);// 設置為默認路由
vc.Version("Client", "Client API");
});
// 添加區域路由文檔過濾
c.DocumentFilter<AddAreasSupportDocumentFilter>();
}
}
// 處理默認路由以及區域路由問題
private static bool ResolveAreasSupportByRouteConstraint(ApiDescription apiDescription, string targetApiVersion)
{
if (targetApiVersion == "v1")
{
return apiDescription.Route.RouteTemplate.StartsWith("api/{controller}");
}
var routeTemplateStart = "api/" + targetApiVersion;
return apiDescription.Route.RouteTemplate.StartsWith(routeTemplateStart);
}
4.5 區域文檔過濾
用於區分每個區域內文檔切換問題,僅供參考,因為里面調整的內容與命名空間.相關。
/// <summary>
/// 添加 Area 文檔過濾器
/// </summary>
public class AddAreasSupportDocumentFilter:IDocumentFilter
{
/// <summary>
/// 配置
/// </summary>
private readonly SwaggerConfiguration _config = ConfigProvider.Default.GetConfiguration<SwaggerConfiguration>();
/// <summary>
/// 重寫Apply方法,加入Area文檔處理
/// </summary>
public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
{
IDictionary<string,PathItem> replacePaths=new ConcurrentDictionary<string, PathItem>();
foreach (var item in swaggerDoc.paths)
{
// api/Areas/Namespace.Controller/Action
string key = item.Key;
if (key.Contains(_config.JwtRoute))
{
replacePaths.Add(item.Key,item.Value);
continue;
}
var value = item.Value;
var keys = key.Split('/');
// Areas路由:keys[0]:"",keys[1]:api,keys[2]:Areas,keys[3]:{ProjectName}.Api.Areas.{AreaName}.Controllers.{ControllerName}Controller,keys[4]:{ActionName}
if (keys[3].IndexOf('.') != -1)
{
// 區域路徑
string areaName = keys[2];
string namespaceFullName = keys[3];
var directoryNames = namespaceFullName.Split('.');
string namespaceName = directoryNames[3];
if (areaName.Equals(namespaceName, StringComparison.OrdinalIgnoreCase))
{
string controllerName = directoryNames[5];
replacePaths.Add(
item.Key.Replace(namespaceFullName,
controllerName.Substring(0,
controllerName.Length - DefaultHttpControllerSelector.ControllerSuffix.Length)),
value);
}
}
// 通用路由:keys[0]:"",keys[1]:api,keys[2]:{ProjectName}.Api.Controllers.{ControllerName}Controller,keys[3]:{ActionName}
else if (keys[2].IndexOf('.') != -1)
{
// 基礎路徑
string namespaceFullName = keys[2];
var directoryNames = namespaceFullName.Split('.');
bool isControllers = directoryNames[2].Equals("Controllers", StringComparison.OrdinalIgnoreCase);
string controllerName = directoryNames[3];
if (isControllers)
{
replacePaths.Add(
item.Key.Replace(namespaceFullName,
controllerName.Substring(0,
controllerName.Length - DefaultHttpControllerSelector.ControllerSuffix.Length)), value);
}
}
swaggerDoc.paths = replacePaths;
}
}
}
4.6 顯示上傳文件參數
SwaggerUI 有上傳文件的功能,與添加自定義HTTP Header做法相類似,我們可以通過特性來標識API是否具有上傳功能。
/// <summary>
/// 添加 上傳操作過濾
/// </summary>
public class AddUploadOperationFilter:IOperationFilter
{
/// <summary>
/// 重寫Apply方法,加入Upload操作過濾
/// </summary>
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
var upload = apiDescription.ActionDescriptor.GetCustomAttributes<UploadAttribute>().FirstOrDefault();
if (upload == null)
{
return;
}
operation.consumes.Add("application/form-data");
operation.parameters.Add(new Parameter()
{
name = upload.Name,
@in = "formData",
required = upload.Require,
type = "file",
description = upload.Description
});
}
}
/// <summary>
/// 上傳屬性,用於標識接口是否包含上傳信息參數
/// </summary>
public class UploadAttribute:Attribute
{
/// <summary>
/// 參數名
/// </summary>
public string Name { get; set; } = "file";
/// <summary>
/// 是否必須包含文件
/// </summary>
public bool Require { get; set; } = true;
/// <summary>
/// 備注
/// </summary>
public string Description { get; set; } = "";
}
然后再SwaggerConfig.cs的EnableSwagger配置類添加一行操作過濾注冊代碼即可。
c.OperationFilter<AddUploadOperationFilter>();
效果圖如下:

4.7 自定義接口備注內容
由於不想將一些跟接口名無關的信息放在接口名那里,那么這個時候可以將部分業務相關的注釋放在<remarks></remarks>標簽當中
/// <summary>
/// 獲取后台Guid
/// </summary>
/// <remarks>
/// 測試一些內容,不想將無用的東西放在接口名稱當中<br/>
/// 換行輸出一下內容
/// </remarks>
/// <returns></returns>
[HttpGet]
[ApiAuthor(Name = "jian玄冰",Status = DevStatus.Wait,Time = "2018-04-28")]
public Guid GetGuid()
{
return Guid.NewGuid();
}
效果圖如下:

4.8 設置接口開發信息
增加ApiAuthor特性,用於設置接口開發狀態、開發人、完成時間等相關信息。
/// <summary>
/// 獲取后台Guid
/// </summary>
/// <remarks>
/// 測試一些內容,不想將無用的東西放在接口名稱當中<br/>
/// 換行輸出一下內容
/// </remarks>
/// <returns></returns>
[HttpGet]
[AllowAnonymous]
[ApiAuthor(Name = "jian玄冰",Status = DevStatus.Wait,Time = "2018-04-28")]
public Guid GetGuid()
{
return Guid.NewGuid();
}
然后再SwaggerConfig.cs的EnableSwagger配置類添加一行啟用代碼即可。
c.ShowDeveloperInfo();
效果圖如下:

4.9 自定義響應信息
使用SwaggerResponse特性,可用於生成自定義響應結果實體、狀態碼、響應信息備注等信息,多用於返回類型為HttpResponseMessage結果。
參數說明:
- 狀態碼:
StatusCode,用於設置返回成功狀態的狀態碼 - 備注:
Description,用於設置響應類備注信息 - 類型:
Type,用於設置返回結果類型的實體。這是主要設置項,因為返回類型HttpResponseMessage無法解析出結果類型。
/// <summary>
/// 獲取用戶信息
/// </summary>
/// <returns></returns>
[HttpGet]
[SwaggerResponse(HttpStatusCode.OK,"自定義內容",Type = typeof(UserInfo))]
public HttpResponseMessage GetUserInfo()
{
return Request.CreateResponse(HttpStatusCode.OK, new UserInfo(), "application/json");
}
效果圖如下:

