.NET Core实战项目之CMS 第十五章 各层联动工作实现增删改查业务
连着两天更新叙述性的文章大家可别以为我转行了!哈哈!今天就继续讲讲我们的.NET Core实战项目之CMS系统的教程吧!这个系列教程拖得太久了,所以今天我就以菜单部分的增删改查为例来讲述下我的项目分层之间的协同工作吧!如果你觉得文中有任何不妥的地方还请留言或者加入DotNetCore实战千人交流群637326624跟大伙进行交流讨论吧!
本文已收录至《.NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划》
作者:依乐祝
写在前面
前面的章节中我们基本的增删改查都有了,甚至后台模板我们也找到并集成到了我们的CMS系统中了!那么剩下的就是对功能的开发了。对于功能的开发部分,我不会全部都拿出来讲,只会以一个菜单的例子来进行讲解!话不多说,开是吧!
各层之间的协作
先来讲讲我的分层协作的设计思路。虽然借助了DDDLite的部分思想,但是又与其不通,因为小项目严格按照DDD的思想来进行开发完全是找虐。如果有需要我后期会对结构进行调整来向DDD层次迁移。先上一张图吧:
这里所有的底层方法都是在Repository层进行的,加入仓储接口层的原因是为了解耦,一路跟着教程走来的朋友一定知道我目前我的仓储层是按照SQLServer数据库进行开发的,后期我会对MySQL,甚至PgSql的支持!这样的话对应用层丝毫不会有影响。
为什么这里用了应用层的服务?因为如果不实用应用层的话,设计到一些逻辑判断等等的话会把控制器搞的很庞大,代码量太多!为了使控制器简洁所以我加入了服务层的概念,这样服务层处理业务逻辑,把结果返回给控制器即可!当然如果涉及到多个事件的处理的话可能还需要借助MediatR来进行实现!什么你不知道MediatR是什么?那你可以看看我的这篇《ASP.NET Core中使用MediatR实现命令和中介者模式》文章的讲述。
实体层充当数据库实体映射以及DTO及ViewModel的角色!对于实体对象模型我更喜欢贫血模式的整洁干净的实体对象!不喜欢充斥各种代码的充血对象。所以里面都是POCO的简单生成。而ViewModel这个层可能我对这个层的概念设计有点模糊,所以DTO跟ViewModel的都混在一起了!这里你不用太过惊讶,因为你完全可以按照自己的理解来进行整理!自由发挥吧!
菜单的增删改查实现
这一节我们就开始写菜单的增删改查的代码实现吧!
菜单的列表页面功能实现
首选在我们的
Czar.Cms.Admin
项目的Controllers
控制器下建立MenuController
控制器!如图所示:里面的代码如下:
public class MenuController : BaseController
{
private readonly IMenuService _service; public MenuController(IMenuService service)
{
_service = service;
} public IActionResult Index()
{
return View();
} }
我们这里先列出首页(也就是列表页的代码)然后创建对应的
Index.cshtml
视图Index.cshtml视图的代码如下:
@{
ViewData["Title"] = "后台菜单管理";
}
<blockquote class="layui-elem-quote quoteBox">
<form class="layui-form">
@Html.AntiForgeryToken()
<div class="layui-inline">
<div class="layui-input-inline">
<input type="text" class="layui-input searchVal" placeholder="请输入菜单名称" />
</div>
<a class="layui-btn search_btn" data-type="reload">搜索</a>
</div>
<div class="layui-inline">
<a class="layui-btn layui-btn-normal addMenu_btn"><i class="layui-icon"></i>添加菜单</a>
</div>
<div class="layui-inline">
<a class="layui-btn layui-btn-danger layui-btn-normal delAll_btn"><i class="layui-icon layui-icon-delete"></i>批量删除</a>
</div>
</form>
</blockquote>
<table id="menuList" lay-filter="menuList"></table>
<!--操作-->
<script type="text/html" id="menuListBar">
<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>
<a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del">删除</a>
</script>
<script type="text/html" id="IsDisplay">
{{# if(d.IsDisplay ===true){ }}
<input type="checkbox" name="IsDisplay" value="{{d.Id}}" lay-filter="IsDisplay" lay-skin="switch" lay-text="是|否" checked>
{{# } else{ }}
<input type="checkbox" name="IsDisplay" value="{{d.Id}}" lay-filter="IsDisplay" lay-skin="switch" lay-text="是|否">
{{# }}}
</script>
@section Scripts{
<script type="text/javascript" src="~/layui/layui.js"></script>
<script type="text/javascript" src="~/js/menu/menuList.js?_=@DateTime.Now.ToString("yyyyMMddHHmmss")"></script>
}
可能对于大多数人来说看到这个视图很懵逼,怎么没有列表的信息啊,语法什么的也都看不懂啊?别急,这里用到的是Layui的一些语法!我们拆分下来看:
<form class="layui-form">
这个部分就是搜索功能部分<table id="menuList" lay-filter="menuList"></table>
就是表格<script type="text/html" id="IsDisplay">
这个是layui模板部分在
wwwroot\js\menu\
下面创建一个menuList.js
的js文件,来对页面的列表进行下初始化。并对一些操作进行控制。由于代码太长,所以只粘贴加载表格的部分代码如下所示:对应的LoadData里面的代码如下:
是不是很简洁,那是因为所有的业务代码都在服务层实现了,不信?我把代码粘贴出来给你看:
这时候体会到服务层的好处了吧!
运行起来看下效果吧:
菜单增加修改功能实现
首先还是要写控制器方法来显示视图,代码如下:
由于修改编辑页面菜单有层级关系,所以我们需要加载顶层的菜单(画外音:只支持两级菜单)所以我们加载编辑页面的时候需要把顶层的菜单给加载出来,方法如下:
列表页弹出编辑或者新增的功能是在
menu.js
中实现的,代码如下:新增或者编辑的时候需要判断菜单的别名是否重复,这里是通过layui的验证模块然后使用ajax实现的,视图代码如下:
js代码如下:
先判断是否符合规则,然后判断是否存在,这个需要对新增或者编辑分别进行处理!新增的时候需要判断是否存在即可,编辑的时候需要判断除自己外有没有重复的,代码如下:
可能你更喜欢看服务层及仓储层的代码,当然我也会毫不吝啬的贴出来,只是可能会消耗你些许流量来查看图片。
服务层:
仓储层代码(由于本人比较懒,所以只实现同步方法,异步获取的方法后期再补上吧,相信参照其他的写法你有何能自行实现):
这里需要注意,我在抽象接口里面都加了注释,所以实现里面就没加了,相信你也能看懂。换句话说,我懒~~~~
结果提交,这里需要注意只要涉及到结果提交的我都会用到
ValidateAntiForgeryToken
还有就是我的结果提交全部是通过ajax进行的,并且把防伪Token放在Token里面的,代码如下:至于为什么这里的Headers设置为
X-CSRF-TOKEN-yilezhu
这个你可以看我的上一节课程《.NET Core实战项目之CMS 第十四章 开发篇-防止跨站请求伪造(XSRF/CSRF)攻击处理》里面有讲述,所以这里就不做过多的讲述了。我们直接上结果提交的代码吧。
很简洁对不对?寥寥几行代码,可是实现真的这么简单吗?看看服务层你就知道了。
public BaseResult AddOrModify(MenuAddOrModifyModel item)
{
var result = new BaseResult();
Menu model;
if (item.Id == 0)
{
//TODO ADD
model = _mapper.Map<Menu>(item);
model.AddManagerId = 1;
model.IsDelete = false;
model.AddTime = DateTime.Now;
if (_repository.Insert(model) > 0)
{
result.ResultCode = ResultCodeAddMsgKeys.CommonObjectSuccessCode;
result.ResultMsg = ResultCodeAddMsgKeys.CommonObjectSuccessMsg;
}
else
{
result.ResultCode = ResultCodeAddMsgKeys.CommonExceptionCode;
result.ResultMsg = ResultCodeAddMsgKeys.CommonExceptionMsg;
}
}
else
{
//TODO Modify
model = _repository.Get(item.Id);
if (model != null)
{
_mapper.Map(item, model);
model.ModifyManagerId = 1;
model.ModifyTime = DateTime.Now;
if (_repository.Update(model) > 0)
{
result.ResultCode = ResultCodeAddMsgKeys.CommonObjectSuccessCode;
result.ResultMsg = ResultCodeAddMsgKeys.CommonObjectSuccessMsg;
}
else
{
result.ResultCode = ResultCodeAddMsgKeys.CommonExceptionCode;
result.ResultMsg = ResultCodeAddMsgKeys.CommonExceptionMsg;
}
}
else
{
result.ResultCode = ResultCodeAddMsgKeys.CommonFailNoDataCode;
result.ResultMsg = ResultCodeAddMsgKeys.CommonFailNoDataMsg;
}
}
return result;
}是不是业务还蛮复杂的,如果都放在控制器处理想想控制器是不是很恐怖,所以说引入服务层很有必要,把一些逻辑移到服务层让控制器只用来显示数据多好!
删除功能实现
你以为删除功能很简单吗?没错,是很简单,可是我们在设计数据库的时候加入了IsDeleted
,看到这个相信你已经猜到了,我们所有的删除操作都是软删除哦!至于为什么这样做?原因就是不想删错了后悔!我只能说这么多了,只有经历惨痛的经历可能才会这样做!还有就是删除之前我会进行js的弹窗提醒,如下图所示,提醒您是否真的要删除!
好了,按照惯例我们第一步是不是要上js的代码啊?那还等什么?立马奉上
注意这里删除的时候也是需要进行防伪验证的,防止别人进行接口恶意删除,下面看下控制器中的代码,哇真干净就一行代码啊,有木有!
其实我想说服务层的代码有超过二十行,不信?我截图给你看吧!好好数数,加上换行是不是有二十行。
总结
今天讲的内容比较简单就是我们这个CMS系统设计的各层之前如何联动工作来实现增删改查业务的,望对大家了解这个系统有所帮助!至于其他的业务功能大家都可以参照这个进行开发!比如角色管理,用户管理等等!下节我们就来实现用户登录模块的功能。
.NET Core实战项目之CMS 第十五章 各层联动工作实现增删改查业务的更多相关文章
- .NET Core实战项目之CMS 第十二章 开发篇-Dapper封装CURD及仓储代码生成器实现
本篇我将带着大家一起来对Dapper进行下封装并实现基本的增删改查.分页操作的同步异步方法的实现(已实现MSSQL,MySql,PgSQL).同时我们再实现一下仓储层的代码生成器,这样的话,我们只需要 ...
- .NET Core实战项目之CMS 第十四章 开发篇-防止跨站请求伪造(XSRF/CSRF)攻击处理
通过 ASP.NET Core,开发者可轻松配置和管理其应用的安全性. ASP.NET Core 中包含管理身份验证.授权.数据保护.SSL 强制.应用机密.请求防伪保护及 CORS 管理等等安全方面 ...
- .NET Core实战项目之CMS 第十六章 用户登录及验证码功能实现
前面为了方便我们只是简单实现了基本业务功能的增删改查,但是登录功能还没有实现,而登录又是系统所必须的,得益于 ASP.NET Core的可扩展性因此我们很容易实现我们的登录功能.今天我将带着大家一起来 ...
- .NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划
作者:依乐祝 原文地址:https://www.cnblogs.com/yilezhu/p/9977862.html 写在前面 千呼万唤始出来,首先,请允许我长吸一口气!真没想到一份来自28岁老程序员 ...
- .NET Core实战项目之CMS 第四章 入门篇-Git的快速入门及实战演练
写在前面 上篇文章我带着大家通过分析了一遍ASP.NET Core的源码了解了它的启动过程,然后又带着大家熟悉了一遍配置文件的加载方式,最后引出了依赖注入以及控制反转的概念!如果大家把前面几张都理解了 ...
- .NET Core实战项目之CMS 第九章 设计篇-白话架构设计
前面两篇文章给大家介绍了我们实战的CMS系统的数据库设计,源码也已经上传到服务器上了.今天我们就好聊聊架构设计,在开始之前先给大家分享一下这几天我一直在听的<从零开始学架构>里面关于架构设 ...
- .NET Core实战项目之CMS 第十一章 开发篇-数据库生成及实体代码生成器开发
上篇给大家从零开始搭建了一个我们的ASP.NET Core CMS系统的开发框架,具体为什么那样设计我也已经在第十篇文章中进行了说明.不过文章发布后很多人都说了这样的分层不是很合理,什么数据库实体应该 ...
- .NET Core实战项目之CMS 第十三章 开发篇-在MVC项目结构介绍及应用第三方UI
作为后端开发的我来说,前端表示真心玩不转,你如果让我微调一个位置的样式的话还行,但是让我写一个很漂亮的后台的话,真心做不到,所以我一般会选择套用一些开源UI模板来进行系统UI的设计.那如何套用呢?今天 ...
- .NET Core实战项目之CMS 第二章 入门篇-快速入门ASP.NET Core看这篇就够了
作者:依乐祝 原文链接:https://www.cnblogs.com/yilezhu/p/9985451.html 本来这篇只是想简单介绍下ASP.NET Core MVC项目的(毕竟要照顾到很多新 ...
随机推荐
- python接口自动化1
组织架构: 包括配置文件,反射.文件路径.Excel操作.测试报告生成 case.config [MODE] file_name=case_data.xlsx mode={"register ...
- 使用Tornado异步接入第三方(支付宝)支付
目前国内比较流行的第三方支付主要有支付宝和微信支付,博主最近研究了下如何用Python接入支付宝支付,这里我以Tornado作为web框架,接入支付宝构造支付接口. 使用Tornado异步接入支付宝支 ...
- navigator的一些冷知识
{ 监听屏幕旋转变化接口: orientationchange orientation.angle : 0 竖屏 , 90 向左横屏 , -90/270 向右横屏 , 180 倒屏 } screenO ...
- 深圳同城快跑笔试题目 2 实现json字符串保存到本地硬盘
//从给定位置读取Json文件 public static String readJson(String path){ //从给定位置获取文件 File file = new File(path); ...
- bs4库学习
# -*- coding:utf-8 -*- import bs4 import requests def tags_val(tag, key='', index=0): ''' tag指HTML元素 ...
- CF741C.Arpa’s overnight party and Mehrdad’s silent entering [构造 二分图染色]
CF741C - Arpa's overnight party and Mehrdad's silent entering 题意: 有 n 对情侣坐成一个圈,有两种食物Kooft and Zahre- ...
- FCC学习笔记(二)
Nest an Anchor Element within a Paragraph 作为参考,再次看一看a元素的图示: 例如: <p>Here's a <a href="h ...
- Linux 结构化命令
if -then 语句 if -then 语句有如下格式 if command then commands f i bash shell 的if语句会先运行if后面的那个命令,如果改命令的退出状态码是 ...
- 4.DHCP与PRE
如何配置IP地址 使用net-tools $ sudo ifconfig eth1 10.0.0.1/24 $ sudo ifconfig eth1 up 使用Iproute2 ...
- cadence网络表解读及导入
绘制完成原理图,并且通过了DRC检验之后,需要创建和导入网络表,下面网络表内容做简单总结.