CRUD的最佳实践,联动前后端,包含微信小程序,API,HTML等(二)

server/2024/9/19 0:47:42/ 标签: html, .netcore

CRUD老生常谈,但是我搜索了一圈,发觉几乎是着重在后端,也就是API部分!
无外乎2个思路
1.归总的接口,比如一个接口,实现不同表的CRUD
2.基于各自的表,使用代码生成器实现CRUD
个人来说是推荐2,虽然代码多了,其实结构更加清晰,而且!而且!后端对安全尤为重要!!!
啥?你说前端就不安全了???
前端!那不叫安全,那叫用户体验,体验懂否?
后端!那才是安全关口!重要的门户!!!!
如果使用1的方式,你会发觉到后续代码越来越臃肿,各种判断,到最后就像上了重庆的立交桥转个不停!
上次我们说到小程序的页面表单的动态化,先看下本次的要点
在这里插入图片描述
既然是系统,那肯定也少不了后台管理端的了,这里我使用的是原生的HTML,如果你喜欢那个VUE,其实可以按照这个思想自己实现!

##!!!VUE是前端点歪了技能树的产物!!!##

WebApi新增

距离上次的一发布后,后端接口我做了如下的调整!在WebApi中

        /// <summary>/// 读取AddDto的数据模型/// </summary>/// <returns></returns>[HttpGet]public PasteBuilderHelper.VoloModelInfo ReadAddModel(){var _model = PasteBuilderHelper.ReadModelProperty<WebsiteNoticeAddDto>(new WebsiteNoticeAddDto());return _model;}/// <summary>/// 读取UpdateDto的数据模型/// </summary>/// <returns></returns>[HttpGet]public async Task<PasteBuilderHelper.VoloModelInfo> ReadUpdateModel(int id){var _info = await _dbContext.WebsiteNotice.Where(x => x.Id == id).AsNoTracking().FirstOrDefaultAsync();if (_info != null && _info != default){var dto = ObjectMapper.Map<WebsiteNotice, WebsiteNoticeUpdateDto>(_info);var _dataModel = PasteBuilderHelper.ReadModelProperty<WebsiteNoticeUpdateDto>(dto);return _dataModel;}var _model = PasteBuilderHelper.ReadModelProperty<WebsiteNoticeUpdateDto>(new WebsiteNoticeUpdateDto());return _model;}/// <summary>/// 读取ListDto的数据模型/// </summary>/// <returns></returns>[HttpGet]public PasteBuilderHelper.VoloModelInfo ReadListModel(){var _model = PasteBuilderHelper.ReadModelProperty<WebsiteNoticeListDto>(new WebsiteNoticeListDto());var _query_model = PasteBuilderHelper.ReadModelProperty(new InputQueryWebsiteNotice());if (_query_model != null){_model.QueryProperties = _query_model.Properties;}return _model;}

注意看上面的,加了ListDto和InputQueryWebsiteNotice
InputQueryWebsiteNotice是什么鬼?

        /// <summary>/// 按页查询对象/// </summary>/// <param name="input"></param>/// <returns></returns>[HttpGet]public async Task<PagedResultDto<WebsiteNoticeListDto>> Page([FromQuery] InputQueryWebsiteNotice input){var _query = _dbContext.WebsiteNotice.Where(t => 1 == 1);var _pagedto = new PagedResultDto<WebsiteNoticeListDto>();if (input.page == 1){_pagedto.TotalCount = await _query.CountAsync();}var dataList = await _query.OrderByDescending(x => x.Id).Page(input.page, input.size).AsNoTracking().ToListAsync();if (dataList == null || dataList.Count == 0){throw new PasteSoftException("没有查询到数据", 204);}var temList = ObjectMapper.Map<List<WebsiteNotice>, List<WebsiteNoticeListDto>>(dataList);_pagedto.Items = temList;return _pagedto;}

看上面,知道了吧?说白点就是列表的时候的查询项!
啥玩意???咋查询搞里面去了???

查询支持

