代码: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. sleep、yield、wait、join的区别(阿里)

    只有runnable到running时才会占用cpu时间片,其他都会出让cpu时间片.线程的资源有不少,但应该包含CPU资源和锁资源这两类.sleep(long mills):让出CPU资源,但是不会 ...

  2. c+多态的本质:编译器维护了类型信息同时插入了解释执行机制

    Calling a virtual function is slower than calling a non-virtual function for a couple of reasons: Fi ...

  3. Linux/Windows 配置config 使用ssh连接

    Linux 产看本地是否有ssh 公私钥 1 cd ~/.ssh 2 ls -a 有的话继续(没有 ssh-keygen 生成) 将公钥内容复制到要连接的服务器用户下 方法一 ssh-copy-id ...

  4. matlab 只安装部分产品

  5. Harbor基础

    harbor: Harbor是构建企业级私有docker镜像的仓库的开源解决方案,它是Docker Registry的更高级封装,它除了提供友好的Web UI界面,角色和用户权限管理,用户操作审计等功 ...

  6. nginx 访问控制之 user_agent

    user_agent大家并不陌生,可以简单理解成浏览器标识,包括一些蜘蛛爬虫都可以通过user_agent来辨识. 通过访问日志,可以发现一些搜索引擎的蜘蛛对网站访问特别频繁,它们并不友好. 为了减少 ...

  7. #Ubuntu 14.04 系统下载

    http://mirrors.aliyun.com/ubuntu-releases/14.04/

  8. 「BJOI2018」治疗之雨

    传送门 Description 有\(m+1\)个数,第一个数为\(p\),每轮:选一个数\(+1\),再依次选\(k\)个数\(-1\) 要求如果第一个数\(=N\),不能选它\(+1\),如果第一 ...

  9. SpringSecurity匿名用户访问权限

    在SpringSecurity中定义一个匿名访问权限,实现未登录用户可以访问默写页面 <http use-expressions="false" entry-point-re ...

  10. IDE 问题及解决

    目录 Eclipse 篇 1.MarketPlace 打不开,对话框闪退 2.使用 lombok ,预编译不通过 3.Eclipse + PyDev - > Unresolved import: ...