1. 程式人生 > >基於MVC4+EasyUI的Web開發框架形成之旅--MVC控制器的設計

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

自從上篇《基於MVC4+EasyUI的Web開發框架形成之旅--總體介紹》總體性的概括,得到很多同行的關注和支援,不過上一篇主要是介紹一個總體的介面效果和思路,本系列的文章將逐步介紹其中的細節,本文主要介紹整個Web開發框架中的MVC控制器的設計。在設計之初,我就希望儘可能的減少程式碼,提高程式設計模型的統一性。因此希望能夠以基類繼承的方式,和我Winform開發框架一樣,儘可能通過基類,而不是子類的重複程式碼來實現各種通用的操作。

1、登入控制的控制器基類設計

我們知道,一般我們建立一個MVC的控制器,都是基於Controller這樣的基類來實現。如下程式碼所示。

    public
class TestController : Controller { // // GET: /Test/ public ActionResult Index() { return View(); } }

在我的Winform開發框架裡面,用到了泛型的型別,非常方便實現業務邏輯和資料訪問基類的設計,控制器是否也可以這樣做的呢?

我們知道,一般的MVC控制器需要驗證使用者是否已經登陸了,這也是很多常見Web操作前的驗證,還有對異常的處理,在MVC的基類,可以一併進行記錄(這個非常不錯),於是我們先來設計一個驗證使用者身份是否登陸的基類BaseController

    /// <summary>
    /// 所有需要進行登入控制的控制器基類
    /// </summary>
    public class BaseController : Controller 
    {
        /// <summary>
        /// 當前登入的使用者屬性
        /// </summary>
        public UserInfo CurrentUserInfo { get; set; }

        /// <summary>
        /// 重新基類在Action執行之前的事情
        
/// </summary> /// <param name="filterContext">重寫方法的引數</param> protected override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); //得到使用者登入的資訊 CurrentUserInfo = Session["UserInfo"] as UserInfo; //判斷使用者是否為空 if (CurrentUserInfo == null) { Response.Redirect("/Login/Index"); } } protected override void OnException(ExceptionContext filterContext) { base.OnException(filterContext); //錯誤記錄 WHC.Framework.Commons.LogTextHelper.Error(filterContext.Exception); // 當自定義顯示錯誤 mode = On,顯示友好錯誤頁面 if (filterContext.HttpContext.IsCustomErrorEnabled) { filterContext.ExceptionHandled = true; this.View("Error").ExecuteResult(this.ControllerContext); } }
........................ }

有了這個基類,我們在主頁的Home控制類,就可以使用使用者資訊物件了進行操作了,而且必須要求客戶登陸了。

    public class HomeController : BaseController
    {
        public ActionResult Index()
        {
            if (CurrentUserInfo != null)
            {
                ViewBag.FullName = CurrentUserInfo.FullName;
                ViewBag.Name = CurrentUserInfo.Name;
            }
            return View();
        }
................
    }

2、資料訪問業務基類控制器的設計

我在我的Winform開發框架裡面,對很多基類都使用泛型進行設計,這樣可以傳遞相應的資料型別到基類裡面進行處理,如下面的BLL層的業務物件定義程式碼如下所示。

namespace WHC.Security.BLL
{
    /// <summary>
    /// 角色資訊業務管理類
    /// </summary>
    public class Role : BaseBLL<RoleInfo>
    {

....................
    /// <summary>
    /// 業務基類物件
    /// </summary>
    /// <typeparam name="T">業務物件型別</typeparam>
    public class BaseBLL<T> where T : BaseEntity, new()
    {

        /// <summary>
        /// 插入指定物件到資料庫中
        /// </summary>
        /// <param name="obj">指定的物件</param>
        /// <returns>執行操作是否成功。</returns>
        public virtual bool Insert(T obj)
        {
            return baseDal.Insert(obj);
        }

............

業務物件Role,要求傳入RoleInfo給基類處理,這樣基類就能定義到都對應的T為具體的RoleInfo型別了。在MVC的控制器是否也可以這樣做呢?當然可以,下面是我定義的一個控制器繼承關係圖。

上面的介紹也已經比較明白了,其實就是在BusinessController<B, T>裡面傳入了兩個引數,定義程式碼如下所示。

