第8章 自定义SwaggerIndex页与登录页
创始人
2024-03-06 20:37:33
0

“Blog.Core-master”程序没有使用.Net7框架内置的index.html页对api方法进行渲染显示,而是通过对“Swagger”和“SwaggerUI”内置中间件的自定义操作,调用根目录下的自定义index.html页对api方法进行渲染显示。

1、自定义“Swagger”和“SwaggerUI”内置中间件和index.html页

1.1 自定义“Swagger”和“SwaggerUI”内置中间件

using System;

using System.IO;

using System.Linq;

using Common.Helper;

using log4net;

//Nuget--Swashbuckle.AspNetCore

using Microsoft.AspNetCore.Builder;

//using static Blog.Core.Extensions.CustomApiVersion;

namespace Extensions.ServiceExtensions

{

    ///

    /// 【Swagger中间件】

    ///

    /// 摘要:

    ///     通过该类中的方法成员把“UseSwagger”管道中间件,集成到.Net7框架内置管道中,为页面渲染显示api提供支撑。

    ///

    ///

    public static class SwaggerMiddleware

    {

        private static readonly ILog Log = LogManager.GetLogger(typeof(SwaggerMiddleware));

        public static void UseSwaggerMiddle(this IApplicationBuilder app, Func streamHtml)

        {

            if (app == null) throw new ArgumentNullException(nameof(app));

            //把“UseSwagger”管道中间件,集成到.Net7框架内置管道中。

            app.UseSwagger();

            //通过自定义设置“UseSwaggerUI”管道中间件,并集成到.Net7框架内置管道中,为页面渲染显示api提供支撑。

            app.UseSwaggerUI(c =>

            {

                //根据版本名称倒序 遍历展示

                //var apiName = AppSettings.app(new string[] { "Startup", "ApiName" });

                //typeof(ApiVersions).GetEnumNames().OrderByDescending(e => e).ToList().ForEach(version =>

                //{

                //    c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"{apiName} {version}");

                //});

                //c.SwaggerEndpoint($"https://petstore.swagger.io/v2/swagger.json", $"{apiName} pet");

                // 将swagger展示api首页,设置成我们自定义的页面(这里特指:WebApi\index.html,记得这个字符串的写法:{项目名.index.html}

                if (streamHtml.Invoke() == null)

                {

                    var msg = "index.html的属性,必须设置为:“嵌入的资源”";

                    Log.Error(msg);

                    throw new Exception(msg);

                }

                c.IndexStream = streamHtml;

                //if (Permissions.IsUseIds4)

                //{

                //    c.OAuthClientId("blogadminjs");

                //}

                // 注意路径配置,设置为空,表示对根目录下的文件(这里特指:WebApi\index.html)进行访问;如果不定义正面的语句将会出现“404”错误。

                c.RoutePrefix = "";

            });

        }

    }

}

1.2自定义根目录Index.html页

    注意:1、根目录Index.html页面的属性必须被设定为:“嵌入的资源”,如下图所示;

 

2、注释掉“launchSettings.json”文件中的"launchUrl"节点;或把“"launchUrl": "swagger"”修改为:“"launchUrl": "indexer.html"” ,如下图所示;

1.3 重构Program类

var app = builder.Build();

//把自定义管道中间件集成到.Net(Core)框架内置管道中,解决vue/uni-app前端项目(Cors)访问当前后端项目时,浏览器或App中出现的异常:

//    1、“has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.”。

//    2、“has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.”。

app.UseMiddleware();

//把自定义“UseSwagger”和“UseSwaggerUI”管道中间件集成到.Net7框架内置管道中,为自定义“index.html”页面渲染显示api提供支撑。

app.UseSwaggerMiddle(() => Assembly.GetExecutingAssembly().GetManifestResourceStream("WebApi.index.html"));


    按F5执行程序如下图所示:

2 自定义“UseSwaggerAuthorized”中间件和swg-login.html页  
2.1 复制资源文件到“wwwroot”目录,如下图所示:

2.2 自定义UseSwaggerAuthorized中间件

using System.Net;

using Microsoft.AspNetCore.Builder;

using Microsoft.AspNetCore.Http;

namespace Extensions.ServiceExtensions

{

    ///

    /// 【Swagger授权中间件】

    ///

    ///

    /// 摘要:

    ///     该管道中间件类主要用于判断1个指定用户是否已经被授权,如果已经被授权则直接访问默认启动页面;反之跳转到登录页面。

    ///

    public class SwaggerAuthMiddleware

    {

        #region 拷贝构造方法与变量

        ///

        /// 【下1个】

        ///

        ///

        /// 摘要:

        ///     .Net(Core)框架内置管道中的下1个管道中间件实例。

        ///

        private readonly RequestDelegate next;

        ///.Net(Core)框架内置管道中的下1个管道中间件实例。

        ///

        /// 【拷贝构造方法】

        ///

        ///

        /// 摘要:

        ///    通过该构造方法中的参数实例,实例化.Net(Core)框架内置管道中的下1个管道中间件实例。

        ///

        public SwaggerAuthMiddleware(RequestDelegate next)