看最新的页面
在这里插入图片描述
上面是某一个表的对应的列表的页面,上面的信息中,处理下方的页码,上方的新增,查询和刷新按钮,其他的都是后端控制的!!!
对,是其他的所有的(表格的线不算哈!),比如这个表对应有几个查询项,就是上面举例子的
InputQueryWebsiteNotice控制的!
以下是页面打开后第一次获取的数据模型数据
在这里插入图片描述
通过读取对应的Dto的内容,控制前端的UI
看下我的查询的模型

    /// <summary>/// 站点公告查询 站点公告的查询项/// </summary>public class InputQueryWebsiteNotice: InputSearchBase{/// <summary>/// 标题 点击键入基于标题查询/// </summary>[MaxLength(16)]public string title { get; set; } = "";/// <summary>/// 状态 默认值为-1表示不查询/// </summary>public int state { get; set; } = -1;/// <summary>/// 开关 基于开关类型查询/// </summary>public bool status { get; set; } = false;/// <summary>/// 开始日期/// </summary>public DateTime? sdate { get; set; } = null;/// <summary>/// 结束日期/// </summary>public DateTime edate { get; set; }}

如何给定其他属性,比如必填,默认值等?
其实只要和Dto一样,把对应的Attribute标注上去即可,数据模型的规则传递给前端后,前端根据规则生成UI即可!
这里有几个规定
对于DateTime类型,如果可为null的,也就是标注了 ?的则数据类型为DateTime ,其中required为false
如果不为Null类型的,则数据类型为DateTime,其中required为true

总结优势

那是不是意味着,一个项目的管理端可以做到只有4个页面!!!
1.登陆到页面
2.菜单页面
3.对应表的列表显示页面,显示表格数据等,兼顾外表的选择!
4.表单页面,兼顾新增,编辑
4个页面即可实现项目的后台管理端,涉及的功能包括不限于,图片上传等,数据列表展示,表单的新增和编辑,日期选择等!
关键点,页面的代码不多,比如我的表格数据页面的代码行才300行不到!
表单页面的代码才500行不到
我的测试页面有些规则还没有提取出来,比如数据项的格式校验等!

需要注意点

数据类型

由于涉及不同端,在数据类型上肯定有不一样的地方,比如后端的存储类型为string,在前端的表示就很多了,
比如昵称,签名内容,文章描述,文章内容,头像的地址,甚至日期等都可以使用string表示,这就需要一个协商,也就是转化,把后端类型转化,翻译成前端类型的函数,这个需要使用方自己实现,和后端协商一致即可!
比如我的规则,如果String类型,长度没有限制,则在前端翻译成richtext,如果长度小于128限定,则为text,如果长度>128则为textarea

指定类型

有些类型,后端没有,或者是没法表示,因为我们的原则是尽量后端控制前端,比如images,比如region,这就需要我们后端在模型上动手脚了!
比如我的一个案例

    /// <summary>/// 用于标记字段有查询的属性/// </summary>public class DataTypeAttribute : Attribute{/// <summary>/// /// </summary>private string Name { get; set; }/// <summary>/// /// </summary>public DataTypeAttribute(string _name = ""){Name = _name;}/// <summary>/// /// </summary>/// <returns></returns>public override string ToString(){return Name.ToString();}}

上面这个属性是自定义的,可以自己命名,后面前端基于这个进行处理即可,比如:

        /// <summary>/// 头像/// </summary>[DataType("image")]public string Head { get; set; }

这样前端在遇到这个字段的时候,读取到他的属性DataType为image,那么前端对这个字段进行渲染的时候,就使用image的类型来处理!
同样的道理,你可以实现更多的,比如单选,选项内容,等可以通过自定义的属性来实现!

写在最后

通过以上的思路,我们可以实现
1.安全,所有的属性信息是dto模块的,我们开放给前端的,前端才能够查询到
2.对模型的字段的规则,前后端都支持,前端是为了体验,后端是为了安全!
3.我们不需要为了新增一个字段而去修改前端了!

目前的代码还在完善中,后续我们会把这个功能添加到PasteTemplate(.netCore的WebApi项目模板)和PasteBuilder右键代码生成器中!

