基於MVC4+EasyUI的Web開發框架形成之旅--基類控制器CRUD的操作
在上一篇隨筆中,我對Web開發框架的總體介面進行了介紹,其中並提到了我的《Web開發框架》的控制器的設計關係,Web開發框架沿用了我的《Winform開發框架》的很多架構設計思路和特點,對Controller進行了封裝。使得控制器能夠獲得很好的繼承關係,並能以更少的程式碼,更高效的開發效率,實現Web專案的開發工作,整個控制器的設計思路如下所示。
從上圖的設計裡面可以看到,我把主要能通過抽象封裝的CRUD方法都放到了BusinessController<B, T>類裡面,本文繼續詳細介紹這個Web框架控制器類的CRUD具體實現,以便使得大家瞭解我的整個Web開發框架的基類控制器的工作原理。
1、基類的插入操作
我們知道,一般常規的插入操作是很普遍的操作,那麼我們在MVC的Web介面上是如何呼叫的,後臺又是如何進行資料的處理的呢?
在MVC的View檢視程式碼裡面,我們新增資料的時候,javascript指令碼程式碼是這樣的:
var postData = $("#ffAdd").serializeArray(); $.post("/Information/Insert", postData, function (data) { if (data = "true") {//新增成功 1.關閉彈出層,2.重新整理DataGird $.messager.alert("提示", "新增成功"); $("#DivAdd").dialog("close"); $("#grid").datagrid("reload"); $("#ffAdd").form("clear"); //本頁面的型別為【通知公告】,固定不變 $("#Category").val("通知公告"); } else { $.messager.alert("提示", "新增失敗,請您檢查"); } });
其中的serializeArray就把該表單要提交的資料序列號到一個字串裡面了,裡面的資料可能類似A=a&B=b&C=c 這樣的字串裡面了,通過POST呼叫控制器Information的Insert方法,實現資料的插入。由於控制器Information是具體業務類,因此它繼承自BusinessController<B, T>,也就是會呼叫BusinessController<B, T>控制器的Insert方法。
如字典資料新增的介面如下所示。
那麼後臺的接收方法如何呢?其實後臺是把資料序列化到了一個FormCollection物件的集合裡面了,但是,我們還可以使用物件T(實體類),讓這些資料集合賦值給對應的實體物件屬性,如下就是我的後臺控制器的插入方法,它的引數是一個實體類T,這樣我們直接呼叫業務操作類就可以插入了,程式碼很簡單易懂。
/// <summary> /// 插入指定物件到資料庫中 /// </summary> /// <param name="info">指定的物件</param> /// <returns>執行操作是否成功。</returns> public virtual ActionResult Insert(T info) {bool result = false; if (info != null) { result = baseBLL.Insert(info); } return Content(result); }
2、基類的更新操作
上面我們看了插入資料的操作,可能大家對下面介紹的資料更新操作,可能也已經有了一些瞭解了,其實它和插入操作的方法很類似的。
更新操作的檢視View中指令碼程式碼如下所示, 它通過控制器Information的Update方法進行更新資料。
var ID = $("#ID1").val(); var postData = $("#ffEdit").serializeArray(); $.post("/Information/Update?ID=" + ID, postData, function (date) { if (date == "true") { //修改成功,關閉彈出層,重新整理DataGird $.messager.alert("提示", "修改成功"); $("#DivEdit").dialog('close'); $("#grid").datagrid("reload"); } else { $.messager.alert("提示", "修改失敗,請您檢查"); } });
由於控制器Information是具體業務類,因此它繼承自BusinessController<B, T>,也就是會呼叫BusinessController<B, T>控制器的Update方法。
和上面的插入操作一樣,後臺是把資料序列化到了一個FormCollection物件的集合裡面了,我們可以使用類似和插入方法的操作,如下所示。
/// <summary> /// 更新物件屬性到資料庫中 /// </summary> /// <param name="info">指定的物件</param> /// <param name="id">主鍵ID的值</param> /// <returns>執行成功返回<c>true</c>,否則為<c>false</c>。</returns> public virtual ActionResult Update(T info, string id) { bool result = baseBLL.Update(info, id); return Content(result); }
但是,如果使用以上的程式碼作為更新資料的程式碼,那麼在編輯介面裡,如果只是顯示編輯部分表的資料,那麼可能導致很多屬性會被初始化為實體類的預設值,顯然這樣不符合我們的要求,我們可能只是進行部分更新,那麼我們進行部分更新的控制器方法應該如何設計呢?
前面我們說到,資料會被序列號到一個FormCollection物件集合裡面,更新方法也一樣,那麼我們可以把更新操作的介面定義為如下程式碼所示,檢視操作程式碼不變化:
/// <summary> /// 更新物件屬性到資料庫中 /// </summary> /// <param name="info">指定的物件</param> /// <param name="id">主鍵ID的值</param> /// <returns>執行成功返回<c>true</c>,否則為<c>false</c>。</returns> public virtual ActionResult Update(string id, FormCollection formValues)
我們可以通過除錯的方法,查詢到FormCollection裡面的值就是我們更新介面裡面的資料(注意:可能是實體類的部分資料)。但使用了這個方法後,我們還需要把FormCollection物件裡面的資料轉換為實體類的資訊,我們才好呼叫BaseBLL裡面的介面進行更新資料。但是不同的實體類,有不同的屬性,我們如何能夠抽象把他們的屬性都賦值了呢?
答案是通過反射屬性方式,把FormCollection裡面屬性的值賦值給對應實體類屬性的值。下面我們來介紹下具體的程式碼實現了。
/// <summary> /// 更新物件屬性到資料庫中 /// </summary> /// <param name="info">指定的物件</param> /// <param name="id">主鍵ID的值</param> /// <returns>執行成功返回<c>true</c>,否則為<c>false</c>。</returns> public virtual ActionResult Update(string id, FormCollection formValues) { T obj = baseBLL.FindByID(id); if (obj != null) { //遍歷提交過來的資料(可能是實體類的部分屬性更新) foreach (string key in formValues.Keys) { string value = formValues[key]; System.Reflection.PropertyInfo propertyInfo = obj.GetType().GetProperty(key); if (propertyInfo != null) { try { // obj物件有key的屬性,把對應的屬性值賦值給它(從字串轉換為合適的型別) //如果轉換失敗,會丟擲InvalidCastException異常 propertyInfo.SetValue(obj, Convert.ChangeType(value, propertyInfo.PropertyType), null); } catch { } } } } bool result = baseBLL.Update(obj, id); return Content(result); }
通過物件propertyInfo的SetValue方法,可以把字串的值,轉換為實體類對應屬性型別的值,順利進行賦值。
如果是業務類需要提交一些HTML的程式碼,那麼我們需要在具體的業務類裡面,重寫插入、更新方法並設定一下 [ValidateInput(false)] 標識才可以。
[ValidateInput(false)] public override ActionResult Insert(InformationInfo info) { info.Editor = CurrentUser.Name; info.EditTime = DateTime.Now; return base.Insert(info); } [ValidateInput(false)] public override ActionResult Update(string id, FormCollection formValues) { return base.Update(id, formValues); }
如通知公告的內容編輯介面如下所示。
3、基類的獲取物件資料方法
我們在很多接口裡面,都要求獲取單一物件的資料資訊,我在基類接口裡面定義了一個FindByID方法,就是從業務物件裡面,根據主鍵ID資訊,獲取一個物件的資料,把他轉換為Json傳遞到View視圖裡面使用即可。
/// <summary> /// 查詢資料庫,檢查是否存在指定ID的物件 /// </summary> /// <param name="id">物件的ID值</param> /// <returns>存在則返回指定的物件,否則返回Null</returns> public virtual ActionResult FindByID(string id) { ActionResult result = Content(""); T info = baseBLL.FindByID(id); if (info != null) { result = JsonDate(info); } return result; }
其中的JsonDate方法是為了避免日期型別的數值在序列化中出現錯誤格式,包裝的一個方法,如下所示。
/// <summary> /// 返回處理過的時間的Json字串 /// </summary> /// <param name="date"></param> /// <returns></returns> public ContentResult JsonDate(object date) { var timeConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" }; return Content(JsonConvert.SerializeObject(date, Formatting.Indented, timeConverter)); }
在View視圖裡面使用控制器方法,繫結資料到檢視介面裡面的程式碼如下所示。
//繫結檢視詳細資訊的方法 function BindViewInfo() { var ID = $("#grid").datagrid('getSelections')[0].ID; //傳送請求 $.getJSON("/Information/FindByID?r=" + Math.random() + "&id=" + ID, function (info) { $("#ID2").val(info.ID); $("#Title2").text(info.Title); $("#Content2").html(info.Content); $("#Attachment_GUID2").text(info.Attachment_GUID); $("#Editor2").text(info.Editor); $("#EditTime2").text(info.EditTime); ShowUpFiles(info.Attachment_GUID, 'divViewAttach'); }); }
具體效果如下所示:
4、基類刪除操作方法
在GridView裡面,我們提供了刪除資料的按鈕,具體視圖裡面使用的程式碼如下所示。
//然後確認傳送非同步請求的資訊到後臺刪除資料 $.messager.confirm("刪除確認", "您確認刪除選定的記錄嗎?", function (deleteAction) { if (deleteAction) { $.get("/Information/DeletebyIds", postData, function (data) { if (data == "true") { $.messager.alert("提示", "刪除選定的記錄成功"); $("#grid").datagrid("reload"); } else { $.messager.alert("提示", data); } }); } });
後臺控制器的基類刪除方法如下所示。
/// <summary> /// 刪除多個ID的記錄 /// </summary> /// <param name="ids">多個id組合,逗號分開(1,2,3,4,5)</param> /// <returns></returns> public virtual ActionResult DeleteByIds(string ids) {bool result = false; if (!string.IsNullOrEmpty(ids)) { string[] idArray = ids.Split(new char[] { ',' }); foreach (string strId in idArray) { if (!string.IsNullOrEmpty(strId)) { baseBLL.Delete(strId); } } result = true; } return Content(result); }
以上就是基類控制器增刪改查的一些通用方法的封裝,業務物件控制器類,如果有特殊的需要,可以對方法進行重寫即可,非常方便使用,從而減少了很多重複編寫的程式碼,並可以使得頁面的操作統一化,提高生產效率。
基於MVC4+EasyUI的Web開發框架的系列文章:
相關推薦
基於MVC4+EasyUI的Web開發框架形成之旅--基類控制器CRUD的操作
在上一篇隨筆中,我對Web開發框架的總體介面進行了介紹,其中並提到了我的《Web開發框架》的控制器的設計關係,Web開發框架沿用了我的《Winform開發框架》的很多架構設計思路和特點,對Controller進行了封裝。使得控制器能夠獲得很好的繼承關係,並能以更少的程式碼,更高效的開發效率,實現Web專案的開
(轉)基於MVC4+EasyUI的Web開發框架形成之旅--MVC控制器的設計
cli dex txt strip -1 function 特殊 remote 文章 http://www.cnblogs.com/wuhuacong/p/3284628.html 自從上篇《基於MVC4+EasyUI的Web開發框架形成之旅--總體介紹》總體性的概括,得
基於MVC4+EasyUI的Web開發框架形成之旅--附件上傳元件uploadify的使用
大概一年前,我還在用Asp.NET開發一些行業管理系統的時候,就曾經使用這個元件作為檔案的上傳操作,在隨筆《Web開發中的檔案上傳元件uploadify的使用》中可以看到,Asp.NET中如何使用這個元件進行檔案上傳的,當時上傳檔案的處理主要也是使用ashx一般處理程式來進行處理的。本文主要介紹我的Web開發
基於MVC4+EasyUI的Web開發框架形成之旅--總體介紹
最近花了很多時間在重構和進一步提煉Winform開發框架的工作上,加上時不時有一些專案的開發工作,我部落格裡面介紹Web開發框架的文章比較少,其實以前在單位工作,80%的時間是做Web開發的,很早就形成了自己的一套Web開發框架,但是由於一些個人原因,一直沒有來得及好好整理和推廣,其實那套Web開發框架對大多
基於MVC4+EasyUI的Web開發框架形成之旅--許可權控制
我在上一篇隨筆《基於MVC4+EasyUI的Web開發框架形成之旅--框架總體介面介紹》中大概介紹了基於MVC的Web開發框架的許可權控制總體思路。其中的許可權控制就是分為“使用者登入身份驗證”、“控制器方法許可權控制”、“介面元素許可權控制”三種控制方式,可以為Web開發框架本身提供了很好使用者訪問控制和許
基於MVC4+EasyUI的Web開發框架形成之旅--介面控制元件的使用
在前面介紹了兩篇關於我的基於MVC4+EasyUI技術的Web開發框架的隨筆,本篇繼續介紹其中介面部分的一些使用知識,包括控制元件的賦值、取值、清空,以及相關的使用。 我們知道,一般Web介面包括的介面控制元件有:單行文字框、多行文字框、密碼文字框、下拉列表Combobox、日期輸入控制元件、數值輸入控制元
基於MVC4+EasyUI的Web開發框架形成之旅--MVC控制器的設計
自從上篇《基於MVC4+EasyUI的Web開發框架形成之旅--總體介紹》總體性的概括,得到很多同行的關注和支援,不過上一篇主要是介紹一個總體的介面效果和思路,本系列的文章將逐步介紹其中的細節,本文主要介紹整個Web開發框架中的MVC控制器的設計。在設計之初,我就希望儘可能的減少程式碼,提高程式設計模型的統一
基於MVC4+EasyUI的Web開發框架形成之旅--框架總體介面介紹
在前面介紹了一些關於最新基於MVC4+EasyUI的Web開發框架文章,雖然Web開發框架的相關技術文章會隨著技術的探討一直寫下去,不過這個系列的文章,到這裡做一個總結,展示一下整體基於MVC4+EasyUI的介面效果,讓大家對這款Web開發框架有一個形象的瞭解,介面設計以及相關思路可以借鑑提高,也可以對相關
Entity Framework 實體框架的形成之旅--基於泛型的倉儲模式的實體框架(1)
一些讀者也經常問問一些問題,不過最近我確實也很忙,除了處理日常工作外,平常主要的時間也花在了繼續研究微軟的實體框架(EntityFramework)方面了。這個實體框架加入了很多特性(例如LINQ等),目前也已經應用的比較成熟了,之所以一直沒有整理成一個符合自己開發模式的
前端開發框架總結之Angular實用技巧(六)
前端開發框架總結之Angular實用技巧(六)
前端開發框架總結之Angular實用技巧(五)
前端開發框架總結之Angular實用技巧(五) 上文講了Angular中網路請求相關的知識,掌握了這些,我們就可以
前端開發框架總結之Angular實用技巧(四)
前端開發框架總結之Angular實用技巧(四) 上文講了Angular中路由的相關的知識,掌握了這些,我們就可以構建比較複雜的頁面
前端開發框架總結之Angular實用技巧(三)
前端開發框架總結之Angular實用技巧(三) 上文講了Angular中頁面重新整理和資
前端開發框架總結之Angular實用技巧(二)
前端開發框架總結之Angular實用技巧(二) 上文講了Angular自
前端開發框架總結之Angular實用技巧(一)
前端開發框架總結之Angular實用技巧(一) 前言: 前一段時間接觸了Angul
前端開發框架總結之利用Jtopo實現網路拓撲功能(四)
前端開發框架總結之利用Jtopo實現網路拓撲功能(四) 上文我們講了拓撲容器相關的互動設計和實現思路以及一些關鍵技術細節。至此,我們已經覆蓋了結
前端開發框架總結之利用Jtopo實現網路拓撲功能(三)
前端開發框架總結之利用Jtopo實現網路拓撲功能(三) 上文我們講了一些拓撲連線、拓撲文字節點相關的互動設計和實現思路以及一些關鍵技術細節。本文
前端開發框架總結之利用Jtopo實現網路拓撲功能(二)
前端開發框架總結之利用Jtopo實現網路拓撲功能(二) 上文我們講了一些拓撲結點生成的實際場景設計和實現思路以及一些關鍵技術細節。本文我們繼續我們的拓撲管理
前端開發框架總結之利用Jtopo實現網路拓撲功能(一)
前端開發框架總結之利用Jtopo實現網路拓撲功能(一) 前言: 前段時間由於專案需要實現一個網路裝置拓撲管理的
springboot全能框架學習之旅
springboot隨著動態語言的發展,java需要獨立執行的基於spring框架內的搭建工程工具。 1.獨立執行spring專案。不需要tomcat 2.內嵌servlet容器。外部只有jdk 3.提供starter'簡化maven依賴配置。 4.自動配置spring。本質上是包掃描 通俗講就是搭