20. 【.NET 8 实战--孢子记账--从单体到微服务】--简易权限--补充--自动添加接口地址

news2025/1/2 22:59:06

在同学学习过程,部分同学向我反馈说每次新增接口都要在接口表里手动添加一条接口很麻烦,因此我把项目代码做了一个改动,使我们不需要手动添加,每次项目运行起来后就会自动把新的接口地址添加进去。

一、实现

首先,我们需要在项目根目录新建Initialization文件夹,以后我们会将初始化项目、初始化数据库数据等类放在这里。接着我们在该文件夹下新建AddPath类,这个类用于初始化数据库中SysUrl表,代码如下:

using System.Reflection;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Routing;
using SporeAccounting.Controllers;
using SporeAccounting.Models;
using SporeAccounting.Server.Interface;

namespace SporeAccounting.Initialization;

/// <summary>
/// 新增web api路径
/// </summary>
public static class AddPath
{
    /// <summary>
    /// 初始化
    /// </summary>
    /// <param name="serviceProvider"></param>
    public static void Init(IServiceProvider serviceProvider)
    {
        using (var scope = serviceProvider.CreateScope())
        {
            var sysUrlServer = scope.ServiceProvider.GetRequiredService<ISysUrlServer>();
            List<SysUrl> sysUrls = new List<SysUrl>();
            //1. 通过反射获取所有的控制器
            var controllers = Assembly.GetExecutingAssembly().GetTypes()
                .Where(type => typeof(BaseController).IsAssignableFrom(type));
            //2. 获取控制器的Route特性
            foreach (var controller in controllers)
            {
                var routeAttribute = controller.GetCustomAttribute<RouteAttribute>();
                if (routeAttribute != null)
                {
                    //3. 根据特性生成完整的路径,
                    //如果路径中包含[controller],则替换为控制器的名称,反之直接使用路径
                    var controllerName = routeAttribute.Template;
                    if (controllerName.Contains("[controller]"))
                    {
                        controllerName =
                            controllerName.Replace("[controller]", controller.Name.Replace("Controller", ""));
                    }

                    //4. 获取controller的所有Action
                    var actions = controller.GetMethods()
                        .Where(method => method.IsPublic && !method.GetCustomAttributes<NonActionAttribute>().Any());
                    for (int i = 0; i < actions.Count(); i++)
                    {
                        var action = actions.ElementAt(i);
                        var actionRouteAttribute = action.GetCustomAttribute<RouteAttribute>();
                        if (actionRouteAttribute != null)
                        {
                            var actionName = actionRouteAttribute.Template;
                            if (actionName.Contains("[action]"))
                            {
                                actionName = actionName.Replace("[action]", action.Name);
                            }

                            actionName = actionName.Split("/")[0];
                            var httpMethod = action.GetCustomAttributes<HttpMethodAttribute>().FirstOrDefault()
                                ?.HttpMethods.FirstOrDefault() ?? "GET";
                            var route = $"/{controllerName}/{actionName}".Replace("//", "/");
                            bool isExist = sysUrlServer.IsExist(route, httpMethod);
                            if (isExist)
                            {
                                continue;
                            }
                            var sysUrl = new SysUrl()
                            {
                                Url = route,
                                IsDeleted = false,
                                Description = "",
                                RequestMethod = httpMethod,
                                CreateUserId = "b47637e2-603f-4df0-abe9-88d70fa870ee"
                            };
                            sysUrls.Add(sysUrl);
                        }
                    }
                }
            }

            //5. 将路径添加到数据库
            sysUrlServer.Add(sysUrls);
        }
    }
}

这段代码用于自动初始化 Web API 的路径配置,并将其存储到数据库中,方便后续管理或用于权限控制等功能。它通过反射获取当前程序集中的控制器和其操作方法(Actions),生成每个 API 的完整路径,并在数据库中进行存储。
代码的入口是 Init 方法,它接受一个 IServiceProvider 参数,用于通过依赖注入获取服务和创建作用域。在作用域内,获取了 ISysUrlServer 服务实例,该服务负责操作路径数据。首先,通过反射获取当前程序集中的所有类型,并筛选出继承自 BaseController 的类型,代表这些类型是 API 控制器。接着,代码对每个控制器检查是否标记了 Route 特性,用来定义控制器的路由模板。如果找到该特性,则会提取其中的模板信息,并替换其中的占位符 [controller] 为控制器的名称(去除 Controller 后缀)。
在处理每个控制器后,代码进一步获取控制器中所有公开的操作方法,这些方法需要满足没有标记为 NonAction 特性的条件。对于每个操作方法,代码检查是否有 Route 特性来定义其路径。如果存在 [action] 占位符,会被替换为具体方法名。结合控制器路径和操作路径,生成每个 API 的完整路径。
在生成路径后,代码检查该路径是否已经存在于数据库中,利用 sysUrlServer.IsExist 方法。如果路径已经存在,则跳过该路径,避免重复存储;如果路径不存在,则创建一个 SysUrl 对象,包含路径、HTTP 请求方法、是否删除标记以及创建者 ID 等信息。所有新的路径信息会被添加到 sysUrls 列表中。
最后,调用 sysUrlServer.Add 方法,将收集到的路径信息批量写入数据库。通过这种方式,代码实现了自动化的路径管理,无需手动配置所有 API 的路由信息,显著提高了开发效率。与此同时,系统可以动态地获取和管理路径信息,为后续功能(如权限验证或日志记录)提供支持。这种设计方式特别适合复杂项目中的路径初始化需求。

