天天看點

Swagger使用教程 SwashbuckleEx

一、前言

自從之前寫了一篇《Webapi文檔描述-swagger優化》這篇文章後,欠了大家一篇使用文檔的說明,現在給大家補上哈。

二、環境

  • .Net Framework 4.5
  • WebApi 2
  • SwashbuckleEx 1.1.2:個人修改後的版本

三、SwashbuclkeEx 優化說明

  • 漢化:支援中、英文。
  • 接口搜尋:子產品名、注釋名、接口名
  • 注釋:控制器備注、開發進度說明、開發人員注釋
  • 區域文檔分組:支援多種文檔切換、并分組顯示在左側,可通過點選進行切換文檔
  • 接口數量統計

展示如下:

Swagger使用教程 SwashbuckleEx
Swagger使用教程 SwashbuckleEx
Swagger使用教程 SwashbuckleEx

三、SwashbuckleEx 使用文檔

4.1 安裝SwashbuckleEx

Install-Package SwashbuckleEx
           

4.2 包含指定XML注釋檔案

  • 設定庫生成Xml檔案:右鍵點選

    項目屬性

    ->

    生成

    輸出

    勾選Xml文檔檔案
    Swagger使用教程 SwashbuckleEx
  • 配置注釋檔案:

    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("[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("自定義文案内容,可以随便輸入内容");
                }
           

效果圖如下:

Swagger使用教程 SwashbuckleEx

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>();
           
Swagger使用教程 SwashbuckleEx

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();
}
           
Swagger使用教程 SwashbuckleEx

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();
           
Swagger使用教程 SwashbuckleEx

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");
}
           
Swagger使用教程 SwashbuckleEx

五、源碼位址

https://github.com/jianxuanbing/SwashbuckleEx

繼續閱讀