.NET Core实战项目之CMS 第十五章 各层联动工作实现增删改查业务-阿里云开发者社区

开发者社区> 依乐祝> 正文

.NET Core实战项目之CMS 第十五章 各层联动工作实现增删改查业务

简介: 连着两天更新叙述性的文章大家可别以为我转行了!哈哈!今天就继续讲讲我们的.NET Core实战项目之CMS系统的教程吧!这个系列教程拖得太久了,所以今天我就以菜单部分的增删改查为例来讲述下我的项目分层之间的协同工作吧!如果你觉得文中有任何不妥的地方还请留言或者加入DotNetCore实战千人交流群637326624跟大伙进行交流讨论吧! 本文已收录至《.
+关注继续查看

连着两天更新叙述性的文章大家可别以为我转行了!哈哈!今天就继续讲讲我们的.NET Core实战项目之CMS系统的教程吧!这个系列教程拖得太久了,所以今天我就以菜单部分的增删改查为例来讲述下我的项目分层之间的协同工作吧!如果你觉得文中有任何不妥的地方还请留言或者加入DotNetCore实战千人交流群637326624跟大伙进行交流讨论吧!

本文已收录至《.NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划

作者:依乐祝

原文地址:https://www.cnblogs.com/yilezhu/p/10263714.html

写在前面

前面的章节中我们基本的增删改查都有了,甚至后台模板我们也找到并集成到了我们的CMS系统中了!那么剩下的就是对功能的开发了。对于功能的开发部分,我不会全部都拿出来讲,只会以一个菜单的例子来进行讲解!话不多说,开是吧!

各层之间的协作

先来讲讲我的分层协作的设计思路。虽然借助了DDDLite的部分思想,但是又与其不通,因为小项目严格按照DDD的思想来进行开发完全是找虐。如果有需要我后期会对结构进行调整来向DDD层次迁移。先上一张图吧:

1547195769549

这里所有的底层方法都是在Repository层进行的,加入仓储接口层的原因是为了解耦,一路跟着教程走来的朋友一定知道我目前我的仓储层是按照SQLServer数据库进行开发的,后期我会对MySQL,甚至PgSql的支持!这样的话对应用层丝毫不会有影响。

为什么这里用了应用层的服务?因为如果不实用应用层的话,设计到一些逻辑判断等等的话会把控制器搞的很庞大,代码量太多!为了使控制器简洁所以我加入了服务层的概念,这样服务层处理业务逻辑,把结果返回给控制器即可!当然如果涉及到多个事件的处理的话可能还需要借助MediatR来进行实现!什么你不知道MediatR是什么?那你可以看看我的这篇《ASP.NET Core中使用MediatR实现命令和中介者模式》文章的讲述。

实体层充当数据库实体映射以及DTO及ViewModel的角色!对于实体对象模型我更喜欢贫血模式的整洁干净的实体对象!不喜欢充斥各种代码的充血对象。所以里面都是POCO的简单生成。而ViewModel这个层可能我对这个层的概念设计有点模糊,所以DTO跟ViewModel的都混在一起了!这里你不用太过惊讶,因为你完全可以按照自己的理解来进行整理!自由发挥吧!

菜单的增删改查实现

这一节我们就开始写菜单的增删改查的代码实现吧!

菜单的列表页面功能实现

  1. 首选在我们的Czar.Cms.Admin 项目的Controllers控制器下建立MenuController控制器!如图所示:

1547197228635

里面的代码如下:

public class MenuController : BaseController
    {
        private readonly IMenuService _service;

        public MenuController(IMenuService service)
        {
            _service = service;
        }

        public IActionResult Index()
        {
            return View();
        }

    }

我们这里先列出首页(也就是列表页的代码)然后创建对应的Index.cshtml视图

  1. 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">&#xe61f;</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模板部分

  1. wwwroot\js\menu\下面创建一个menuList.js的js文件,来对页面的列表进行下初始化。并对一些操作进行控制。由于代码太长,所以只粘贴加载表格的部分代码如下所示:

1547198173155

对应的LoadData里面的代码如下:

1547198145587

是不是很简洁,那是因为所有的业务代码都在服务层实现了,不信?我把代码粘贴出来给你看:

1547198201852

这时候体会到服务层的好处了吧!

  1. 运行起来看下效果吧:

1547198251998

菜单增加修改功能实现

  1. 首先还是要写控制器方法来显示视图,代码如下:

1547198381483

  1. 由于修改编辑页面菜单有层级关系,所以我们需要加载顶层的菜单(画外音:只支持两级菜单)所以我们加载编辑页面的时候需要把顶层的菜单给加载出来,方法如下:

1547198494483

  1. 列表页弹出编辑或者新增的功能是在menu.js中实现的,代码如下:

1547198579342

  1. 新增或者编辑的时候需要判断菜单的别名是否重复,这里是通过layui的验证模块然后使用ajax实现的,视图代码如下:

1547198653419

js代码如下:

1547198676317

先判断是否符合规则,然后判断是否存在,这个需要对新增或者编辑分别进行处理!新增的时候需要判断是否存在即可,编辑的时候需要判断除自己外有没有重复的,代码如下:

1547198800139