下期,作者将提供实际项目的案例展示,和其中做的一些处理等!


http://www.ppmy.cn/server/106555.html

相关文章

Linux下单网卡配置多个路由ip方法

Linux下配置网卡ip别名何谓ip别名 用windows的话说&#xff0c;就是为一个网卡配置多个ip。 什么场合增加ip别名能派上用场&#xff1f; 布网需要、多ip访问测试、特定软件对多ip的需要 下面通过几个例子简单介绍一下如何使用ifconfig命令给网卡配置ip别名。 一、首先为服务器…

C#实现数据采集系统-数据反写(2)消息内容处理和写入通信类队列

C#实现数据采集系统-数据反写 实现步骤 MQTT订阅&#xff0c;接收消息 链接-MQTT订阅接收消息反写内容写入通信类&#xff0c;添加到写入队列中实现Modbustcp通信写入 具体实现 2. 消息内容写入通信类&#xff0c;添加到写入队列中 在服务类DAqService中添加通信集合_modb…

MyBatis框架学习

系列文章目录 第一章 基础知识、数据类型学习 第二章 万年历项目 第三章 代码逻辑训练习题 第四章 方法、数组学习 第五章 图书管理系统项目 第六章 面向对象编程&#xff1a;封装、继承、多态学习 第七章 封装继承多态习题 第八章 常用类、包装类、异常处理机制学习 第九章 集…

NRC-SIM:基于Node-RED的多级多核缓存模拟器

整理自&#xff1a; 《NRC-SIM: A NODE-RED Based Multi-Level, Many-Core Cache Simulator》&#xff0c;由 Ezequiel Trevio 撰写&#xff0c;作为他在德克萨斯大学里奥格兰德河谷分校攻读电气工程硕士学位的部分成果。以下是论文的详细主要内容&#xff1a; 摘要(Abstract…

day41.动态规划

