webapi+swagger ui 文檔描述

代碼:GitHubhtml

swagger ui在咱們的.NET CORE和.NET Framework中的展示形式是不同的,若是有了解的,在.NET CORE中的是比.NET Framework好的。兩張圖對比下node

 .NET Framework中自帶的就是這個,樣式通常git

 

 

.NET CORE中:github

 

 

 一對比core中的明顯好看,本篇教你怎麼在Framework 環境中搭建下面的樣式,先看看效果,下面就是在Framework 環境搭建的效果:api

 

 

 

 

 

環境:Owinide

owin瞭解:http://www.javashuo.com/article/p-uivrzpid-hx.htmlpost

 注:怎麼搭建的能夠百度一下Owin,這邊主要是介紹要注意的幾點,源碼在github上。ui

 

①下載咱們的Swagger uithis

地址:https://github.com/swagger-api/swagger-uispa

下載dist文件夾的東西

 

添加到咱們的項目中,文件夾爲swagger

 

 ② nuget  Swashbuckle.Core

在App_Start中建立一個DocConfig 類,進行文檔配置

using Sealee.Util;
using Swashbuckle.Application;
using Swashbuckle.Swagger;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Http;
using System.Web.Http.Description;
using System.Xml;
using WebApiOwin.App_Start;

namespace WebApiOwin
{
    public class DocConfig
    {
        public static void Register(HttpConfiguration config)
        {
            Assembly _thisAssembly = typeof(DocConfig).Assembly;
            string _project = MethodBase.GetCurrentMethod().DeclaringType.Namespace;//項目命名空間

            //註釋  咱們的post提交都會建立Dto來申明,這邊添加了註釋,前臺頁面就會顯示
            string path = System.AppDomain.CurrentDomain.BaseDirectory;
            string _xmlPath = string.Format("{0}/bin/{1}.XML", path, _project);
            string path2 = path.GetSlnPath(2);
            string _xmlPath2 = Path.Combine(path2, "My.Entity\\bin\\My.Entity.xml");


            config.EnableSwagger(c =>
            {
                c.MultipleApiVersions(
                      (apiDesc, targetApiVersion) =>
                      {
                          //控制器描述
                          IEnumerable<string> versions = apiDesc.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<MyVersionAttribute>().Select(x => x.Version);
                          return versions.Any(v => $"{v.ToString()}" == targetApiVersion);
                      },
                      (vc) =>
                      {
                          //MyVersionAttribute 標識了這個屬性的都須要在這裏加上  這邊會配合index.html頁面完成
                          vc.Version("Token", "");
                          vc.Version("JwtUser", "");
                      });

                //c.SingleApiVersion("Token", "Super duper API");
                //忽略標記爲已刪除的屬性
                c.IgnoreObsoleteProperties();

                //多文檔描述
                //文檔描述
                c.IncludeXmlComments(_xmlPath);
                //文檔描述
                c.IncludeXmlComments(_xmlPath2);

                c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());

                c.CustomProvider((defaultProvider) =>
                {
                    //獲取描述
                    return new MySwaggerProvider(defaultProvider, _xmlPath);
                });

                //操做過濾
                c.OperationFilter<HttpHeadFilter>();
            }); //.EnableSwaggerUi()  重點:這邊咱們不須要他生成頁面,使用咱們剛剛下載dist中的頁面

        }
    }

    /// <summary>
    /// 設置SwaggerDocument 顯示的數據
    /// </summary>
    public class MySwaggerProvider : ISwaggerProvider
    {
        private static ConcurrentDictionary<string, SwaggerDocument> _cache =
               new ConcurrentDictionary<string, SwaggerDocument>();

        private readonly ISwaggerProvider _swaggerProvider;
        private readonly string _xmlPath;

        public MySwaggerProvider(ISwaggerProvider swaggerProvider, string xmlPath)
        {
            _swaggerProvider = swaggerProvider;
            _xmlPath = xmlPath;
        }

        public SwaggerDocument GetSwagger(string rootUrl, string apiVersion)
        {
            string cacheKey = string.Format("{0}_{1}", rootUrl, apiVersion);
            //只讀取一次
            if (!_cache.TryGetValue(cacheKey, out SwaggerDocument srcDoc))
            {
                srcDoc = _swaggerProvider.GetSwagger(rootUrl, apiVersion);
                ConcurrentDictionary<string, string> pairs = GetControllerDesc(apiVersion);
                //控制器描述
                IList<Tag> tagList = new List<Tag>();
                foreach (KeyValuePair<string, string> item in pairs)
                {
                    Tag tag = new Tag();
                    tag.name = item.Key;
                    tag.description = item.Value;
                    tagList.Add(tag);
                }
                srcDoc.tags = tagList;


                srcDoc.vendorExtensions = new Dictionary<string, object> {
                        { "ControllerDesc", pairs }
                    };
                _cache.TryAdd(cacheKey, srcDoc);
            }
            return srcDoc;
        }

        /// <summary>
        /// 從API文檔中讀取控制器描述
        /// </summary>
        private ConcurrentDictionary<string, string> GetControllerDesc(string apiVersion)
        {
            ConcurrentDictionary<string, string> controllerDescDict = new ConcurrentDictionary<string, string>();
            if (File.Exists(_xmlPath))
            {
                XmlDocument xmldoc = new XmlDocument();
                xmldoc.Load(_xmlPath);
                string type = string.Empty, path = string.Empty, controllerName = string.Empty;

                string[] arrPath;
                int length = -1, cCount = "Controller".Length;
                XmlNode summaryNode = null;
                foreach (XmlNode node in xmldoc.SelectNodes("//member"))
                {
                    type = node.Attributes["name"].Value;
                    if (type.StartsWith("T:"))
                    {
                        string[] typeName = type.Split(':');
                        Type t = Type.GetType(typeName[1]);

                        //控制器
                        arrPath = type.Split('.');
                        length = arrPath.Length;
                        controllerName = arrPath[length - 1];
                        if (controllerName.EndsWith("Controller"))
                        {
                            //若是分組了
                            if (t.GetCustomAttributes<MyVersionAttribute>().Count() != 0)
                            {
                                string version = t.GetCustomAttribute<MyVersionAttribute>().Version;
                                //上面tag和下面的須要同步過濾
                                if (version == apiVersion)
                                {
                                    //獲取控制器註釋
                                    summaryNode = node.SelectSingleNode("summary");
                                    string key = controllerName.Remove(controllerName.Length - cCount, cCount);
                                    if (summaryNode != null && !string.IsNullOrEmpty(summaryNode.InnerText) && !controllerDescDict.ContainsKey(key))
                                    {
                                        controllerDescDict.TryAdd(key, summaryNode.InnerText.Trim());
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return controllerDescDict;
        }
    }


    public class HttpHeadFilter : IOperationFilter
    {
        public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
        {
            // if (operation.parameters == null)
            //     operation.parameters = new List<Parameter>();
            ////判斷是否添加受權過濾器
            // var filterPipeline = apiDescription.ActionDescriptor.GetFilterPipeline();
            // var isAuthorized = filterPipeline.Select(fileInfo => fileInfo.Instance).Any(filter => filter is IAuthorizationFilter);
            // var allowAnonymous = apiDescription.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any();
            // if (isAuthorized&&!allowAnonymous)
            // {
            //     operation.parameters.Add(new Parameter { name = "Authorization", @in = "head", description = "token", required = false, type = "string" });

            // }                                                         

            if (operation == null)
            {
                return;
            }

            if (operation.parameters == null)
            {
                operation.parameters = new List<Parameter>();
            }
            if (operation.security == null)
            {
                operation.security = new List<IDictionary<string, IEnumerable<string>>>();
            }

            Parameter parameter = new Parameter
            {
                description = "The authorization token",
                @in = "header",
                name = "Authorization",
                required = true,
                type = "string"
            };


            //var parameter = new Parameter
            //{
            //    description = "The authorization token",
            //    @in = "header",
            //    name = "Authorization",
            //    required = true,
            //    type = "string"
            //};                            
            //顯示鎖標識
            if (apiDescription.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any())
            {
                //parameter.required = false;
            }
            else
            {
                Dictionary<string, IEnumerable<string>> oAuthRequirements = new Dictionary<string, IEnumerable<string>> { { "Authorization", new List<string>() } };
                operation.security.Add(oAuthRequirements);
            }
            // operation.parameters.Add(parameter);    
        }
    }
}
View Code

 

MyVersionAttribute 類用來顯示咱們的版本
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true)]
    public class MyVersionAttribute : Attribute
    {

        public MyVersionAttribute(string _version)
        {
            this.Version = _version;
        }

        /// <summary>
        /// 版本
        /// </summary>
        public string Version { get; set; }
    }

 最後在咱們的owin中添加DocConfig 

 

接口列子:

 

 

 ③修改咱們的Index.html頁面

文檔配置:https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md

 

 附受權,頁面上左邊的按鈕:

地址: https://github.com/aspnetboilerplate/eventcloud/blob/master/aspnet-core-angular/aspnet-core/src/EventCloud.Web.Host/wwwroot/swagger/ui/index.html

獲得這兩個js,應用到你的項目

 

 這邊就是這兩個js生成了受權按鈕,以及樣式,文本,而後把你受權須要的信息傳到後臺進行獲取token。看下這個js你就知道了,這邊不詳細介紹了.應爲項目中的受權不同這邊的代碼你也進行相應的修改才行,別直接Copy用。

受權:通常咱們的在接口中受權了的須要你攜帶token信息才能訪問。

 

 

 

 

 

 總結:最主要的仍是不要使用代碼生成的頁面,須要咱們的本身添加的頁面,而後進行配置就行了。

相關文章
相關標籤/搜索