系列目录

.  创建项目并集成swagger

  1.1 创建

  1.2 完善

二. 搭建项目整体架构

三. 集成轻量级ORM框架——SqlSugar

  3.1 搭建环境

  3.2 实战篇:利用SqlSugar快速实现CRUD

  3.3 生成实体类

四. 集成JWT授权验证

 


 

 

前一章我们在项目中初步集成了swagger插件,但是还有一些问题需要解决,所以这一章要做的,就是完善swagger的相关设置。

 

  1. 设置swagger ui页面为启动页

在前一章的末尾,我们通过在域名后面输入/swagger后,成功访问到swagger ui页,但是我们发现每次运行项目,都会默认访问api/values这个接口,我想要将启动页设为swagger(或者是你画好的任一个html页),那应该怎么设置呢?

位置就在Properties下的launchSettings.json文件里,只要将profiles下的launchUrl改成你需要的地址就可以

【从零开始搭建自己的.NET Core Api框架】(一)创建项目并集成swagger:1.2 swagger的高级应用

 

当然,文件里还有其他一些基本设置,比如端口设置,就不一一说了。

 

  2. 注释问题

swagger很重要的一个功能,就是将我们接口的注释信息和参数(包括实体类)的注释信息显示到页面上。

现在我们分别将控制器、函数和参数添加相应的注释(添加方式是在类或函数的上一行敲三下“/”)

【从零开始搭建自己的.NET Core Api框架】(一)创建项目并集成swagger:1.2 swagger的高级应用

 

F5运行,发现swagger ui上并没有将它们显示出来。那是因为还缺少两步

 2.1项目生成xml注释文件

右键项目名称=>属性=>生成

勾选“输出”下面的“生成xml文档文件”,后面填写保存该文档的地址(xml文件的名字可以修改,但是不建议修改保存的路径,然后记住这个地址,待会会用到)

【从零开始搭建自己的.NET Core Api框架】(一)创建项目并集成swagger:1.2 swagger的高级应用

 

操作完之后,我们会发现错误列表会多出很多黄色的警告,提示“缺少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运行调试:

【从零开始搭建自己的.NET Core Api框架】(一)创建项目并集成swagger:1.2 swagger的高级应用

 

我们之前添加的注释就全部都出来了。

现在是不是突然觉得swagger很有用处了?

 

其实到这儿,细心的人都会发现,有一个地方还是没有显示注释,就是控制器的名称(在这个例子里就是values),我们之前在代码里明明也添加了注释,这里却没有显示出来,为什么?

好,接下来要放我个人私藏的大招了~

解决办法是:在项目中添加一个文件夹“SwaggerHelp”,在该文件加下添加类“SwaggerDocTag”,这个类的作用是根据控制器的名称向swagger ui额外附加注释,代码如下:

【从零开始搭建自己的.NET Core Api框架】(一)创建项目并集成swagger:1.2 swagger的高级应用

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
        }
    }
}

 

现在再次运行调试,你会发现,控制器的注释就可以显示了

【从零开始搭建自己的.NET Core Api框架】(一)创建项目并集成swagger:1.2 swagger的高级应用

 

这儿的“测试模块”的注释,其实是从SwaggerDocTag类中读取出来的,并不是控制器本身的注释。

然后,这只是我个人目前为止发现的最好好用的方法,如果有人有什么其他更好的解决办法,欢迎大家指教,互相学习~

 

BTW,这里提一下可能会遇到的问题:如果项目发布之后,或是上线服务器之后,发现注释又没了,十有八九是生成的xml文件路径的问题。可以按照之前的步骤,依次排查,重新修改路径就可以了。


 

【20180705】更新显示控制器注释方法:

经@陆韦里同学私信指教,现提供另一种swagger展示控制器注释的方法,思路如下:

其实我们对控制器添加的注释,已经生成在xml注释文档里了(APIHelp.xml),打开xml文档,如下:

【从零开始搭建自己的.NET Core Api框架】(一)创建项目并集成swagger:1.2 swagger的高级应用

 

仔细观察下,其实就能找到它的规律:我们需要的主要数据都在二级节点<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;
        }
    }
}
View Code

相关文章:

  • 2021-04-02
  • 2021-06-08
  • 2021-04-04
  • 2022-12-23
  • 2021-07-03
  • 2022-02-19
  • 2022-12-23
猜你喜欢
  • 2021-11-17
  • 2021-11-21
  • 2021-10-02
  • 2021-10-29
  • 2021-11-17
  • 2022-03-09
  • 2021-09-14
相关资源
相似解决方案