可能你更喜欢看服务层及仓储层的代码,当然我也会毫不吝啬的贴出来,只是可能会消耗你些许流量来查看图片。

服务层:

1547347299803

仓储层代码(由于本人比较懒,所以只实现同步方法,异步获取的方法后期再补上吧,相信参照其他的写法你有何能自行实现):

1547347389722

这里需要注意,我在抽象接口里面都加了注释,所以实现里面就没加了,相信你也能看懂。换句话说,我懒~~~~

  1. 结果提交,这里需要注意只要涉及到结果提交的我都会用到ValidateAntiForgeryToken 还有就是我的结果提交全部是通过ajax进行的,并且把防伪Token放在Token里面的,代码如下:

1547347613595

至于为什么这里的Headers设置为X-CSRF-TOKEN-yilezhu这个你可以看我的上一节课程《.NET Core实战项目之CMS 第十四章 开发篇-防止跨站请求伪造(XSRF/CSRF)攻击处理

里面有讲述,所以这里就不做过多的讲述了。我们直接上结果提交的代码吧。

1547348249807

很简洁对不对?寥寥几行代码,可是实现真的这么简单吗?看看服务层你就知道了。

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的弹窗提醒,如下图所示,提醒您是否真的要删除!

1547377563781

  1. 好了,按照惯例我们第一步是不是要上js的代码啊?那还等什么?立马奉上

1547377653057

  1. 注意这里删除的时候也是需要进行防伪验证的,防止别人进行接口恶意删除,下面看下控制器中的代码,哇真干净就一行代码啊,有木有!

1547377792361

  1. 其实我想说服务层的代码有超过二十行,不信?我截图给你看吧!好好数数,加上换行是不是有二十行。

1547377883804

总结

今天讲的内容比较简单就是我们这个CMS系统设计的各层之前如何联动工作来实现增删改查业务的,望对大家了解这个系统有所帮助!至于其他的业务功能大家都可以参照这个进行开发!比如角色管理,用户管理等等!下节我们就来实现用户登录模块的功能。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Netty 源码阅读入门实战(一)-介绍
1 简介 以 Netty 为底层的框架 Netty 是什么 Netty 技术和方法的特点 设计 针对多种传输类型的统一接口 - 阻塞和非阻塞 简单但更强大的线程模型 真正的无连接的数据报套接字支持 链接逻辑支持复用 易用性 大量的 Javadoc 和 代码实例 除了在 JDK 1.6 + 额外的限制。
1414 0
艾伟也谈项目管理,ERP项目实施要未雨绸缪不要亡羊补牢
  在ERP项目中,要做到在项目实施的未雨绸缪,不会出现亡羊补牢的情况就需要项目管理和实施人员在项目推进过程中队下面的阶段进行预测,把握好发展的趋势,掌握项目的主动权。下面就提出一些建议,供大家讨论。希望对大家有用。
758 0
一文带你彻底厘清 Kubernetes 中的证书工作机制
云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 接触 Kubernetes 以来,我经常看到 Kubernetes 在不同的地方使用了证书(Certificate),在 Kubernetes 安装和组件启动参数中也需要配置大量证书相关的参数。
747 0
《妥协的完美主义:优秀产品经理的实践指南(卷二)》一第2章 产品设计项目管理2.1 项目管理内容
本节书摘来自异步社区《妥协的完美主义:优秀产品经理的实践指南(卷二)》一书中的第2章,第2.1节,作者 陈洁,更多章节内容可以访问云栖社区“异步社区”公众号查看 第2章 产品设计项目管理 妥协的完美主义:优秀产品经理的实践指南(卷二) 随着传统互联网逐渐向移动互联网行业过渡,移动产品设计项目的管理工作,越来越不同于工业设计时代的软件开发管理工作。
1733 0
《阿里巴巴Java Spring Boot 2.0开发实战课程》05课:三层MVC网站与架构分层误区、Java面试题
本期分享主题:三层架构MVC网站与分层架构误区、Java面试题,国内系统架构设计的文章和书籍。经常会搞错分层的概念,本课程进行了讲解。还有关于model概念的解析,以及Java Spring Boot2.0面试题。 另外java是免费的!
3230 0
【MyEcplise】导入项目后,会定时弹出一下错误MyEcplise tern was unable to complete your request in time.This couble happen if your project contains several large javaScr
Myecplise弹出错误如下:   错误代码: MyEcplise tern was unable to complete your request in time.This couble happen if your project contains several large javaScript libraies.
993 0
Netty4 实战精华EventLoop 和线程模型
简单地说,线程模型指定了操作系统、编程语言、框架或者应用程序的上下文中的线程管理的关键方面。 显而易见地,如何以及何时创建线程将对应用程序代码的执行产生显著的影响,因此开发人员需要理解与不同模型相关的权衡。
1217 0
+关注
依乐祝
学无先后,达者为师!爱写代码并乐于分享技术但不喜欢搞基!目前专注于ASP.NET Core微服务架构的研究。能够利用现有开源的微服务相关的技术开发支持高并发,高可用的分布式系统!本人微账信号:jkingzhu。.NETCore实战项目交流群637326624
49
文章
7
问答
文章排行榜
最热
最新
相关电子书
更多
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载
《2021云上架构与运维峰会演讲合集》
立即下载