代码:GitHub

swagger ui在我们的.NET CORE和.NET Framework中的展现形式是不一样的,如果有了解的,在.NET CORE中的是比.NET Framework好的。两张图对比下

.NET Framework中自带的就是这个,样式一般

.NET CORE中:

一对比core中的明显好看,本篇教你怎么在Framework 环境中搭建下面的样式,先看看效果,下面就是在Framework 环境搭建的效果:

环境:Owin

owin了解:https://www.cnblogs.com/neverc/p/4864414.html

注:怎么搭建的可以百度一下Owin,这边主要是介绍要注意的几点,源码在github上。

①下载我们的Swagger ui

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

下载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();
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 = -, 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[]); //控制器
arrPath = type.Split('.');
length = arrPath.Length;
controllerName = arrPath[length - ];
if (controllerName.EndsWith("Controller"))
{
//如果分组了
if (t.GetCustomAttributes<MyVersionAttribute>().Count() != )
{
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

附授权,页面上左边的按钮:

地址: 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信息才能访问。

隐藏接口:

[ApiExplorerSettings(IgnoreApi = true)]

总结:最主要的还是不要使用代码生成的页面,需要我们的自己添加的页面,然后进行配置就好了。

webapi+swagger ui 文档描述的更多相关文章

  1. MVC WebApi Swagger帮助文档 接口用法

    1.WebApi在解决方案Apps.WebApi中 2.将Apps.WebApi设置为启动项目之后,可以直接浏览到Api的帮助文档,并直接进行调试 3.登录接口 4.登录获取的token来访问其他接口 ...

  2. 使用Swagger实现webapi接口自动化文档生成

    这里是实现自动化api稳当的生成,在网上看了很多swagger的文档,可能都是在为实现接口时直接使用的swagger,其实步骤差不多,但是更加详细的我还没看到,又或者说,我看着文档来的时候还是出错啦, ...

  3. springboot+swagger接口文档企业实践(上)

    目录 1.引言 2.swagger简介 2.1 swagger 介绍 2.2 springfox.swagger与springboot 3. 使用springboot+swagger构建接口文档 3. ...

  4. Swagger API文档

    Swagger API文档集中化注册管理   接口文档是前后端开发对接时很重要的一个组件.手动编写接口文档既费时,又存在文档不能随代码及时更新的问题,因此产生了像swagger这样的自动生成接口文档的 ...

  5. Swagger在线文档使用教程

    springboot整合Swagger2 1.首先创建一个springboot工程,在pom文件内导入依赖   <!--swagger依赖-->      <!--Swagger2- ...

  6. .net core的Swagger接口文档使用教程(二):NSwag

    上一篇介绍了Swashbuckle ,地址:.net core的Swagger接口文档使用教程(一):Swashbuckle 讲的东西还挺多,怎奈微软还推荐了一个NSwag,那就继续写吧! 但是和Sw ...

  7. .net core的Swagger接口文档使用教程(一):Swashbuckle

    现在的开发大部分都是前后端分离的模式了,后端提供接口,前端调用接口.后端提供了接口,需要对接口进行测试,之前都是使用浏览器开发者工具,或者写单元测试,再或者直接使用Postman,但是现在这些都已经o ...

  8. Swagger 接口文档

    目录 Swagger 介绍 Swagger 依赖 SpringBoot 集成 Swagger 配置类 常用注解 效果示例 Swagger 介绍 Swagger UI 允许任何人(无论是开发团队还是最终 ...

  9. 使用Swashbuckle.AspNetCore生成.NetCore WEBAPI的接口文档

    一.问题 使用Swashbuckle.AspNetCore生成.NetCore WEBAPI的接口文档的方法 二.解决方案 参考文章:https://docs.microsoft.com/zh-cn/ ...

随机推荐

  1. 第一章 Java起源

    1.计算机语言发展史:B语言-->C语言-->C++语言-->Java语言.通过C和C++反过来理解Java的设计,理解更深: 复杂性:结构化变成=>面向对象编程:继承.封装. ...

  2. 【Java】Java环境变量配置

    一.windows系统 右键你的电脑(计算机/此电脑)打开属性->高级系统设置->环境变量,在系统变量里配置三个环境变量. 假设jdk的安装路径为C:\Program Files\Java ...

  3. The Difference between Gamification and Game-Based Learning

    http://inservice.ascd.org/the-difference-between-gamification-and-game-based-learning/ Have you trie ...

  4. React Virtual DOM Explained in Simple English

    If you are using React or learning React, you must have heard of the term “Virtual DOM”. Now what is ...

  5. Linked List Sorting

    静态链表(用结构体数组模拟链表)     1052 Linked List Sorting (25分)   A linked list consists of a series of structur ...

  6. RabbitMQ六种队列模式-路由模式

    前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅RabbitMQ六种队列模式-路由模式 [本文]RabbitMQ六种队列模式-主 ...

  7. 做个小插件(打开Part路径插件)

    1 (CAIDAN.men) VERSION EDIT UG_GATEWAY_MAIN_MENUBAR AFTER UG_HELP CASCADE_BUTTON TOOLS LABEL 工具 END_ ...

  8. bzoj1176: [Balkan2007]Mokia cdq

    链接 bzoj 思路 cdq入门题,拆成4个矩阵,然后cdq. 代码 /************************************************************** P ...

  9. request和response文件下载案例

    一.需求分析 * 文件下载需求: 1. 页面显示超链接 2. 点击超链接后弹出下载提示框 3. 完成图片文件下载 * 分析: 1. 超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,如果不能解析 ...

  10. python3-django+uwsgi+supervisor+nginx跳坑指南(记录)

    首先运行django项目:在项目目录内: python manage.py runserver 0.0.0.0:8000 外部服务器访问:http://www.xxx.com:8000/ 可以正常运行 ...