基於MVC4+EasyUI的Web開發框架造成之旅--基類控制器CRUD的操做

在上一篇隨筆中,我對Web開發框架的整體界面進行了介紹,其中並提到了個人《Web開發框架》的控制器的設計關係,Web開發框架沿用了個人《Winform開發框架》的不少架構設計思路和特色,對Controller進行了封裝。使得控制器可以得到很好的繼承關係,並能以更少的代碼,更高效的開發效率,實現Web項目的開發工做,整個控制器的設計思路以下所示。javascript

從上圖的設計裏面能夠看到,我把主要能經過抽象封裝的CRUD方法都放到了BusinessController<B, T>類裏面,本文繼續詳細介紹這個Web框架控制器類的CRUD具體實現,以便使得你們瞭解個人整個Web開發框架的基類控制器的工做原理。html

一、基類的插入操做

咱們知道,通常常規的插入操做是很廣泛的操做,那麼咱們在MVC的Web界面上是如何調用的,後臺又是如何進行數據的處理的呢?java

在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,這樣咱們直接調用業務操做類就能夠插入了,代碼很簡單易懂。dom

        /// <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);
        }

二、基類的更新操做

上面咱們看了插入數據的操做,可能你們對下面介紹的數據更新操做,可能也已經有了一些瞭解了,其實它和插入操做的方法很相似的。異步

更新操做的視圖View中腳本代碼以下所示, 它經過控制器Information的Update方法進行更新數據。ide

                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方法。post

和上面的插入操做同樣,後臺是把數據序列化到了一個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);
        }

如通知公告的內容編輯界面以下所示。

三、基類的獲取對象數據方法

咱們在不少接口裏面,都要求獲取單一對象的數據信息,我在基類接口裏面定義了一個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');
            });
        }

具體效果以下所示:

四、基類刪除操做方法

在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開發框架造成之旅--整體介紹

基於MVC4+EasyUI的Web開發框架造成之旅--MVC控制器的設計

基於MVC4+EasyUI的Web開發框架造成之旅--界面控件的使用

基於MVC4+EasyUI的Web開發框架造成之旅--附件上傳組件uploadify的使用

基於MVC4+EasyUI的Web開發框架造成之旅--框架整體界面介紹

基於MVC4+EasyUI的Web開發框架造成之旅--基類控制器CRUD的操做

基於MVC4+EasyUI的Web開發框架造成之旅--權限控制

基於MVC4+EasyUI的Web開發框架經驗總結(1)-利用jQuery Tags Input 插件顯示選擇記錄

基於MVC4+EasyUI的Web開發框架經驗總結(2)- 使用EasyUI的樹控件構建Web界面

基於MVC4+EasyUI的Web開發框架經驗總結(3)- 使用Json實體類構建菜單數據

基於MVC4+EasyUI的Web開發框架經驗總結(4)--使用圖表控件Highcharts

基於MVC4+EasyUI的Web開發框架經驗總結(5)--使用HTML編輯控件CKEditor和CKFinder

基於MVC4+EasyUI的Web開發框架經驗總結(6)--在頁面中應用下拉列表的處理

基於MVC4+EasyUI的Web開發框架經驗總結(7)--實現省份、城市、行政區三者聯動

基於MVC4+EasyUI的Web開發框架經驗總結(8)--實現Office文檔的預覽

基於MVC4+EasyUI的Web開發框架經驗總結(9)--在Datagrid裏面實現外鍵字段的轉義操做

基於MVC4+EasyUI的Web開發框架經驗總結(10)--在Web界面上實現數據的導入和導出

基於MVC4+EasyUI的Web開發框架經驗總結(11)--使用Bundles處理簡化頁面代碼

基於MVC4+EasyUI的Web開發框架經驗總結(12)--利用Jquery處理數據交互的幾種方式

基於MVC4+EasyUI的Web開發框架經驗總結(13)--DataGrid控件實現自動適應寬帶高度

基於MVC4+EasyUI的Web開發框架經驗總結(14)--自動生成圖標樣式文件和圖標的選擇操做

相關文章
相關標籤/搜索