编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

基于.NetCore和ABP.VNext的项目实战二:Swagger

wxchong 2024-07-05 01:53:31 开源技术 15 ℃ 0 评论

Mag.Blog.Swagger层添加Volo.Abp.AspNetCore和Swashbuckle.AspNetCore包,引用实体层.Domain

添加模块类MagBlogSwaggerModule.cs,依赖MagBlogDomainModule模块,并且重写ConfigureServices和OnApplicationInitialization方法

namespace Mag.Blog.Swagger
{
    [DependsOn(typeof(MagBlogDomainModule))]
    public class MagBlogSwaggerModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            base.ConfigureServices(context);
        }
        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            base.OnApplicationInitialization(context);
        }
    }
}

新建扩展类MagBlogSwaggerExtensions.cs,编写两个扩展方法AddSwagger和UseSwaggerUI,

在AddSwagger方法中引用我们的XML文件,配置接口的名称版本以及描述信息,在UseSwaggerUI方法中使用SwaggerUI。并在MagBlogSwaggerModule中引用

namespace Mag.Blog.Swagger
{
    public static class MagBlogSwaggerExtensions
    {
        public static IServiceCollection AddSwagger(this IServiceCollection services)
        {
            return services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new OpenApiInfo
                {
                    Version = "1.0.0",
                    Title = "Mag.Blog.API",
                    Description = "Mag.Blog 接口文档(.NetCore+ABP.VNext)"
                });

                options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "Mag.Blog.HttpApi.xml"));
                options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "Mag.Blog.Domain.xml"));
                options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "Mag.Blog.Application.Contracts.xml"));

            });
            
        }

        public static void UseSwaggerUI(this IApplicationBuilder app)
        {
            app.UseSwaggerUI(options =>
            {
                options.SwaggerEndpoint(#34;/swagger/v1/swagger.json", "Mag.Blog.HttpApi接口");
            });
        }
    }
}
namespace Mag.Blog.Swagger
{
    [DependsOn(typeof(MagBlogDomainModule))]
    public class MagBlogSwaggerModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            context.Services.AddSwagger();
        }
        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            context.GetApplicationBuilder().UseSwagger().UseSwaggerUI();
        }
    }
}

在Mag.Blog.HttpApi.Hosting层的的启动模块中引用Swagger,FrameworkCore层

namespace Mag.Blog.HttpApi.Hosting
{
    [DependsOn(
           typeof(AbpAspNetCoreMvcModule),
           typeof(AbpAutofacModule),
        typeof(MagBlogHttpApiModule),
        typeof(MagBlogFrameworkCoreModule),
        typeof(MagBlogSwaggerModule)
        )]
    public class MagBlogHttpApiHostingModule : AbpModule
    {
        ....

    }

F5运行项目

项目结构显示为

因为一个项目可能存在多个不同种类的接口,对他们进行分组可以有效的区分开来。在扩展方法MagBlogSwaggerExtensions中新建一个内部类:SwaggerApiInfo

public class SwaggerApiInfo
{
    /// <summary>
    /// Url前缀
    /// </summary>
    public string UrlPrefix { get; set; }
    /// <summary>
    /// 名称
    /// </summary>
    public string Name { get; set; }
    /// <summary>
    /// 接口描述
    /// </summary>
    public OpenApiInfo OpenApiInfo { get; set; }
}

options.SwaggerDoc(...)改成接收两个参数:string name, OpenApiInfo info。

name:为当前分组的前缀;OpenApiInfo:配置三个参数,Version、Title、Description,version:可以将其配置在appsettings.json中,可以动态修改,通过AppSettings.cs读取;

UrlPrefix:分别为,API1,API2,API3,API4...在Domain.Shared层中为其定义好常量

description:定义一个变量,内容自拟主要是一些介绍性的描述,将在Swagger界面进行显示

//appsettings.json
{
  "ApiVersion": "1.0.0",
}
//AppSettings.cs       
 /// <summary>
        /// swagger版本
        /// </summary>
        public static string ApiVersion => _config["ApiVersion"];
    //MagBlogConsts.cs
...
/// <summary>
    /// swagger分组
    /// </summary>
    public static class Grouping
    {
        /// <summary>
        /// 博客前台接口组
        /// </summary>
        public const string GroupName_API_1 = "API_1";

        /// <summary>
        /// 博客后台接口组
        /// </summary>
        public const string GroupName_API_2 = "API_2";

        /// <summary>
        /// 其他通用接口组
        /// </summary>
        public const string GroupName_API_3 = "API_3";

