.NET Core實戰項目之CMS 第十五章 各層聯動工作實現增刪改查業務

来源:https://www.cnblogs.com/yilezhu/archive/2019/01/13/10263714.html
-Advertisement-
Play Games

連著兩天更新敘述性的文章大家可別以為我轉行了!哈哈!今天就繼續講講我們的.NET Core實戰項目之CMS系統的教程吧!這個系列教程拖得太久了,所以今天我就以菜單部分的增刪改查為例來講述下我的項目分層之間的協同工作吧!如果你覺得文中有任何不妥的地方還請留言或者加入DotNetCore實戰千人交流群6 ...


連著兩天更新敘述性的文章大家可別以為我轉行了!哈哈!今天就繼續講講我們的.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視圖

  2. 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/[email protected]("yyyyMMddHHmmss")"></script>
    }

    可能對於大多數人來說看到這個視圖很懵逼,怎麼沒有列表的信息啊,語法什麼的也都看不懂啊?別急,這裡用到的是Layui的一些語法!我們拆分下來看:

    <form class="layui-form">這個部分就是搜索功能部分

    <table id="menuList" lay-filter="menuList"></table>就是表格

    <script type="text/html" id="IsDisplay">這個是layui模板部分

  3. wwwroot\js\menu\下麵創建一個menuList.js的js文件,來對頁面的列表進行下初始化。並對一些操作進行控制。由於代碼太長,所以只粘貼載入表格的部分代碼如下所示:

    1547198173155

    對應的LoadData裡面的代碼如下:

    1547198145587

    是不是很簡潔,那是因為所有的業務代碼都在服務層實現了,不信?我把代碼粘貼出來給你看:

    1547198201852

    這時候體會到服務層的好處了吧!

  4. 運行起來看下效果吧:

    1547198251998

菜單增加修改功能實現

  1. 首先還是要寫控制器方法來顯示視圖,代碼如下:

    1547198381483

  2. 由於修改編輯頁面菜單有層級關係,所以我們需要載入頂層的菜單(畫外音:只支持兩級菜單)所以我們載入編輯頁面的時候需要把頂層的菜單給載入出來,方法如下:

    1547198494483

  3. 列表頁彈出編輯或者新增的功能是在menu.js中實現的,代碼如下:

    1547198579342

  4. 新增或者編輯的時候需要判斷菜單的別名是否重覆,這裡是通過layui的驗證模塊然後使用ajax實現的,視圖代碼如下:

    1547198653419

    js代碼如下:

    1547198676317

    先判斷是否符合規則,然後判斷是否存在,這個需要對新增或者編輯分別進行處理!新增的時候需要判斷是否存在即可,編輯的時候需要判斷除自己外有沒有重覆的,代碼如下:

    1547198800139

    可能你更喜歡看服務層及倉儲層的代碼,當然我也會毫不吝嗇的貼出來,只是可能會消耗你些許流量來查看圖片。

    服務層:

    1547347299803

    倉儲層代碼(由於本人比較懶,所以只實現同步方法,非同步獲取的方法後期再補上吧,相信參照其他的寫法你有何能自行實現):

    1547347389722

    這裡需要註意,我在抽象介面裡面都加了註釋,所以實現裡面就沒加了,相信你也能看懂。換句話說,我懶~~~~

  5. 結果提交,這裡需要註意只要涉及到結果提交的我都會用到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

  2. 註意這裡刪除的時候也是需要進行防偽驗證的,防止別人進行介面惡意刪除,下麵看下控制器中的代碼,哇真乾凈就一行代碼啊,有木有!

    1547377792361

  3. 其實我想說服務層的代碼有超過二十行,不信?我截圖給你看吧!好好數數,加上換行是不是有二十行。

    1547377883804

總結

今天講的內容比較簡單就是我們這個CMS系統設計的各層之前如何聯動工作來實現增刪改查業務的,望對大家瞭解這個系統有所幫助!至於其他的業務功能大家都可以參照這個進行開發!比如角色管理,用戶管理等等!下節我們就來實現用戶登錄模塊的功能。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 稍微關心編程語言的使用趨勢的人都知道,最近幾年,國內最火的兩種語言非 Python 與 Go 莫屬,於是,隔三差五就會有人問:這兩種語言誰更厲害/好找工作/高工資…… 對於編程語言的爭論,就是猿界的生理周期,每個月都要鬧上一回。到了年末,各類榜單也是特別抓人眼球,鬧得更凶。 其實,它們各有對方所無法 ...
  • 一、SSM搭建 1、使用的工具: myeclipse+jdk8+maven+MySQL+Tomcat8.5 2、配製文件截: 二、配置文件 1、web.xml 1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http:// ...
  • 轉載自CSDN的文章 https://blog.csdn.net/gongpulin/article/details/80972806 國內的go get問題的解決 轉載自CSDN的文章 https://blog.csdn.net/gongpulin/article/details/80972806 ...
  • 本文介紹如何自定義迭代器,涉及到類的運算符重載,包括 的索引迭代,以及 、`__next__ __contains__`,如果不瞭解這些知識可跳過本文。 索引迭代方式 索引取值和分片取值 元組、列表、字典、集合、字元串都支持索引取值操作和分片操作。 分片操作實際上將一個slice對象當作索引位傳遞給 ...
  • 1 public static MvcHtmlString PageControl(this HtmlHelper html, PageData page) 2 { 3 if (page == null || page.totalpage == 0) 4 return MvcHtmlString.C... ...
  • class Program { static void Main(string[] args) { Console.WriteLine("please input a number:"); int n =int.Parse ( Console.ReadLine()); int [,] c=new i ...
  • Vue + WebApi 小項目:構造自己的線上 Markdown 筆記本應用 目錄 概要 知識點 完整示例圖 代碼與資源文件 流程步驟 概要 基於 MVP 最小可行性產品設計理念,我們先完成一個可以使用,並具備基本功能的 Markdown 筆記本應用,再進行逐步完善。 知識點 本文會指導初學者如何 ...
  • Docker的使用初探(二):Docker與.NET Core的結合 [TOC] 在二者的結合上,微軟官方給予了很大的支持,從官方發佈的一些文章和VS 2017在建立.NET Core項目時自帶的Docker選項都可以看出來,這也與Core的跨平臺特性有很大的關係,而Docker正是可以選擇以Lin ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...