        {

            this.next = next;

        }

        #endregion

        #region 方法

        ///HTTP上下文实例。

        ///

        /// 【异步调用】

        ///

        ///

        /// 摘要:

        ///    通过该方法向.Net(Core)框架内置管道中集成当前管道中间件,判断1个指定用户是否已经被授权,如果已经被授权则直接访问默认启动页面;反之跳转到登录页面:

        ///

        public async Task InvokeAsync(HttpContext context)

        {

            // 也可以根据是否是本地做判断 IsLocalRequest。

            // 说明:该“index.html”页面即不是根目录中的“index.html”页面;也不是“wwwroot”目录中的“index.html”页面,它是“Swagger”中间件内置的“index.html”页面。

            //所以只要当前程序集成了“Swagger”中间件,下面1行语句的值总为:true。

            if (context.Request.Path.Value.ToLower().Contains("index.html"))

            {

                // 判断权限是否正确

                if (IsAuthorized(context))

                {

                    await next.Invoke(context);

                    return;

                }

                // 无权限,跳转swagger登录页

                context.Response.Redirect("/swg-login.html");

            }

            else

            {

                await next.Invoke(context);

            }

        }

        ///HTTP上下文实例。

        ///

        /// 【已授权?】

        ///

        /// 摘要:

        ///     通过对服务器端的“session”中指定信息的匹配操作,获取1个值false(未授权)/true(已授权),该值指示指定用户是否已经被授权。

        ///

        ///

        /// 返回:

        ///     1个值false(未授权)/true(已授权)。

        ///

        ///

        public bool IsAuthorized(HttpContext context)

        {

            // 使用session模式

            // 可以使用其他的

            return context.Session.GetString("swagger-code") == "success";

        }

        ///HTTP上下文实例。

        ///

        /// 【本地请求?】

        ///

        /// 摘要:

        ///     获取1个值false(非本地请求)/true(本地请求),该值指示指定请求是否是本地请求,如果不是swagger中间件将自动执行拦截操作。

        /// 注意:

        ///     该方法原程序中没有任何对象进行调用,如果简化定义实现可以直接删除掉。

        ///

        ///

        /// 返回:

        ///    1个值false(非本地请求)/true(本地请求)

        ///

        ///

        public bool IsLocalRequest(HttpContext context)

        {

            if (context.Connection.RemoteIpAddress == null && context.Connection.LocalIpAddress == null)

            {

                return true;

            }

            if (context.Connection.RemoteIpAddress.Equals(context.Connection.LocalIpAddress))

            {

                return true;

            }

            if (IPAddress.IsLoopback(context.Connection.RemoteIpAddress))

            {

                return true;

            }

            return false;

        }

        #endregion

    }

    ///

    /// 【Swagger授权中间件扩展】

    ///

    ///

    /// 摘要:

    ///     通过该类中的方法成员把Swagger授权中间件集成到.Net7框架的内置管道中,以实现,如果已经被授权则直接访问默认启动页面;反之跳转到登录页面。

    ///

    public static class SwaggerAuthorizeExtensions

    {

        public static IApplicationBuilder UseSwaggerAuthorized(this IApplicationBuilder builder)

        {

            return builder.UseMiddleware();

        }

    }

}

2.3 重构Program类

//必须在把下面的1行定义上否则会出现异常:““An exception was thrown while activating Microsoft.AspNetCore.Session.DistributedSessionStore.”“An exception was thrown while activating Microsoft.AspNetCore.Session.DistributedSessionStore.””。

builder.Services.AddDistributedMemoryCache();

//把“Session”中间件实例,依赖注入到.Net(Core)7框架内置容器中。

builder.Services.AddSession();

builder.Services.AddControllers();

app.UseMiddleware();

app.UseSession();

//把自定义“Swagger”授权管道中间件集成到.Net7框架内置管道中,以实现,如果已经被授权则直接访问默认启动页面;反之跳转到登录页面。

app.UseSwaggerAuthorized();

//把自定义“UseSwagger”和“UseSwaggerUI”管道中间件集成到.Net7框架内置管道中,为自定义“index.html”页面渲染显示api提供支撑。

app.UseSwaggerMiddle(() => Assembly.GetExecutingAssembly().GetManifestResourceStream("WebApi.index.html"));

//设定“wwwroot”目录中的“index.html”页面,为默认启动页。

DefaultFilesOptions defaultFilesOptions = new DefaultFilesOptions();

defaultFilesOptions.DefaultFileNames.Clear();

// 说明:该“index.html”页面即不是根目录中的“index.html”页面;也不是“Swagger”中间件内置的“index.html”页面,它是“wwwroot”目录中的“index.html”页面。

//实际上原程序是以根目录中的“index.html”页面,为默认启动页,为了简化定义实现本从并没有复制“wwwroot”目录中的“index.html”页面。

defaultFilesOptions.DefaultFileNames.Add("index.html");

app.UseDefaultFiles(defaultFilesOptions);

app.UseStaticFiles();

按F5执行程序如下图所示:

对以上功能更为具体实现和注释见:221201_07Blog(自定义SwaggerIndex页与登录页)。

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...