        /// <summary>
        /// JWT授权接口组
        /// </summary>
        public const string GroupName_API_4 = "API_4";
    }
...

然后在扩展类MagBlogSwaggerExtensions.cs中新建一个List<SwaggerApiInfo>手动为其初始化一些值,记录swagger的分组信息,在AddSwagger方法、UseSwaggerUI方法中遍历使用。

using Mag.Blog.Common;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerUI;
using System;
using System.Collections.Generic;
using System.IO;

namespace Mag.Blog.Swagger
{
    public static class MagBlogSwaggerExtensions
    {
        public static IServiceCollection AddSwagger(this IServiceCollection services)
        {
            return services.AddSwaggerGen(options =>
            {
                //options.SwaggerDoc("v1", new OpenApiInfo
                //{
                //    Version = "1.0.0",
                //    Title = "Mag.Blog.API",
                //    Description = "Mag.Blog 接口文档(.NetCore+ABP.VNext)"
                //});

                //遍历swagger信息
                apiInfos.ForEach(apiInfo =>
                {
                    options.SwaggerDoc(apiInfo.UrlPrefix, apiInfo.OpenApiInfo);
                });

                options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "Mag.Blog.HttpApi.xml"));
                options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "Mag.Blog.Domain.xml"));
                options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "Mag.Blog.Application.Contracts.xml"));

            });

        }

        public static void UseSwaggerUI(this IApplicationBuilder app)
        {
            app.UseSwaggerUI(options =>
            {
                //options.SwaggerEndpoint(#34;/swagger/v1/swagger.json", "Mag.Blog.HttpApi接口");
                apiInfos.ForEach(apiInfo =>
                {
                    options.SwaggerEndpoint(#34;/swagger/{apiInfo.UrlPrefix}/swagger.json", apiInfo.Name);
                });
            });
        }
        /// <summary>
        /// 获取appsettings.json中设置版本
        /// </summary>
        private static readonly string version = #34;v{AppSettings.ApiVersion}";
        /// <summary>
        /// Swagger描述信息
        /// </summary>
        private static readonly string description = @"<b>CSDN</b>:<a target=""_blank"" href=""https://blog.csdn.net/yigu4011?spm=1011.2415.3001.5343"">https://blog.csdn.net/yigu4011?spm=1011.2415.3001.5343</a> <b>头条号</b>:<a target=""_blank"" href=""https://www.toutiao.com/c/user/token/MS4wLjABAAAAFen-NnTFKSSXr-wQ777uFrHr73F9sJynU1dQ5Ud2PLA/?"">https://www.toutiao.com/c/user/token/MS4wLjABAAAAFen-NnTFKSSXr-wQ777uFrHr73F9sJynU1dQ5Ud2PLA/?</a> <b>Hangfire</b>:<a target=""_blank"" href=""/hangfire"">任务调度中心</a> <code>Powered by .NET Core 3.1 on Linux</code>";

        /// <summary>
        /// swagger分组信息,遍历使用
        /// </summary>
        private static readonly List<SwaggerApiInfo> apiInfos = new List<SwaggerApiInfo>()
        {
            new SwaggerApiInfo
            {
                UrlPrefix=Grouping.GroupName_API_1,
                Name="博客前台接口",
                OpenApiInfo=new OpenApiInfo
                {
                    Version=version,
                    Title="MagCore - 博客前台接口",
                    Description=description
                }
            },
            new SwaggerApiInfo
            {
                UrlPrefix=Grouping.GroupName_API_2,
                Name="博客后台接口",
                OpenApiInfo =new OpenApiInfo
                {
                    Version=version,
                    Title="MagCore - 博客后台接口",
                    Description=description
                }
            },
            new SwaggerApiInfo
            {
                UrlPrefix=Grouping.GroupName_API_3,
                Name="通用公共接口",
                OpenApiInfo=new OpenApiInfo
                {
                    Version=version,
                    Title="MagCore - 通用公共接口",
                    Description = description
                }
            },
            new SwaggerApiInfo
            {
                UrlPrefix=Grouping.GroupName_API_4,
                Name="JWT授权接口",
                OpenApiInfo=new OpenApiInfo
                {
                   Version=version,
                   Title="MagCore - JWT授权接口",
                   Description  =description
                }
            }

        };
        public class SwaggerApiInfo
        {
            /// <summary>
            /// Url前缀
            /// </summary>
            public string UrlPrefix { get; set; }
            /// <summary>
            /// 名称
            /// </summary>
            public string Name { get; set; }
            /// <summary>
            /// 接口描述
            /// </summary>
            public OpenApiInfo OpenApiInfo { get; set; }
        }
    }
}

Swagger配置路由,运行项目默认进入swagger界面。

options.DefaultModelsExpandDepth(-1);是模型的默认扩展深度,设置为 -1 完全隐藏模型。

options.DocExpansion(DocExpansion.List);代表API文档仅展开标记,不默然展开所有接口,需要我们手动去点击才展开,可以自行查看DocExpansion。

options.RoutePrefix = string.Empty;代表路由设置为空,直接打开页面就可以访问了。

options.DocumentTitle = "接口文档 - MagCore???";是设置文档页面的标题的。

...
        public static void UseSwaggerUI(this IApplicationBuilder app)
        {
            app.UseSwaggerUI(options =>
            {
                //options.SwaggerEndpoint(#34;/swagger/v1/swagger.json", "Mag.Blog.HttpApi接口");
                apiInfos.ForEach(apiInfo =>
                {
                    options.SwaggerEndpoint(#34;/swagger/{apiInfo.UrlPrefix}/swagger.json", apiInfo.Name);
                });

                //模型的默认扩展深度,设置为-1完全隐藏模型
                options.DefaultModelExpandDepth(-1);
                //API 文档仅展开标记
                options.DocExpansion(DocExpansion.List);
                //API 前缀设置为空
                options.RoutePrefix = string.Empty;
                //API 页面title
                options.DocumentTitle = "接口文档 - MagCore???";
            });
        }
...

在Controller中使用 Attribute:[ApiExplorerSettings(GroupName = ...)]指定是哪个分组

F5运行项目

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表