一.动态规划 121.买卖股票的最佳时机I 思路:dp[i][1] 表示第i天不持有股票所得最多现金 dp[i][0] 表示第i天持有股票所得最多现金 class Solution { public:int maxProfit(vector<int>& prices) {int len prices.size();if (len 0) return 0;vector<vector&…

强化学习第九章:策略梯度方法

强化学习第九章&#xff1a;策略梯度方法 思路优化函数优化函数的梯度求解 Monte Carlo policy gradient (REINFORCE)总结参考资料 思路 与上一章的思路类似&#xff0c; 状态-动作 对下标索引获取概率π(s, a)的方式转换为状态-动作对 或者状态输入到神经网络中&#xff0c;两…

DevOps实现CI/CD实战(三)- 集成Sonar Qube

七、集成Sonar Qube 1. SonarQube介绍 Sonar Qube是一个开源的代码分析平台&#xff0c;支持Java、Python、PHP、JavaScript、CSS等25种以上的语言&#xff0c;可以检测出重复代码、代码漏洞、代码规范和安全性漏洞的问题。 Sonar Qube可以与多种软件整合进行代码扫描&#…

TCP keepalive和HTTP keepalive区别

TCP 的 Keepalive 在传输层 是内核态实现的&#xff0c;是TCP的保活机制 当两端的TCP连接一直没有数据交互&#xff0c;就达到了触发TCP保活机制的条件&#xff0c;那么内核里的TCP协议栈就会发送探测报文。 如果对端程序是正常工作的&#xff0c;当TCP保活的探测报文发送到对…

wp-autopost-pro 3.7.8最新完美版

插件简介&#xff1a; 插件是wp-autopost-pro 3.7.8最新版本。 采集插件适用对象 1、刚建的wordpress站点内容比较少&#xff0c;希望尽快有比较丰富的内容&#xff1b; 2、热点内容自动采集并自动发布&#xff1b; 3、定时采集&#xff0c;手动采集发布或保存到草稿&#xff…

mysql数据表管理

数据表管理 如果将数据库管理系统与之前的文件管理系统做类比的话&#xff1a; 数据库管理系统文件管理系统数据库文件夹数据表文件夹下的文件 数据表的常见操作指令 进入数据库use 数据库&#xff0c;查看当前所有表:show tables 创建表结构 idnameemailage创建表的基础语…

Leetcode面试经典150题-13.罗马数字转整数

解法都在代码里&#xff0c;不懂就留言或者私信&#xff0c;这个是相对简单点的&#xff0c;感觉会在低职级面试的时候考 class Solution {/**罗马数字转整数还是比较简单的&#xff0c;基本思路&#xff1a;把罗马数字字符串转成字符数组同时创建一个int型数组&#xff0c;遍…

「C#」EF Core的“迁移”(Migration)

1、“迁移”是什么 “迁移”&#xff08;Migration&#xff09;我觉得可以理解为将实体类的变化 转换为对数据库修改的方案&#xff0c;应用迁移就是将这个修改方案应用到数据库。其次&#xff0c;迁移也记录了数据库的版本历史等信息。 2、添加迁移 2.1、dotnet cli tool …

设计模式之简单工厂模式

一 、定义 简单工厂模式是一种创建型设计模式&#xff0c;它提供一个统一的接口来创建对象&#xff0c;而不需要客户端直接实例化对象。简单工厂模式通过封装创建对象的逻辑&#xff0c;简化了对象的创建过程&#xff0c;同时也提高了代码的可维护性和扩展性。缺点是&#xff…

浅谈【数据结构】图-图的存储

目录 1、图的存储 2、邻接表 3、十字链表 谢谢帅气美丽且优秀的你看完我的文章还要点赞、收藏加关注 没错&#xff0c;说的就是你&#xff0c;不用再怀疑&#xff01;&#xff01;&#xff01; 希望我的文章内容能对你有帮助&#xff0c;一起努力吧&#xff01;&#xff01;…

计算机毕业设计pyspark+django+scrapy租房推荐系统 租房大屏可视化 租房爬虫 hadoop 58同城租房爬虫 房源推荐系统

用到的技术: 1. python 2. django后端框架 3. django-simpleui&#xff0c;Django后台 4. vue前端 5. element-plus&#xff0c;vue的前端组件库 6. echarts前端可视化库 7. scrapy爬虫框架 基于大数据的租房信息推荐系统包括以下功能&#xff1a…

选择排序【详解】

本期介绍&#x1f356; 主要介绍&#xff1a;排序中的选择排序。 文章目录 1. 前言2. 选择排序3. 优化选择排序 1. 前言 相信只要接触过C语言的同学都或多或少了解排序问题&#xff0c;其中最基本&#xff0c;且最为人所熟知的排序是&#xff1a;选择排序。下面我会带着大家重新…

JAVA后端程序拉取私人仓库的npm包并将该程序打包成jar包

当前有一个系统用于导出项目&#xff0c;而每次导出的项目并不可以直接使用&#xff0c;需要手动从npm私人仓库中获取一个npm包然后将他们整合到一起它才是一个完整的项目&#xff0c;所以目前我的任务就是编写一个java程序可以自动地从npm私人仓库中拉取下来那个模板代码到指定…

C语言文件操作

目录 文件指针 文件的打开和关闭 文件路径&#xff1a; 相对路径 绝对路径 文件的顺序读写 所有输出流&#xff1a; fputc&#xff1a; fgetc&#xff1a; fputs&#xff1a; fgets&#xff1a; fprintf&#xff1a; fscanf&#xff1a; fwrite&#xff1a; fre…

MVVM框架对比

框架名称 MvvmLigth CommunityToolkit.Mvvm Prism Caliburn.Micro 通知属性 ObservableObject ObservableObject BindableBase PropertyChangedBase ViewModel基类 ViewModelBase 无 无 Screen/Conductor 命令对象 RelayCommand RelayCommand DelegateComman…

人工智能-TensorFlow

TensorFlow 是一个非常流行的开源机器学习框架&#xff0c;它支持广泛的机器学习和深度学习任务。以下是使用 TensorFlow 完成机器学习和深度学习任务的基本步骤&#xff1a; 1. 安装 TensorFlow 首先需要安装 TensorFlow。可以通过 pip 命令来安装 TensorFlow&#xff1a; …