完成AddPath类后,我们还需要在Program类中使用它,使其可以项目启动时帮我们吧接口路径写入到数据库中,这里需要注意的是AddPath类是在开发中用的,生产环境中我们捕获这么初始化数据库,因此需要将这个类的调用限制在开发环境下,代码如下:

if (app.Environment.IsDevelopment())
{
	//more code....
    AddPath.Init(app.Services);
    AddRolePath.Init(app.Services);
}

二、总结

在开发过程中,针对每次新增接口需要手动添加到接口表的问题,设计并实现了一个自动化解决方案:利用反射动态生成 API 路径并自动存储到数据库中。具体实现通过新增一个名为 AddPath 的静态类完成。此类通过反射扫描当前程序集的控制器及其操作方法(Action),提取路由信息,动态生成完整的 API 路径,并检查路径是否已存在于数据库中。如果不存在,则将路径及相关元数据保存到数据库中,从而实现接口的自动注册。实现过程中,AddPath 类的核心逻辑包括反射获取控制器及其 Route 特性,替换路由模板中的占位符(如 [controller][action]),并结合 HTTP 方法信息生成唯一标识的完整路径。为了确保数据的一致性和避免重复存储,还使用 ISysUrlServer 服务检查路径是否已存在。最终,通过批量操作将新路径存储到数据库中。此外,将该功能集成到项目启动流程中,仅在开发环境下调用此功能以避免在生产环境中执行不必要的初始化操作。这种自动化路径管理机制显著提高了开发效率,避免了手动维护接口表的繁琐过程,同时为后续权限控制和日志管理提供了便利支持。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2268003.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法基础一:冒泡排序

一、冒泡排序 1、定义 冒泡排序&#xff08;英语&#xff1a;Bubble Sort&#xff09;是一种简单的排序算法。它重复地走访过要排序的数列&#xff0c;一次比较两个元素&#xff0c;如果他们的顺序&#xff08;如从大到小、首字母从A到Z&#xff09;错误就把他们交换过来。 …

llamafactory报错:双卡4090GPU,训练qwen2.5:7B、14B时报错GPU显存不足(out of memory),轻松搞定~~~

实际问题场景&#xff1a; 使用llamafactory进行微调qwen2.5 7B和14B的大模型时&#xff0c;会出现out of memory的报错。尝试使用降低batch_size&#xff08;原本是2&#xff0c;现在降到1&#xff09;的方式&#xff0c;可以让qwen2.5:7B跑起来&#xff0c;但时不时会不稳定…

七牛云—对象云存储Kodo(详解,文件上传和下载)

文章目录 七牛—对象云存储Kodo1.1 介绍1.2 使用注册账号创建bucket空间查询accessKey/secretKey查看官网SDK1.3 SpringBoot中使用七牛云上传引入依赖(在官方SDK文档中有)引入工具类servie层controller层postman测试下载引入工具类域名查询controller层七牛—对象云存储Kodo 1…

概率统计与随机过程--作业8

推导题 试给出图1中所有关于Z{e}与变量a条件独立的变量。 编程题 有一个美国医生使用Bayes网络诊断胸部疾病&#xff0c;其掌握的数据信息如图2所示&#xff0c;其中包括&#xff1a; 有50%的病人吸烟&#xff08;smoking&#xff09;&#xff0c;1%患有肺结核(Tuberculosis…

Java设计模式 —— 【结构型模式】享元模式(Flyweight Pattern) 详解

文章目录 概述结构案例实现优缺点及使用场景 概述 享元模式也叫蝇量模式&#xff1a;运用共享技术有效地支持大量细粒度的对象&#xff1b; 常用于系统底层开发&#xff0c;解决系统的性能问题。像数据库连接池&#xff0c;里面都是创建好的连接对象&#xff0c;在这些连接对象…

Linux实验报告7-文件管理

目录 一&#xff1a;实验目的 二&#xff1a;实验内容 (1)查看/etc/inittab文件的权限属性&#xff0c;并指出该文件的所有者以及文件所属组群。 (2)新建文件test&#xff0c;设置文件权限为r--r-----。 (3)新建文件test2&#xff0c;设系统中有用户study和用户组studygr…

机器学习DAY7: 特征工程和特征选择(数据预处理)(完)

本文通过特征提取、特征转换、特征选择三个过程介绍数据预处理方法&#xff0c;特征提取将原始数据转换为适合建模的特征&#xff0c;特征转换将数据进行变换以提高算法的准确性&#xff0c;特征选择用来删除无用的特征。 知识点 特征提取特征转换特征选择 本次实验的一些示…

