1. 程式人生 > >.netcore下使用Swagger生成webapi文件

.netcore下使用Swagger生成webapi文件

一、準備工作

1.新建一個.netcore webapi專案

2.新增一個Model子專案用於存放輸入輸出類

在解決方案中新增一個.netcore類庫子專案,命名為Test.Model,用於存放API介面的輸入輸出引數類

3.在Test.Model子專案中新建兩個輸入輸出類備用

using System;
using System.Collections.Generic;
using System.Text;

namespace Test.Model.InputParam
{
    public class SearchInput
    {
        /// <summary>
        /// 姓名
        /// </summary>
        public string name { get; set; }
        /// <summary>
        /// 性別
        /// </summary>
        public string sex { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace Test.Model.OutputParam
{
    public class SearchOutput
    {
        /// <summary>
        /// 使用者ID
        /// </summary>
        public int UserId { get; set; }
        /// <summary>
        /// 姓名
        /// </summary>
        public string UserName { get; set; }
        /// <summary>
        /// 性別
        /// </summary>
        public string Sex { get; set; }
        /// <summary>
        /// 年齡
        /// </summary>
        public int Age { get; set; }
        /// <summary>
        /// 註冊時間
        /// </summary>
        public DateTime CreateTime { get; set; }
    }
}

4.在Test.Web中新增對Test.Model子專案的引用

5.在Test.Web中新建一個控制器,並建立方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Test.Model.InputParam;
using Test.Model.OutputParam;

namespace Test.Web.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class HomeController : ControllerBase
    {
        /// <summary>
        /// 查詢使用者
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet]
        public List<SearchOutput> UserSearch(SearchInput input)
        {
            //邏輯暫空,這裡主要看生成的輸入輸出
            return null;
        }

    }
}

至此,準備工作已經差不多了,專案結構如下:

二.安裝並配置Swagger

1.在Test.Web子專案中使用nuget安裝Swashbuckle.AspNetCore包

2.新增幫助文件頁面

這裡不使用自動生成的/swagger/,而是自己新增方便定製

右鍵wwwroot,新增一個html頁面,內容如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>swagger</title>
    <style type="text/css">
        html, body {
            padding: 0;
            margin: 0;
            width: 100%;
            height: 96%;
        }

        iframe {
            padding: 0;
            margin: 0;
            width: 100%;
            height: 100%;
            border: 0;
        }
    </style>
</head>
<body>
    <iframe src="/swagger/index.html" id="iframe_swagger" name="iframe_swagger"></iframe>
</body>
</html>

3.設定Index.html為啟動頁

開啟Test.Web專案下的Properties/launchSettings.json檔案,launchUrl屬性值配置為:Index.html

4.設定專案生成輸出xml檔案

5.StartUp.cs檔案配置

(1)ConfigureServices方法下增加配置

            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new Info
                {
                    Version = "v1",
                    Title = "API",
                    Description = "api文件",
                    TermsOfService = "None"
                });
                var basePath = AppContext.BaseDirectory;
                var xmlPath = Path.Combine(basePath, "Test.Web.xml");
                var xmlPathByModel = Path.Combine(basePath, "Test.Model.xml");
                options.IncludeXmlComments(xmlPathByModel);    
                //true表示生成控制器描述,包含true的IncludeXmlComments過載應放在最後,或者兩句都使用true
                options.IncludeXmlComments(xmlPath,true);
            });

(2)Configure方法下增加配置

            app.UseStaticFiles();//啟用預設資料夾wwwroot
            app.UseSwagger();
            app.UseSwaggerUI(action =>
            {
                action.ShowExtensions();
                action.SwaggerEndpoint("/swagger/v1/swagger.json", "V1 Docs");
            });

到此,文件已經生成了,如圖:

點選對應的Model即可檢視輸入輸出引數註釋說明。

三、擴充套件(請求引數附帶Token)

webapi經常碰到介面需要驗證token的情況,使用Try it out測試時候怎麼提交Token呢

1.在StartUp.cs中新建一個類

    public class AddAuthTokenHeaderParameter : IOperationFilter
    {
        public void Apply(Operation operation, OperationFilterContext context)
        {
            if (operation.Parameters == null)
            {
                operation.Parameters = new List<IParameter>();
            }
            var attrs = context.ApiDescription.ActionDescriptor.AttributeRouteInfo;

            //先判斷是否是匿名訪問,
            var descriptor = context.ApiDescription.ActionDescriptor as ControllerActionDescriptor;
            if (descriptor != null)
            {
                var actionAttributes = descriptor.MethodInfo.GetCustomAttributes(inherit: true);
                bool isAnonymous = actionAttributes.Any(a => a is AllowAnonymousAttribute);
                //非匿名的方法,連結中新增accesstoken值
                if (!isAnonymous)
                {
                    operation.Parameters.Add(new NonBodyParameter()
                    {
                        Name = "token",
                        In = "query",//query header body path formData
                        Type = "string",
                        Required = true //是否必選
                    });
                }
            }
        }
    }

2.在上文的ConfigureServices的AddSwaggerGen中註冊新增的類:

options.OperationFilter<AddAuthTokenHeaderParameter>();

完整的StartUp.cs檔案如下:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace Test.Web
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new Info
                {
                    Version = "v1",
                    Title = "API",
                    Description = "api文件",
                    TermsOfService = "None"
                });
                var basePath = AppContext.BaseDirectory;
                var xmlPath = Path.Combine(basePath, "Test.Web.xml");
                var xmlPathByModel = Path.Combine(basePath, "Test.Model.xml");

                options.IncludeXmlComments(xmlPathByModel);    
                //true表示生成控制器描述,包含true的IncludeXmlComments過載應放在最後,或者兩句都使用true
                options.IncludeXmlComments(xmlPath,true);
                options.OperationFilter<AddAuthTokenHeaderParameter>();
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseMvc();
            app.UseStaticFiles();//啟用預設資料夾wwwroot
            app.UseSwagger();
            app.UseSwaggerUI(action =>
            {
                action.ShowExtensions();
                action.SwaggerEndpoint("/swagger/v1/swagger.json", "V1 Docs");
            });
        }
    }
    /// <summary>
    /// 新增Token引數
    /// </summary>
    public class AddAuthTokenHeaderParameter : IOperationFilter
    {
        /// <summary>
        /// 非匿名方法新增Token引數
        /// </summary>
        /// <param name="operation"></param>
        /// <param name="context"></param>
        public void Apply(Operation operation, OperationFilterContext context)
        {
            if (operation.Parameters == null)
            {
                operation.Parameters = new List<IParameter>();
            }
            var attrs = context.ApiDescription.ActionDescriptor.AttributeRouteInfo;

            //先判斷是否是匿名訪問,
            var descriptor = context.ApiDescription.ActionDescriptor as ControllerActionDescriptor;
            if (descriptor != null)
            {
                var actionAttributes = descriptor.MethodInfo.GetCustomAttributes(inherit: true);
                bool isAnonymous = actionAttributes.Any(a => a is AllowAnonymousAttribute);
                //非匿名的方法,連結中新增accesstoken值
                if (!isAnonymous)
                {
                    operation.Parameters.Add(new NonBodyParameter()
                    {
                        Name = "token",
                        In = "query",//query header body path formData
                        Type = "string",
                        Required = true //是否必選
                    });
                }
            }
        }
    }
}

生成的文件最終效果,點選Try it out 以後會生成一個填寫Token的輸入框: