一.入门

https://www.nuget.org/packages/Swashbuckle.AspNetCore.SwaggerGen/

1.添加核心NUGET包 Swashbuckle.AspNetCore:

2.startup中配置:

ConfigureServices中:

           //注册swagger生成器,定义一个或多个swagger文档
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info
{
Version = "v1",
Title = "测试 API",
Description = "A simple example ASP.NET Core Web API",
TermsOfService = "None",
Contact = new Contact { Name = "ck", Email = "", Url = "http://www.cnblogs.com/chuankang/" },
License = new License { Name = "博客园", Url = "http://www.cnblogs.com/chuankang/" }
}); // api描述文档xml的生成地址和文件名,需要在项目的属性中进行配置
var basePath = AppContext.BaseDirectory;
var xmlPath = Path.Combine(basePath, "SwaggerDemo.xml");
if (File.Exists(xmlPath))
{
c.IncludeXmlComments(xmlPath);
}
});

Configure中:

        // 启用中间件以生成JSON作为JSON端点.
app.UseSwagger(); // 启用中间件以提供用户界面(HTML、js、CSS等),特别是指定JSON端点。
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
         //页面头名称
c.DocumentTitle = "平台API";
     //页面API文档格式 Full=全部展开, List=只展开列表, None=都不展开
c.DocExpansion(DocExpansion.List);
});

注意:c.SwaggerDoc的第一个参数 要和 c.SwaggerEndpoint第一个参数 字符串swagger/后面的对应,本例用的是v1

3.api描述文档xml的生成地址和文件名,需要在项目的属性中进行配置,右键项目-> 属性-> 生成 如下图:

加上1591忽略属性类名必须加xml注释

4.在controller中action方法都要指定http请求Post(新增),Put(修改),Delete(删除),Get(查询)中的一个,不然会报错:
http://localhost:55642/swagger/v1/swagger.json   浏览器F12控制台查看错误原因


5.启动看效果:

6.每次输入/swagger太麻烦,可以设置借助vs进行跳转,如下图加上 "launchUrl": "swagger" :

7.如果controller继承了自己定义的基类controller,要为自己定义的方法加上NonActionFillter,因为swagger要为每个action添加http mehod

二.设置多个API版本

ConfigureServices中: 
c.SwaggerDoc("v2", new Info
{
Version = "v2",
Title = "API 版本2"
});
Configure中:
c.SwaggerEndpoint("/swagger/v2/swagger.json", "API V2");

在action上指定版本,不指定版本的action在所有版本中都显示

三.修改默认路由

swagger给我们默认的路由是:http://localhost:49833/swagger/index.html

如果有很多个API项目怎么区分呢?我们可以指定路由把swagger替换掉

那么我们现在应该请求的路由为:http://localhost:49833/test/index.html

四.忽略过时的接口

为action指定Obsolete特性表示过时了,但并不表示不可以使用

运行:

怎么把这过时的接口不显示在swagger页面呢?

只需要在生成器中加入options.IgnoreObsoleteActions();属性就行了

五.忽略某个Api,不在ui页面中显示

六.仅获取某个Http请求的action

例如下面只获取HttpGet请求的接口显示在界面上

// ApiExplorerGetsOnlyConvention.cs
public class ApiExplorerGetsOnlyConvention : IActionModelConvention
{
public void Apply(ActionModel action)
{
action.ApiExplorer.IsVisible = action.Attributes.OfType<HttpGetAttribute>().Any();
}
} // Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(c =>
c.Conventions.Add(new ApiExplorerGetsOnlyConvention())
); ...
}

七.对action根据Http请求进行分组

