系列目录html
1.1 建立json
1.2 完善api
三. 集成轻量级ORM框架——SqlSugar服务器
3.1 搭建环境架构
四. 集成JWT受权验证ide
前一章咱们在项目中初步集成了swagger插件,可是还有一些问题须要解决,因此这一章要作的,就是完善swagger的相关设置。
1. 设置swagger ui页面为启动页
在前一章的末尾,咱们经过在域名后面输入/swagger后,成功访问到swagger ui页,可是咱们发现每次运行项目,都会默认访问api/values这个接口,我想要将启动页设为swagger(或者是你画好的任一个html页),那应该怎么设置呢?
位置就在Properties下的launchSettings.json文件里,只要将profiles下的launchUrl改为你须要的地址就能够
固然,文件里还有其余一些基本设置,好比端口设置,就不一一说了。
2. 注释问题
swagger很重要的一个功能,就是将咱们接口的注释信息和参数(包括实体类)的注释信息显示到页面上。
如今咱们分别将控制器、函数和参数添加相应的注释(添加方式是在类或函数的上一行敲三下“/”)
F5运行,发现swagger ui上并无将它们显示出来。那是由于还缺乏两步
2.1项目生成xml注释文件
右键项目名称=>属性=>生成
勾选“输出”下面的“生成xml文档文件”,后面填写保存该文档的地址(xml文件的名字能够修改,可是不建议修改保存的路径,而后记住这个地址,待会会用到)
操做完以后,咱们会发现错误列表会多出不少黄色的警告,提示“缺乏XML注释”。
这时只须要像以前那样,在类或函数的上面一行添加注释便可。(固然,若是没有强迫症的话,装做没看到也是不影响的~)
若是咱们按照刚才记住的地址去文件夹查看,也能看到对应xml文件。
2.2启动类中添加swagger服务来读取这个xml文件
从新编辑Startup.cs,修改ConfigureServices函数:
/// <summary> /// This method gets called by the runtime. Use this method to add services to the container. /// </summary> /// <param name="services"></param> public void ConfigureServices(IServiceCollection services) { services.AddMvc(); #region Swagger services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Version = "v1.1.0", Title = "Ray WebAPI", Description = "框架集合", TermsOfService = "None", Contact = new Swashbuckle.AspNetCore.Swagger.Contact { Name = "RayWang", Email = "2271272653@qq.com", Url = "http://www.cnblogs.com/RayWang" } }); //添加读取注释服务 var basePath = PlatformServices.Default.Application.ApplicationBasePath; var xmlPath = Path.Combine(basePath, "APIHelp.xml"); c.IncludeXmlComments(xmlPath); }); #endregion }
以上两步完成以后,F5运行调试:
咱们以前添加的注释就所有都出来了。
如今是否是忽然以为swagger颇有用处了?
其实到这儿,细心的人都会发现,有一个地方仍是没有显示注释,就是控制器的名称(在这个例子里就是values),咱们以前在代码里明明也添加了注释,这里却没有显示出来,为何?
好,接下来要放我我的私藏的大招了~
解决办法是:在项目中添加一个文件夹“SwaggerHelp”,在该文件加下添加类“SwaggerDocTag”,这个类的做用是根据控制器的名称向swagger ui额外附加注释,代码以下:
using Swashbuckle.AspNetCore.Swagger; using Swashbuckle.AspNetCore.SwaggerGen; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace CKPI.SwaggerHelp { /// <summary> /// Swagger注释帮助类 /// </summary> public class SwaggerDocTag : IDocumentFilter { /// <summary> /// 添加附加注释 /// </summary> /// <param name="swaggerDoc"></param> /// <param name="context"></param> public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context) { swaggerDoc.Tags = new List<Tag> { //添加对应的控制器描述 这个是我好不容易在issues里面翻到的 new Tag { Name = "Values", Description = "测试模块" }, }; } } }
接下来要去Startup.cs添加相应的服务:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using CKPI.SwaggerHelp; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Microsoft.Extensions.PlatformAbstractions; using Swashbuckle.AspNetCore.Swagger; namespace RayPI { /// <summary> /// /// </summary> public class Startup { /// <summary> /// /// </summary> /// <param name="configuration"></param> public Startup(IConfiguration configuration) { Configuration = configuration; } /// <summary> /// /// </summary> public IConfiguration Configuration { get; } /// <summary> /// This method gets called by the runtime. Use this method to add services to the container. /// </summary> /// <param name="services"></param> public void ConfigureServices(IServiceCollection services) { services.AddMvc(); #region Swagger services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Version = "v1.1.0", Title = "Ray WebAPI", Description = "框架集合", TermsOfService = "None", Contact = new Swashbuckle.AspNetCore.Swagger.Contact { Name = "RayWang", Email = "2271272653@qq.com", Url = "http://www.cnblogs.com/RayWang" } }); //添加注释服务 var basePath = PlatformServices.Default.Application.ApplicationBasePath; var xmlPath = Path.Combine(basePath, "APIHelp.xml"); c.IncludeXmlComments(xmlPath); //添加对控制器的标签(描述) c.DocumentFilter<SwaggerDocTag>(); }); #endregion } /// <summary> /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. /// </summary> /// <param name="app"></param> /// <param name="env"></param> public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseMvc(); #region Swagger app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiHelp V1"); }); #endregion } } }
如今再次运行调试,你会发现,控制器的注释就能够显示了
这儿的“测试模块”的注释,实际上是从SwaggerDocTag类中读取出来的,并非控制器自己的注释。
而后,这只是我我的目前为止发现的最好好用的方法,若是有人有什么其余更好的解决办法,欢迎你们指教,互相学习~
BTW,这里提一下可能会遇到的问题:若是项目发布以后,或是上线服务器以后,发现注释又没了,十有八九是生成的xml文件路径的问题。能够按照以前的步骤,依次排查,从新修改路径就能够了。
【20180705】更新显示控制器注释方法:
经@陆韦里同窗私信指教,现提供另外一种swagger展现控制器注释的方法,思路以下:
其实咱们对控制器添加的注释,已经生成在xml注释文档里了(APIHelp.xml),打开xml文档,以下:
仔细观察下,其实就能找到它的规律:咱们须要的主要数据都在二级节点<members>里,三级节点<member>有一个name属性,这个name的值凡是以“T:”开头的表示的都是类,凡是以“M:”开头的表示的都是函数,其中类里面凡是控制器必然会以“Controller”结尾。
因此咱们要写一个读取xml的函数,根据这个规则,将注释提取出来,就能够了。
Stratup.cs里之前地配置不须要改变,只须要从新编辑SwaggerHelp下面的SwaggerDocTag.cs,添加一个GetControllerDesc函数,SwaggerDocTag.cs的完整代码以下:


using Microsoft.Extensions.PlatformAbstractions; using Swashbuckle.AspNetCore.Swagger; using Swashbuckle.AspNetCore.SwaggerGen; using System.Collections.Generic; using System.IO; using System.Xml; namespace RayPI.SwaggerHelp { /// <summary> /// Swagger注释帮助类 /// </summary> public class SwaggerDocTag : IDocumentFilter { /// <summary> /// 添加附加注释 /// </summary> /// <param name="swaggerDoc"></param> /// <param name="context"></param> public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context) { /* swaggerDoc.Tags = new List<Tag> { //添加对应的控制器描述 这个是我好不容易在issues里面翻到的 new Tag { Name = "Admin", Description = "后台" }, new Tag { Name = "Client", Description = "客户端" }, new Tag { Name = "System", Description = "系统" } }; */ swaggerDoc.Tags = GetControllerDesc(); } /// <summary> /// 从xml注释中读取控制器注释 /// </summary> /// <returns></returns> private List<Tag> GetControllerDesc() { List<Tag> tagList = new List<Tag>(); var basePath = PlatformServices.Default.Application.ApplicationBasePath; var xmlpath = Path.Combine(basePath, "APIHelp.xml"); if (!File.Exists(xmlpath))//检查xml注释文件是否存在 return tagList; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(xmlpath); string memberName = string.Empty;//xml三级节点的name属性值 string controllerName = string.Empty;//控制器完整名称 string key = string.Empty;//控制器去Controller名称 string value = string.Empty;//控制器注释 foreach (XmlNode node in xmlDoc.SelectNodes("//member"))//循环三级节点member { memberName = node.Attributes["name"].Value; if (memberName.StartsWith("T:"))//T:开头的表明类 { string[] arrPath = memberName.Split('.'); controllerName = arrPath[arrPath.Length - 1]; if (controllerName.EndsWith("Controller"))//Controller结尾的表明控制器 { XmlNode summaryNode = node.SelectSingleNode("summary");//注释节点 key = controllerName.Remove(controllerName.Length - "Controller".Length, "Controller".Length); if (summaryNode != null && !string.IsNullOrEmpty(summaryNode.InnerText) && !tagList.Contains(new Tag { Name = key })) { value = summaryNode.InnerText.Trim(); tagList.Add(new Tag { Name = key, Description = value }); } } } } return tagList; } } }
点击F5运行,控制器的注释就显示出来了。
【20180705】再次更新显示控制器注释方法:
此次应该是终极解决办法了,并且这个方法其实swagger已经帮咱们集成好了~
其中给swagger添加xml注释文件的函数叫“IncludeXmlComments”,F12跳转到定义,摘要是这样的:
// // 摘要: // Inject human-friendly descriptions for Operations, Parameters and Schemas based // on XML Comment files // // 参数: // filePath: // An abolsute path to the file that contains XML Comments // // includeControllerXmlComments: // Flag to indicate if controller XML comments (i.e. summary) should be used to // assign Tag descriptions. Don't set this flag if you're customizing the default // tag for operations via TagActionsBy. public void IncludeXmlComments(string filePath, bool includeControllerXmlComments = false);
能够看到,函数其实十有两个参数的,只是第二个参数默认设置了false,而这个参数就是设置是否显示显示控制器注释的。。。
因此只须要更改Startup.cs下ConfigureServices函数中的swagger配置就好了:
c.IncludeXmlComments(apiXmlPath, true);//添加控制器层注释(true表示显示控制器注释)
20180703更新:添加headers受权验证
3. 为Swagger添加头部受权验证功能
当接口添加了受权验证以后,咱们是不能直接调用该接口,通常须要在发起的http请求的headers中添加“令牌"进行验证。用过Postman的应该知道,Postman是能够手动在headers中添加字段的,下面就要实现swagger添加headers的功能。
这里以JWT受权验证为例,若是须要了解JWT受权验证的,能够去该系列的第四篇【从零开始搭建本身的.NET Core Api框架】(四)实战!带你半个小时实现JWT受权验证,有专门介绍。
打开Startup.cs,咱们须要在ConfigService函数中添加以下服务:
services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Version = "v1.1.0", Title = "Ray WebAPI", Description = "框架集合", TermsOfService = "None", Contact = new Swashbuckle.AspNetCore.Swagger.Contact { Name = "RayWang", Email = "2271272653@qq.com", Url = "http://www.cnblogs.com/RayWang" } }); //添加注释服务 var basePath = PlatformServices.Default.Application.ApplicationBasePath; var xmlPath = Path.Combine(basePath, "APIHelp.xml"); c.IncludeXmlComments(xmlPath); //添加对控制器的标签(描述) c.DocumentFilter<SwaggerDocTag>(); //手动高亮 //添加header验证信息 //c.OperationFilter<SwaggerHeader>(); var security = new Dictionary<string, IEnumerable<string>> { { "Bearer", new string[] { } }, }; c.AddSecurityRequirement(security);//添加一个必须的全局安全信息,和AddSecurityDefinition方法指定的方案名称要一致,这里是Bearer。 c.AddSecurityDefinition("Bearer", new ApiKeyScheme { Description = "JWT受权(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\"", Name = "Authorization",//jwt默认的参数名称 In = "header",//jwt默认存放Authorization信息的位置(请求头中) Type = "apiKey" }); });
完成以后,F5运行,swagger ui页面就会多出一个按钮"Authorize",点击能够跳出token填写页面,做用能够去看第四章,这里就不讲了
【20180714】更新:设置swagger显示实体类信息(swagger读取多个xml注释文件)
4. 显示实体类注释
咱们的WebApi接口大部分都是以实体类做为对象来传输的,可是swagger若是不设置的话是看不到这些实体类的注释的。
好比,实体类Student以下:
“添加学生”接口,须要接收一个“Student”类:
这里swagger只是把该实体类的字段一一列出来供测试填写数据,可是却看不到注释。
再好比,“获取单个学生”接口,调用 后会返回一个学生实体,可是Responses信息中却只显示了一个200的状态码,而没有显示该返回的实体类的信息:
下面,就来解决这个问题:
1)项目生成xml注释文件
这一步和以前同样,只是项目要选择实体类所在项目,而不是控制器层的项目:
这里注意点是,XML文档文件的路径最好选择到控制器层XML注释文件相同的路径下,若是生成成功,打开文件夹能够看到生成的xml文件:
2)设置swagger读取该xml注释文件
完整的ConfigureServices下swagger配置以下:
services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Version = "v1.1.0", Title = "Ray WebAPI", Description = "框架集合", TermsOfService = "None", Contact = new Swashbuckle.AspNetCore.Swagger.Contact { Name = "RayWang", Email = "2271272653@qq.com", Url = "http://www.cnblogs.com/RayWang" } }); //添加注释服务 var basePath = PlatformServices.Default.Application.ApplicationBasePath; var apiXmlPath = Path.Combine(basePath, "APIHelp.xml"); var entityXmlPath = Path.Combine(basePath, "EntityHelp.xml"); c.IncludeXmlComments(apiXmlPath, true);//控制器层注释(true表示显示控制器注释) c.IncludeXmlComments(entityXmlPath); //添加控制器注释 //c.DocumentFilter<SwaggerDocTag>(); //添加header验证信息 //c.OperationFilter<SwaggerHeader>(); var security = new Dictionary<string, IEnumerable<string>> { { "Bearer", new string[] { } }, }; c.AddSecurityRequirement(security);//添加一个必须的全局安全信息,和AddSecurityDefinition方法指定的方案名称要一致,这里是Bearer。 c.AddSecurityDefinition("Bearer", new ApiKeyScheme { Description = "JWT受权(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\"", Name = "Authorization",//jwt默认的参数名称 In = "header",//jwt默认存放Authorization信息的位置(请求头中) Type = "apiKey" }); });
到这,第一个问题,接受实体类就能够显示注释了:
3)控制器的接口函数头设置标签
在接口的头部添加标签:
[ProducesResponseType(typeof(Student),200)]
代表该接口返回实体类类型。以下图例:
再次运行项目,查看获取单个学生接口:
点击黑框上面“Model”字样,还能够查看该类的注释~
另外,swagger还在接口的下方很贴心的生成了一个用于显示实体Model模块:
到这,咱们的第一章的内容“搭建项目和集成sawgger”就结束了,若是有问题,欢迎留言一块儿讨论,互相学习。
原本想着代码比较简单,就不放源码,可是考虑以后,仍是决定上传一下。正好也定个规矩,这个系列后面每完成一个大的章节以后,都上传一份源码。这样也是给本身一个交代吧。
源码下载:点击查看下载地址
下一章的内容是项目架构的搭建和集成SqlSugar