• .NET Core Swagger 的分组使, 以及相同Action能被多个分组公用,同时加载出尚未分组的数据出来


    .NET Core Swagger 的分组使, 以及相同Action能被多个分组公用,同时加载出尚未分组的数据出来

    1.本文章参考(https://www.cnblogs.com/caijt/p/10739841.html)改写的 一对多分组模式。需要一对一的可以参考

    2.本文主要讲的是 一对多 分组公用, 同时把尚未分组的加载出来

    3.效果演示GIF图:

    具体操作代码如下:

    1.在项目创建一个目录(ApiGroup),然后创建三个类,分别为ApiGroupAttribute.cs(控制器特性),ApiGroupNames.css(系统分组枚举),GroupInfoAttribute.cs(给系统分组枚举值增加相关信息的特性,这个主要是用于在Swagger分组时可关联Title,Version,Description值)

    ApiGroupAttribute.cs代码如下

     /// <summary>
        /// 系统分组特性
        /// </summary>
        public class ApiGroupAttribute : Attribute
        {
            public ApiGroupAttribute(params ApiGroupNames[] name)
            {
                GroupName = name;
            }
            public ApiGroupNames[] GroupName { get; set; }
        }

    ApiGroupNames.cs代码如下

    /// <summary>
        /// 系统分组枚举值
        /// </summary>
        public enum ApiGroupNames
        {
            [GroupInfo(Title = "All", Description = "All接口", Version = "")]
            All = 0,
            [GroupInfo(Title = "尚未分组", Description = "尚未分组相关接口", Version = "")]
            NoGroup = 1,
            [GroupInfo(Title = "登录认证", Description = "登录认证相关接口", Version = "")]
            Login = 2,
            [GroupInfo(Title = "IT", Description = "登录认证相关接口", Version = "")]
            It = 3,
            [GroupInfo(Title = "人力资源", Description = "登录认证相关接口", Version = "")]
            Hr = 4,
            [GroupInfo(Title = "系统配置", Description = "系统配置相关接口", Version = "")]
            Config = 5
        }

    GroupInfoAttribute.cs代码如下

    public class GroupInfoAttribute : Attribute
        {
            public string Title { get; set; }
            public string Version { get; set; }
            public string Description { get; set; }
        }
    

    ******** 打开Startup.cs文件修改ConfigureServices方法(为了方便查看,只列出关于Swagger分组的关键代码)*************

    //1.0 ConfigureServices 里面swagger 的设置
    #region swagger
    
                var openApiInfo = new OpenApiInfo
                {
                    Version = "v1",
                    Title = "WebApi",
                    Description = "A simple example ASP.NET Core Web API",
                    TermsOfService = new Uri("https://www.cnblogs.com/goodluckily/"),
                    Contact = new OpenApiContact
                    {
                        Name = "雨太阳",
                        Email = string.Empty,
                        Url = new Uri("https://www.cnblogs.com/goodluckily/")
                    },
                    License = new OpenApiLicense
                    {
                        Name = "许可证名字",
                        Url = new Uri("https://www.cnblogs.com/goodluckily/")
                    }
                };
    
                services.AddSwaggerGen(c =>
                {
                    #region 分组方案二
    
                    //遍历ApiGroupNames所有枚举值生成接口文档,Skip(1)是因为Enum第一个FieldInfo是内置的一个Int值
                    typeof(ApiGroupNames).GetFields().Skip(1).ToList().ForEach(f =>
                    {
                        //获取枚举值上的特性
                        var info = f.GetCustomAttributes(typeof(GroupInfoAttribute), false).OfType<GroupInfoAttribute>().FirstOrDefault();
                        openApiInfo.Title = info?.Title;
                        openApiInfo.Version = info?.Version;
                        openApiInfo.Description = info?.Description;
                        c.SwaggerDoc(f.Name, openApiInfo);
                    });
    
                    //判断接口归于哪个分组
                    c.DocInclusionPredicate((docName, apiDescription) =>
                    {
                        if (!apiDescription.TryGetMethodInfo(out MethodInfo method)) return false;
                        //1.全部接口
                        if (docName == "All") return true;
                        //反射拿到控制器分组特性下的值
                        var actionlist = apiDescription.ActionDescriptor.EndpointMetadata.FirstOrDefault(x => x is ApiGroupAttribute);
                        //2.得到尚未分组的接口***************
                        if (docName == "NoGroup") return actionlist == null ? true : false;
                        //3.加载对应已经分好组的接口
                        if (actionlist != null)
                        {
                            //判断是否包含这个分组
                            var actionfilter = actionlist as ApiGroupAttribute;
                            return actionfilter.GroupName.Any(x => x.ToString().Trim() == docName);
                        }
                        return false;
                    });
    
                    #endregion
    
                    //添加授权
    
                    //认证方式,此方式为全局添加
    
    
                    var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                    var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                    c.IncludeXmlComments(xmlPath, true);
                });
    #endregion
    

    2.0 Configure 里面swagger 的设置

     #region Swagger
    
                app.UseSwagger();
                app.UseSwaggerUI(c =>
                {
                    c.RoutePrefix = "swagger";
    
                    #region 分组方案二
                    //遍历ApiGroupNames所有枚举值生成接口文档,Skip(1)是因为Enum第一个FieldInfo是内置的一个Int值
                    typeof(ApiGroupNames).GetFields().Skip(1).ToList().ForEach(f =>
                    {
                        //获取枚举值上的特性
                        var info = f.GetCustomAttributes(typeof(GroupInfoAttribute), false).OfType<GroupInfoAttribute>().FirstOrDefault();
                        c.SwaggerEndpoint($"/swagger/{f.Name}/swagger.json", info != null ? info.Title : f.Name);
                    });
                    #endregion
    
                    //swagger 默认折叠
                    //c.DocExpansion(Swashbuckle.AspNetCore.SwaggerUI.DocExpansion.None);
    
                    //MiniProfiler用的
                    c.IndexStream = () => GetType().GetTypeInfo().Assembly.GetManifestResourceStream("WebApi.index.html");
                });
    
    #endregion

    然后你F6生成一下,没出错的话,就Ctrl+F5看看,正常的话就会在Swagger右上角看到分组了。

     *********************具体在 WeatherForecastController 里面的使用***************

    1.单个Action特性 [ApiGroup(ApiGroupNames.Config)]

    2.多个Action特性 [ApiGroup(ApiGroupNames.Login,ApiGroupNames.It)]

    ..............

    具体详细的Controller代码如下

        [ApiController]
        [Route("[controller]")]
        public class WeatherForecastController : Controller
        {
    
            private readonly ILogger<WeatherForecastController> _logger;
    
            private readonly IHttpContextAccessor _accessor;
            public WeatherForecastController(ILogger<WeatherForecastController> logger, IHttpContextAccessor accessor)
            {
                _logger = logger;
                _accessor = accessor;
            }
            /// <summary>
            /// 多分组共用请求
            /// </summary>
            /// <returns></returns>
            //[ProducesResponseType(201)]
            //[ProducesResponseType(400)]
    
            [HttpGet("getLoginAndIT")]
            [ApiGroup(ApiGroupNames.Login,ApiGroupNames.It)]
            public IActionResult GetLoginAndIT()
            {
                return  Json("GetLoginAndIT ok");
            }
    
            [HttpGet("getConfig")]
            [ApiGroup(ApiGroupNames.Config)]
            public IActionResult GetConfig()
            {
                return Json("Config ok");
            }
    
    
            [HttpGet("getHr")]
            [ApiGroup(ApiGroupNames.Hr)]
    
            public IActionResult GetHr()
            {
                return Json("Hr ok");
            }
    
            [HttpGet("getIt")]
            [ApiGroup(ApiGroupNames.It)]
    
            public IActionResult GetIt()
            {
                return Json("GetIt ok");
            }
            /// <summary>
            /// 获取Miniprofiler Index的 Script (尚未分组的)
            /// </summary>
            /// <returns></returns>
            [HttpGet("getMiniprofilerScript")]
            public IActionResult getMiniprofilerScript()
            {
                var htmlstr = MiniProfiler.Current.RenderIncludes(_accessor.HttpContext);
                var script = htmlstr.Value;
                return Json(script);
            }
        }

     转载,请注明原文出处

    -----------至此结束 end ----------------------------------

    有疑问意见等,欢迎大家讨论.......

     
  • 相关阅读:
    朋友圈、浏览器分享实现
    Cannot read property 'appendChild' of null
    Nginx报错:Sorry, the page you are looking for is currently unavailable. Please try again later.
    RGBA(0,0,0,0)调色
    windows下 python中报错ImportError: No module named 'requests'
    一起谈.NET技术,C# 基础概念之延迟加载 狼人:
    一起谈.NET技术,为类提供软件约定 狼人:
    一起谈.NET技术,asp.net控件开发基础(6) 狼人:
    一起谈.NET技术,详解.NET程序集的加载规则 狼人:
    一起谈.NET技术,Linq学习笔记 狼人:
  • 原文地址:https://www.cnblogs.com/goodluckily/p/14429279.html
Copyright © 2020-2023  润新知