一、前言
自從之前寫了一篇《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文檔檔案輸出
Swagger使用教程 SwashbuckleEx - 配置注釋檔案:
,可配置多個,但是釋出伺服器的時候需要将XML帶上,如果沒有則會通路報錯。IncludeXmlComments('絕對路徑')
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("[email protected]");
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" } }
);
}
}
-
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("[email protected]").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");
}
五、源碼位址
https://github.com/jianxuanbing/SwashbuckleEx