【Core Swagger】.NET Core中使用swagger
一.入门
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(201, "The product was created", typeof(Product))] [SwaggerResponse(400, "The product data is invalid")] public IActionResult Create([FromBody]Product product)
十.Token验证
ConfigureServices添加
public void ConfigureServices(IServiceCollection services){#region swaggerservices.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路径区分大小写,这里用appcontextstring xmlPath = Path.Combine(basePath, "WebApiA.xml");//如果有xml注释文档就读取,需在项目属性生成xmlif (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());});#endregionservices.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()),//Idnew 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(2),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;}} }
View Code
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,获取授权//授权 注意这个可以添加多个角色声明,请注意这是一个 listvar 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);}}
View Code
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 = 1, 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
转载于:https://www.cnblogs.com/chuankang/p/8783761.html
【Core Swagger】.NET Core中使用swagger相关推荐
- [第二篇]如何在ASP.Net Core的生产环境中使用OAuth保护swagger ui
在我上篇文章如何在ASP.Net Core的生产环境中保护swagger ui中,我们讨论了如何使用基本身份验证来保护 swagger ui. 使用 OAuth 2.0 和 OpenIdConnect ...
- asp.net core 3.0 中使用 swagger
asp.net core 3.0 中使用 swagger Intro 上次更新了 asp.net core 3.0 简单的记录了一下 swagger 的使用,那个项目的 api 比较简单,都是匿名接口 ...
- ASP.NET Core Web API中使用Swagger
本节导航 Swagger介绍 在ASP.NET CORE 中的使用swagger 在软件开发中,管理和测试API是一件重要而富有挑战性的工作.在我之前的文章<研发团队,请管好你的API文档& ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - 再说Swagger,分组、描述、小绿锁
基于 abp vNext 和 .NET Core 开发博客项目 - 再说Swagger,分组.描述.小绿锁 https://github.com/Meowv/Blog 在开始本篇正文之前,解决一个 @ ...
- .NET Core API文档管理组件 Swagger
Swagger这个优秀的开源项目相信大家都用过,不多介绍了,这里简单记录一下使用过程. 开源地址:https://github.com/domaindrivendev/Swashbuckle.AspN ...
- 【 .NET Core 3.0 】框架之三 || swagger的使用
一.为什么使用Swagger 上文中已经说到,单纯的项目接口在前后端开发人员使用是特别不舒服的,那所有要推荐一个,既方便又美观的接口文档说明框架,当当当,就是Swagger,随着互联网技术的发展,现在 ...
- asp.net core系列 37 WebAPI 使用OpenAPI (swagger)中间件
一.概述 在使用Web API时,对于开发人员来说,了解其各种方法可能是一项挑战.在ASP.NET Core上,Web api 辅助工具介绍二个中间件,包括:Swashbuckle和NSwag .NE ...
- Swagger在header中添加token
概述 平常做项目使用mvc+webapi,采取前后端分离的方式,后台提供API接口给前端开发人员.这个过程中遇到一个问题后台开发人员怎么提供接口说明文档给前端开发人员.为了解决这个问题,项目中引用sw ...
- Spring Cloud Zuul中使用Swagger汇总API接口文档
有很多读者问过这样的一个问题: 虽然使用Swagger可以为Spring MVC编写的接口生成了API文档,但是在微服务化之后,这些API文档都离散在各个微服务中,是否有办法将这些接口都整合到一个文档 ...
- 在spring boot中集成Swagger
Swagger 在spring boot中集成Swagger 新建一个swagger项目 maven依赖 <!-- https://mvnrepository.com/artifact/io.s ...
最新文章
- 编译语言与解释语言,动态与静态,以及强类型和弱类型的区别
- ArcSDE、ArcGis Engine、ArcGis Desktop的授权配置
- P3919 【模板】可持久化数组(可持久化线段树/平衡树)
- 周志华领衔撰写,历时4年,宝箱书问世!文末送书
- Block循环引用问题(Objective-c)
- 基于FPGA实现压缩算法
- Phoenix的数据类型和操作符、函数
- 入侵感知系列之弱口令检测思路
- WinForm和WPF的区别
- devc语言图形编程教程_devc编程软件程序怎么调试 devc调试步骤图文方法教程
- 麦吉尔 计算机科学学分,麦吉尔大学计算机
- 淘淘商城---8.10
- 让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法
- 一筐鸡蛋编程解题Java_一筐鸡蛋总共369个标准答案怎么算的?求法解答公式解题步骤...
- 华为机考108题(c++)(41-51)
- bzoj1085 骑士精神
- 第三章:fog(恐惧感 fear,责任感obligation,罪恶感guilty)
- Ubuntu_ROS中应用kinect v2笔记
- 【实战】一次对某涩情 app 的渗透
- [Unity] 战斗系统学习 12:Switchable 1
热门文章
- 深度学习《CNN架构续篇 - 学习率衰减》
- threadpoolexecutor参数_ThreadPoolExecutor的使用
- python比较两个文件内容是否相同_python比较两个列表是否相等的方法
- matlab中double 和single数据类型的差别
- Python3 SSH远程连接服务器
- ahp层次分析法软件_层次分析法在历史街区研究中的应用简析
- 【小程序】【Tips】【前端】交互【后端】从Json对象数组里面获取数据的方法 - PHP - JS 的原生方法
- 超级vga显示卡_VGA视频采集卡常见故障分析
- python判断质数用for循环_Day3.Python判断与循环语句
- linux io100的原因_Unix与Linux的区别与联系