    /// <summary>
    /// 本控制器基類專門為訪問資料業務物件而設的基類
    /// </summary>
    /// <typeparam name="B">業務物件型別</typeparam>
    /// <typeparam name="T">實體類型別</typeparam>
    public class BusinessController<B, T> : BaseController
        where B : class
        where T : WHC.Framework.ControlUtil.BaseEntity, new()
    {

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

................

我根據傳入的BLL業務物件型別B,物件實體類型別T,那麼我們就可以構造對應的baseBLL物件,然後呼叫其基類介面實現基本的操作,如插入,刪除,更新,查詢等等,這樣的模式就和我的Winform開發框架的理念非常吻合了。

我們以角色控制器來說明,它的定義如下所示,如果不需要實現額外的介面(除了常見的操作),基本上不需要寫任何程式碼了,因為所有很多常見的操作,都已經封裝在了基類控制器BusinessController<B, T>裡面了。

    /// <summary>
    /// 角色業務操作控制器
    /// </summary>
    public class RoleController : BusinessController<Role, RoleInfo>
    {
        public RoleController() : base()
        {
        }

...............

對於一些需要特殊資料處理的操作,可以增加一些自定義的介面函式,也可以重寫基類的一些介面,實現資料的相應處理。如我的選單介面顯示中,需要根據縮排的層級對選單名稱進行縮排,以便更好的展示它們的層級結構,那麼我就需要對分頁函式進行重寫了,如下程式碼所示是整個選單Menu類的控制器類程式碼。

    public class MenuController : BusinessController<Menu, MenuInfo>
    {
        public override ActionResult FindWithPager()
        {
            string where = GetPagerCondition(); //基類實現
            PagerInfo pagerInfo = GetPagerInfo(); //基類實現            
            List<MenuInfo> list = baseBLL.FindWithPager(where, pagerInfo);
            list = CollectionHelper<MenuInfo>.Fill("-1", 0, list, "PID", "ID", "Name");

            //Json格式的要求{total:22,rows:{}}
            //構造成Json的格式傳遞
            var result = new { total = pagerInfo.RecordCount, rows = list };
            return JsonDate(result);
        }

        /// <summary>
        /// 用作下拉列表的選單Json資料
        /// </summary>
        /// <returns></returns>
        public ActionResult GetDictJson()
        {
            List<MenuInfo> list = baseBLL.GetAll();
            list = CollectionHelper<MenuInfo>.Fill("-1", 0, list, "PID", "ID", "Name");

            List<CListItem> itemList = new List<CListItem>();
            foreach (MenuInfo info in list)
            {
                itemList.Add(new CListItem(info.Name, info.ID));
            }
            return Json(itemList, JsonRequestBehavior.AllowGet);
        }
    }

我們來看看一段HTML頁面裡面,使用javascript指令碼呼叫控制器API來實現資料的繫結的操作,也就是使用示例。

            $.getJSON("/Role/FindById?r=" + Math.random() + "&id=" + id, function (json) {
                $("#txtID").val(json.ID);
                $("#txtName").val(json.Name);
                $("#txtNote").val(json.Note);
            });

上面這個很標準的介面FindById是業務基類控制器BusinessController<B, T>裡提供的。

當然,BusinessController裡面可以類似我Winform開發框架裡面基類一樣,提供很豐富的操作介面,如返回列表Json集合,增刪改查的操作及返回,分頁資料的返回,以及一些特殊的操作都可以實現。而這些都不需要子類進行任何實現。

如下面實際案例的使用者登陸日誌,裡面的介面功能還是很豐富的,當他的控制器業務類不需要任何實現,只需要繼承基類即可。

    public class LoginLogController : BusinessController<LoginLog, LoginLogInfo>
    {
        public LoginLogController() : base()
        {
        }

    }

介面部分程式碼如下所示。

        //實現對DataGird控制元件的繫結操作
        function InitGrid(queryData) {
            $('#grid').datagrid({   //定位到Table標籤,Table標籤的ID是grid
                url: '/LoginLog/FindWithPager',   //指向後臺的Action來獲取當前使用者的資訊的Json格式的資料
                title: '使用者登陸日誌', 
                //下面的這些屬性如果誰不太清楚的話我建議去官方網站去學習
                iconCls: 'icon-view',
                height: 450,
                nowrap: true,
                autoRowHeight: false,
                striped: true,
                collapsible: true,
                pagination: true,
                rownumbers: true,
                //sortName: 'ID',    //根據某個欄位給easyUI排序
                sortOrder: 'asc',
                remoteSort: false,
                idField: 'ID',
                queryParams: queryData,  //非同步查詢的引數
                columns: [[
                    { field: 'ck', checkbox: true },   //選擇
                    { title: 'ID', field: 'ID', width: 40, sortable: true },  //主鍵
                     { title: '登入使用者ID', field: 'User_ID', width: 80, sortable: true },
                     { title: '登入名稱', field: 'LoginName', width: 80, sortable: true },
                     { title: '真實名稱', field: 'FullName', width: 80, sortable: true },
                     { title: '日誌描述', field: 'Note', width: 100, sortable: true },
                     { title: 'IP地址', field: 'IPAddress', width: 100, sortable: true },
                     { title: 'Mac地址', field: 'MacAddress', width: 120, sortable: true },
                     { title: '系統編號', field: 'SystemType_ID', width: 120, sortable: true },
                     { title: '記錄日期', field: 'LastUpdated', width: 120, sortable: true },
                ]],
                toolbar: [{
                    id: 'btnAdd',
                    text: '新增',
                    iconCls: 'icon-add',
                    handler: function () {                        
                        ShowAddDialog();//實現新增記錄的頁面
                    }
                }, '-', {
                    id: 'btnEdit',
                    text: '修改',
                    iconCls: 'icon-edit',
                    handler: function () {                        
                        ShowEditOrViewDialog();//實現修改記錄的方法
                    }
                }, '-', {
                    id: 'btnDelete',
                    text: '刪除',
                    iconCls: 'icon-remove',
                    handler: function () {                        
                        Delete();//實現直接刪除資料的方法
                    }
                }, '-', {
                    id: 'btnView',
                    text: '檢視',
                    iconCls: 'icon-table',
                    handler: function () {                        
                        ShowEditOrViewDialog("view");//實現檢視記錄詳細資訊的方法
                    }
                }, '-', {
                    id: 'btnReload',
                    text: '重新整理',
                    iconCls: 'icon-reload',
                    handler: function () {
                        //實現重新整理欄目中的資料
                        $("#grid").datagrid("reload");
                    }
                }]
            });

            $('#grid').datagrid({
                onDblClickRow: function (rowIndex, rowData) {
                    $('#grid').datagrid('uncheckAll');
                    $('#grid').datagrid('checkRow', rowIndex);
                    ShowEditOrViewDialog();
                }
            });
        }

這個就是我的控制器設計的中心思想了,下一篇繼續介紹整體的MVC系列的Web開發框架,介紹其中Web介面部分的處理和相關經驗,希望大家多多提出寶貴的意見。

基於MVC4+EasyUI的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開發框架形成--MVC控制器設計

自從上篇《基於MVC4+EasyUI的Web開發框架形成之旅--總體介紹》總體性的概括,得到很多同行的關注和支援,不過上一篇主要是介紹一個總體的介面效果和思路,本系列的文章將逐步介紹其中的細節,本文主要介紹整個Web開發框架中的MVC控制器的設計。在設計之初,我就希望儘可能的減少程式碼,提高程式設計模型的統一

基於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開發框架形成--基類控制器CRUD的操作

在上一篇隨筆中,我對Web開發框架的總體介面進行了介紹,其中並提到了我的《Web開發框架》的控制器的設計關係,Web開發框架沿用了我的《Winform開發框架》的很多架構設計思路和特點,對Controller進行了封裝。使得控制器能夠獲得很好的繼承關係,並能以更少的程式碼,更高效的開發效率,實現Web專案的開

基於MVC4+EasyUI的Web開發框架形成--介面控制元件的使用

在前面介紹了兩篇關於我的基於MVC4+EasyUI技術的Web開發框架的隨筆,本篇繼續介紹其中介面部分的一些使用知識,包括控制元件的賦值、取值、清空,以及相關的使用。 我們知道,一般Web介面包括的介面控制元件有:單行文字框、多行文字框、密碼文字框、下拉列表Combobox、日期輸入控制元件、數值輸入控制元

基於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。本質上是包掃描 通俗講就是搭