services.AddSwaggerGen(c =>
{
...
c.TagActionsBy(api => api.HttpMethod);
};

八.指定接口排序规则

services.AddSwaggerGen(c =>
{
...
c.OrderActionsBy((apiDesc) => $"{apiDesc.ActionDescriptor.RouteValues["controller"]}_{apiDesc.HttpMethod}");
};

九.安装并启用注释

安装nuget Swashbuckle.AspNetCore.Annotations

启用:

services.AddSwaggerGen(c =>
{
... c.EnableAnnotations();
});

为controller加注释

为action加注释

[HttpPost]

[SwaggerOperation(
Summary = "Creates a new product",
Description = "Requires admin privileges",
OperationId = "CreateProduct",
Tags = new[] { "Purchase", "Products" }
)]
public IActionResult Create([FromBody]Product product)

为响应加验证

[HttpPost]
[SwaggerResponse(, "The product was created", typeof(Product))]
[SwaggerResponse(, "The product data is invalid")]
public IActionResult Create([FromBody]Product product)

十.Token验证

ConfigureServices添加

 public void ConfigureServices(IServiceCollection services)
{
#region swagger
services.AddSwaggerGen(c =>
{
//启用注释nuget包
c.EnableAnnotations();
c.SwaggerDoc("WebApiA", new Info { Title = "用户API接口A", Version = "v1" });
//var basePath = PlatformServices.Default.Application.ApplicationBasePath;
string basePath = AppContext.BaseDirectory;//Linux路径区分大小写,这里用appcontext
string xmlPath = Path.Combine(basePath, "WebApiA.xml");
//如果有xml注释文档就读取,需在项目属性生成xml
if (File.Exists(xmlPath))
{
c.IncludeXmlComments(xmlPath);
} #region Token绑定到ConfigureServices
//添加header验证信息
//c.OperationFilter<SwaggerHeader>();
var security = new Dictionary<string, IEnumerable<string>> { { "Blog.Core", new string[] { } }, };
c.AddSecurityRequirement(security);
//方案名称“Blog.Core”可自定义,上下一致即可
c.AddSecurityDefinition("Blog.Core", new ApiKeyScheme
{
Description = "JWT授权(数据将在请求头中进行传输) 直接在下框中输入{token}\"",
Name = "Authorization",//jwt默认的参数名称
In = "header",//jwt默认存放Authorization信息的位置(请求头中)
Type = "apiKey"
});
#endregion
});
#endregion #region Token服务注册
services.AddSingleton<IMemoryCache>(factory =>
{
var cache = new MemoryCache(new MemoryCacheOptions());
return cache;
});
services.AddAuthorization(options =>
{
options.AddPolicy("Client", policy => policy.RequireRole("Client").Build());
options.AddPolicy("Admin", policy => policy.RequireRole("Admin").Build());
options.AddPolicy("AdminOrClient", policy => policy.RequireRole("Admin,Client").Build());
});
#endregion services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

启动:

每次请求时,从Header报文中,获取密钥token,这里根据token可以进一步判断相应的权限等

添加类

JwtHelper:

using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using WebApiA.Models; namespace WebApiA.AuthHelper
{
/// <summary>
/// JWT序列化和反序列化
/// </summary>
public class JwtHelper
{
public static string SecretKey { get; set; } = "sdfsdfsrty45634kkhllghtdgdfss345t678fs";
/// <summary>
/// 颁发JWT字符串
/// </summary>
/// <param name="tokenModel"></param>
/// <returns></returns>
public static string IssueJWT(TokenModelJWT tokenModel)
{
var dateTime = DateTime.UtcNow;
var claims = new Claim[]
{
new Claim(JwtRegisteredClaimNames.Jti,tokenModel.Uid.ToString()),//Id
new Claim("Role", tokenModel.Role),//角色
new Claim(JwtRegisteredClaimNames.Iat,dateTime.ToString(),ClaimValueTypes.Integer64)
};
//秘钥
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtHelper.SecretKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var jwt = new JwtSecurityToken(
issuer: "Blog.Core",
claims: claims, //声明集合
expires: dateTime.AddHours(),
signingCredentials: creds); var jwtHandler = new JwtSecurityTokenHandler();
var encodedJwt = jwtHandler.WriteToken(jwt); return encodedJwt;
} /// <summary>
/// 解析
/// </summary>
/// <param name="jwtStr"></param>
/// <returns></returns>
public static TokenModelJWT SerializeJWT(string jwtStr)
{
var jwtHandler = new JwtSecurityTokenHandler();
JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr);
object role = new object(); ;
try
{
jwtToken.Payload.TryGetValue("Role", out role);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
var tm = new TokenModelJWT
{
Uid = Convert.ToInt32(jwtToken.Id),
Role = role != null ? role.ToString() : "",
};
return tm;
}
}
}

JwtTokenAuth:

/// <summary>
/// 中间件
/// </summary>
public class JwtTokenAuth
{
private readonly RequestDelegate _next;
public JwtTokenAuth(RequestDelegate next)
{
_next = next;
} public Task Invoke(HttpContext httpContext)
{
//检测是否包含'Authorization'请求头
if (!httpContext.Request.Headers.ContainsKey("Authorization"))
{
return _next(httpContext);
}
var tokenHeader = httpContext.Request.Headers["Authorization"].ToString(); TokenModelJWT tm = JwtHelper.SerializeJWT(tokenHeader);//序列化token,获取授权 //授权 注意这个可以添加多个角色声明,请注意这是一个 list
var claimList = new List<Claim>();
var claim = new Claim(ClaimTypes.Role, tm.Role);
claimList.Add(claim);
var identity = new ClaimsIdentity(claimList);
var principal = new ClaimsPrincipal(identity);
httpContext.User = principal; return _next(httpContext);
}
}

startup的Configure中加入

//将TokenAuth注册中间件
app.UseMiddleware<JwtTokenAuth>();

接口加权限filter

启动调用会报错

是因为每次操作请求,都会经过TokenAuth 中的Invoke方法,方法中对Header信息进行过滤,因为现在Header中,并没有相应的配置信息,看到这里,你就想到了,这个特别像我们常见的[HttpGet]等特性,没错!在.Net Core 中,到处都可以看到AOP编程,真的特别强大。

这个时候我们就用到了最开始的那个权限按钮

新建一个LoginController,来模拟一次登陆操作,简单传递几个参数,将用户角色和缓存时间传递,然后生成Token,并生成到缓存中,为之后做准备。

 [Route("api/[controller]")]
public class LoginController : Controller
{
/// <summary>
/// 获取JWT的重写方法,推荐这种,注意在文件夹OverWrite下
/// </summary>
/// <param name="id">id</param>
/// <param name="sub">角色</param>
/// <returns></returns>
[HttpGet]
[Route("Token2")]
public JsonResult GetJWTStr(long id = , string sub = "Admin")
{
//这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作
TokenModelJWT tokenModel = new TokenModelJWT();
tokenModel.Uid = id;
tokenModel.Role = sub; string jwtStr = JwtHelper.IssueJWT(tokenModel);
return Json(jwtStr);
}
}

调用获取tonken

复制到这里验证:

再次调用接口就可以了

示例代码:https://github.com/chuankang/DotNetCore/tree/master/OwnSpace/WebApiA

参考文档:https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/web-api-help-pages-using-swagger

https://github.com/domaindrivendev/Swashbuckle.AspNetCore

【Core Swagger】.NET Core中使用swagger的更多相关文章

  1. ASP.NET Core 3.0 WebApi中使用Swagger生成API文档简介

    参考地址,官网:https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/getting-started-with-swashbuckle?view ...

  2. 在.net core web api项目中安装swagger展示api接口(相当于生成api文档)

    1,  建立或打开项目后,在“程序包管理器控制台”中执行以下命令添加包引用: Install-Package Swashbuckle.AspNetCore 2,在项目中打开Startup.cs文件,找 ...

  3. NetCore 3.0 中使用Swagger生成Api说明文档及升级报错原因

    认识Swagger Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法,参 ...

  4. ASP.NET Core 1.0 中使用 Swagger 生成文档

    github:https://github.com/domaindrivendev/Ahoy 之前文章有介绍在ASP.NET WebAPI 中使用Swagger生成文档,ASP.NET Core 1. ...

  5. Asp.Net Core WebApi中接入Swagger组件(初级)

    开发WebApi时通常需要为调用我们Api的客户端提供说明文档.Swagger便是为此而存在的,能够提供在线调用.调试的功能和API文档界面. 环境介绍:Asp.Net Core WebApi + S ...

  6. Asp.Net Core中使用Swagger,你不得不踩的坑

    很久不来写blog了,换了新工作后很累,很忙.每天常态化加班到21点,偶尔还会到凌晨,加班很累,但这段时间,也确实学到了不少知识,今天这篇文章和大家分享一下:Asp.Net Core中使用Swagge ...

  7. ASP.NET Core Web API中使用Swagger

    本节导航 Swagger介绍 在ASP.NET CORE 中的使用swagger   在软件开发中,管理和测试API是一件重要而富有挑战性的工作.在我之前的文章<研发团队,请管好你的API文档& ...

  8. asp.net core 3.0 中使用 swagger

    asp.net core 3.0 中使用 swagger Intro 上次更新了 asp.net core 3.0 简单的记录了一下 swagger 的使用,那个项目的 api 比较简单,都是匿名接口 ...

  9. .net core在Ocelot网关中统一配置Swagger

    最近在做微服务的时候,由于我们是采用前后端分离来开发的,提供给前端的直接是Swagger,如果Swagger分布在各个API中,前端查看Swagger的时候非常不便,因此,我们试着将Swagger集中 ...

  10. Asp.Net Core WebApi (Swagger+EF Core/Code First)

    Swagger简介: Swagger™的目标是为REST APIs 定义一个标准的,与语言无关的接口,使人和计算机在看不到源码或者看不到文档或者不能通过网络流量检测的情况下能发现和理解各种服务的功能. ...

随机推荐

  1. 黑盒测试实践——day01

    一.任务进展情况 小组成员讨论了测试案例的选取以及测试工具的选取,目前正在设计合理的测试方法,研究待测试系统的功能需求和缺陷. 二.存在的问题 测试工具的使用还是不很清楚. 三.解决方法 通过上网搜集 ...

  2. 手写AVL 树(上)

    平衡二叉树 左旋,右旋,左右旋,右左旋 具体原理就不说了,网上教程很多.这里只实现了建树的过程,没有实现删除节点的操作. 下一篇会实现删除节点的操作. // // main.cpp // AVL // ...

  3. 代码块事务—TransactionScope

    今天上班遇到这样的业务:将删除的用户信息记录到记录表,再删除用户表中的信息. 可以说是不幸也可以说是幸运的. 在以往遇到这样的业务,我会考虑到各种出现异常或者失败的情况.在删除一张表数据失败的情况,对 ...

  4. PTA 树的遍历

    给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列.这里假设键值都是互不相等的正整数. 输入格式: 输入第一行给出一个正整数N(≤30),是二叉树中结点的个数.第二行给出其后序遍历序列.第三 ...

  5. Python加密保护解决方案

    防止代码反编译,高强度加密保护exe或pyc文件 产品简介 Python语言写的程序无需编译成二进制文件代码,可以直接从源代码运行程序.在计算机内部,Python解释器把源代码转换成字节码的中间形式, ...

  6. [摘抄] Bezier曲线、B样条和NURBS

    Bezier曲线.B样条和NURBS,NURBS是Non-Uniform Rational B-Splines的缩写,都是根据控制点来生成曲线的,那么他们有什么区别了?简单来说,就是: Bezier曲 ...

  7. cocos中FPS数值的含义

    在cocos2d-x 2.x ,大家都看到了左下角的FPS变成3行,多了两行数据. 1.最上面一行是指的当前场景的渲染批次.(简单理解为需要渲染多少个贴图出来) 2.中间一行是渲染每一帧需要的时间. ...

  8. day05 Python中的set集合

    集合是无序的,不重复的数据集合,它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键)的.以下是集合最重要的两点: 1.去重,把一个列表变成集合,就自动去重了. 2.关 ...

  9. JVM探秘1--JVM内存运行时区域划分

    Java程序员一般不需要太关注内存,因为操作内存的权力都交给了Java虚拟机,但是Java程序员必须需要了解JVM是如何使用内存的,否则一旦内存出现泄漏或事溢出的话,就会一筹莫展不知道从哪去入手排查问 ...

  10. vue条件语句v-if、v-else、v-else-if用法

    vue条件语句v-if.v-else.v-else-if用法 v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建.v-if 也是惰性的:如果在初始渲 ...