代碼: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); } } }
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
附受權,頁面上左邊的按鈕:
獲得這兩個js,應用到你的項目
這邊就是這兩個js生成了受權按鈕,以及樣式,文本,而後把你受權須要的信息傳到後臺進行獲取token。看下這個js你就知道了,這邊不詳細介紹了.應爲項目中的受權不同這邊的代碼你也進行相應的修改才行,別直接Copy用。
受權:通常咱們的在接口中受權了的須要你攜帶token信息才能訪問。
總結:最主要的仍是不要使用代碼生成的頁面,須要咱們的本身添加的頁面,而後進行配置就行了。