当前位置: 首页 > news >正文

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

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右键代码生成器中!

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

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 大模型企业应用落地系列》基于大模型的对话式推荐系统》技术架构设计全攻略
  • HarmonyOS应用开发者基础认证
  • IPv4和IPv6的区别是什么?什么是局域网和广域网,公网IP和私有IP?
  • Redis Cluster(无中心化设计)
  • 信号量笔记
  • pytorch FSDP分布式训练minist案例
  • java springboot 集成activeMQ(保姆级别教程)
  • C++学习笔记——交换值
  • Unity3D UGUI性能消耗和管理详解
  • Redis集群技术
  • CSS3页面布局-三栏-中栏流动布局
  • 基于无人机边沿相关 ------- IBUS、SBUS协议和PPM信号
  • 目标检测:Cascade R-CNN: Delving into High Quality Object Detection - 2017【方法解读】
  • 张宇36讲+1000题重点强化!保100冲120速刷攻略
  • <WPF> xaml代码如何使用c#编写
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • eclipse(luna)创建web工程
  • JAVA并发编程--1.基础概念
  • SSH 免密登录
  • Webpack 4 学习01(基础配置)
  • 记一次和乔布斯合作最难忘的经历
  • 实习面试笔记
  • ​iOS实时查看App运行日志
  • ‌U盘闪一下就没了?‌如何有效恢复数据
  • # C++之functional库用法整理
  • # 利刃出鞘_Tomcat 核心原理解析(七)
  • ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTr
  • #include
  • #考研#计算机文化知识1(局域网及网络互联)
  • (1)Jupyter Notebook 下载及安装
  • (C语言)逆序输出字符串
  • (javaweb)Http协议
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (力扣记录)1448. 统计二叉树中好节点的数目
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (五)activiti-modeler 编辑器初步优化
  • (一) 初入MySQL 【认识和部署】
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • (转)ABI是什么
  • (转)Groupon前传:从10个月的失败作品修改,1个月找到成功
  • (转)ObjectiveC 深浅拷贝学习
  • (转载)(官方)UE4--图像编程----着色器开发
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .net core 6 redis操作类
  • .NET Core 和 .NET Framework 中的 MEF2
  • .net core使用ef 6
  • .NET MVC、 WebAPI、 WebService【ws】、NVVM、WCF、Remoting
  • .Net Redis的秒杀Dome和异步执行
  • .NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。
  • .NetCore发布到IIS
  • .net操作Excel出错解决
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)