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

自從上篇《基於MVC4+EasyUI的Web開發框架造成之旅--整體介紹》整體性的歸納,獲得不少同行的關注和支持,不過上一篇主要是介紹一個整體的界面效果和思路,本系列的文章將逐步介紹其中的細節,本文主要介紹整個Web開發框架中的MVC控制器的設計。在設計之初,我就但願儘量的減小代碼,提升編程模型的統一性。所以但願可以以基類繼承的方式,和我Winform開發框架同樣,儘量經過基類,而不是子類的重複代碼來實現各類通用的操做。javascript

一、登陸控制的控制器基類設計

咱們知道,通常咱們建立一個MVC的控制器,都是基於Controller這樣的基類來實現。以下代碼所示。html

    public class TestController : Controller
    {
        //
        // GET: /Test/

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

    }

在個人Winform開發框架裏面,用到了泛型的類型,很是方便實現業務邏輯和數據訪問基類的設計,控制器是否也能夠這樣作的呢?java

咱們知道,通常的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();
        }
................
    }

 

二、數據訪問業務基類控制器的設計

我在個人Winform開發框架裏面,對不少基類都使用泛型進行設計,這樣能夠傳遞相應的數據類型到基類裏面進行處理,以下面的BLL層的業務對象定義代碼以下所示。json

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>裏面傳入了兩個參數,定義代碼以下所示。dom

    /// <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>裏面了。ide

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

基於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)--自動生成圖標樣式文件和圖標的選擇操做

相關文章
相關標籤/搜索