AE Dressler CESAR 1312 Generator Model User Manual

AE Dressler CESAR 1312 Generator Model User Manual

科大讯飞超拟人合成python

1、进入自己的项目 复制APPID、APISecret、APIKey 2、添加好听发音人 复制参数 3、需要替换代码部分&#xff1a; 换自己喜欢的发声人的参数 4、完整代码&#xff1a; import _thread as thread import base64 import datetime import hashlib import hmac import json fro…

关于缓冲文件系统和文件控制块的介绍

缓冲文件系统 缓冲文件系统的定义与原理 应用程序是如何进行文件数据的访问的呢&#xff1f;由于系统对磁盘文件数据的存取速度与内存数据存取的速度不同&#xff0c;而且文件数据量较大&#xff0c;数据从磁盘读到内存或从内存写到磁盘不可能瞬间完成&#xff0c;所以为了提高…

Llama系列关键知识总结

系列文章目录 第一章&#xff1a;LoRA微调系列笔记 第二章&#xff1a;Llama系列关键知识总结 文章目录 系列文章目录Llama: Open and Efficient Foundation Language Models关键要点LLaMa模型架构&#xff1a;Llama2分组查询注意力 (GQA) Llama3关键信息 引用&#xff1a; Ll…

【已解决】Latex中高亮段内命令(如参考文献引用、图、表格)

速览&#xff1a;解决前后图片对比拟解决的问题问题描述Latex高亮的一般做法段内有命令时候的高亮报错 问题原因 解决方案——在导言区为 \cite 等命令“注册”解决方案简要描述详细解释其他情况 速览&#xff1a;解决前后图片对比 解决前&#xff1a; 解决后&#xff1a; …

【C语言】数组指针与指针数组

前言 前面的文章讲了指针的一些基本内容&#xff0c;这里我们来讲一下数组指针与指针数组&#xff0c;数组指针是指针运用的一个明显体现&#xff0c;准确来说是通过指针访问内存地址的具体体现 一、一维数组的指针 首先&#xff0c;我们先来看一段代码 #include <stdio…

30天面试打卡计划 2024-12-25 26 27 面试题

2024-12-25 面试题 后端 MySQL三层B树能存多少数据&#xff1f; B 树&#xff1a;一种特殊的多路平衡查找树&#xff0c;广泛应用于数据库索引中。它具有所有叶子节点都位于同一层且包含指向相邻叶子节点指针的特点&#xff0c;这使得范围查询更加高效。InnoDB&#xff1a;My…

嵌入式系统 第十一讲 Android操作系统(增加)

• 11.1 Android 操作系统介绍 • Android 是 Google 公司于2007 年11月发布的一款非常优秀的智能移 动平台操作系统。到2011 年第一季度Android 在全球的市场份额首 次超过Nokia的Symbian系统&#xff0c;跃居全球第一。 • Android系统最初由AndyRubin等人于2003年10月创建…

Three.js 字体

在 Three.js 中&#xff0c;我们可以通过 FontLoader 加载字体&#xff0c;并结合 TextGeometry 创建 3D 文本。加载字体是因为字体文件包含了字体的几何信息&#xff0c;例如字体的形状、大小、粗细等&#xff0c;而 TextGeometry 则是根据字体信息生成 3D 文本的几何体。 在…

机器人C++开源库The Robotics Library (RL)使用手册(三)

进入VS工程,我们先看看这些功能函数及其依赖库的分布关系: rl命名空间下,主要有八大模块。 搞定VS后将逐个拆解。 1、编译运行 根据报错提示,配置相应错误的库(根据每个人安装位置不同而不同,我的路径如下:) 编译所有,Release版本耗时大约10分钟。 以rlPlan运动…

【GUI-PyQt5】简介

1. 简介 GUI&#xff1a;带图形的用户接口程序&#xff0c;也就是桌面应用。 2. 分类 2.1 基本窗口控件 QMainWindowQwidgetQlabelQLineEdit菜单工具栏 2.2 高级组件 QTableViewQListView容器多线程 2.3 布局管理 QBoxLayoutQGridLayoutQFormLayout嵌套布局 2.4 信号与…

Mysql学习笔记之SQL-4

这篇文章开始介绍SQL语句的最后一个部分&#xff0c;DCL&#xff08;Data Control Language&#xff09;数据库控制语言。 1.简介 DCL英文全称是Data Control Language(数据控制语言)&#xff0c;用来管理数据库用户、控制数据库的访 问权限。 这一部分比较简单&#xff0c;主…

Chrome被360导航篡改了怎么改回来?

一、Chrome被360导航篡改了怎么改回来&#xff1f; 查看是否被360主页锁定&#xff0c;地址栏输入chrome://version&#xff0c;看命令行end后面&#xff08;蓝色部分&#xff09;&#xff0c;是否有https://hao.360.com/?srclm&lsn31c42a959f 修改步骤 第一步&#xff1a…