這幾年來做了很多個網站系統,一直堅持使用asp.net mvc建站,每次都從頭開始做Layout,CSS,做許可權管理等等,有點惱火,將這幾年的代碼好好整理了一下,準備搭建一個架構。
一、目標
0)面向領域:網站後台管理系統、MIS等結構相對規範的管理類應用;
a)基於Asp.net MVC 4搭建系統架構
b)整合RBAC基於角色的許可權管理機制,能夠控制到控制項層級
c)整合一些基礎服務:資料字典、日誌記錄等
d)使用AJAX特性(使用JQuery與MVC的Partiview等實現)
e)外掛程式機制:架構搭建完畢之後,新開發的功能模組能夠直接以外掛程式的形式安裝到系統架構中運行
f)使用EF Codefirst
二、系統設計
A)基於RBAC的許可權管理系統
參考了園子裡一些許可權管理系統,使用了 模組->資源->操作 作為最基礎的許可權元素,[資源,操作]作為 基本的許可權原子,將許可權原子賦給“角色”
為了配合RBAC的使用,繼承 AuthorizeAttribute 來修飾Action
B)菜單架構
此應用程式框架主要面向管理系統,所以導覽功能表設計為兩級,頂部導航為一級菜單,左側 邊為二級菜單,菜單能與許可權進行關聯,配置許可權時可影響到菜單;,Menu2根據所選擇Menu1發生變化;
C)Ajax架構
此應用程式框架中,Content Area為Ajax更新內容,使用JQuery的 $.get 操作訪問 Action,在Action中返回 PartialView,然後更新到 ContentArea中;
全部使用Ajax來載入,帶來一個問題,無法使用前進、後退、還有重新整理等操作,借鑒網上一些資料,使用了 "jquery.bbq.js"的外掛程式,通過url的hashchange使系統能夠在瀏覽器中保持狀態,能夠使用 “前進“,”後退“,”重新整理“等操作;通過將真實的請求代碼加入到URL”#"後,來載入所需要的內容,JS代碼如下:
$(window).bind('hashchange', function (e) { var hash = window.location.hash || ''; if (oldHash == '') { // 需要選擇預設菜單 } if (hash != '' && hash != oldHash) { if (hash == "#top") { //TODO, Load the index page!!!! return; } $('#contentPanel').html('<div class="wp"><img src="@Url.Content("~/Content/loading.gif")" border="0" /> 載入中...</div>'); oldHash = hash; $.get(hash.substr(1, hash.length - 1), {}, function (data, status) { if (status == "success") { if (data.substr(0, 7) == '"logon"') { window.location = "/Home/Login"; } else { $('#contentPanel').html(data); } //} } else { $('#contentPanel').html('error.. - ' + status); } }, "html"); } }); $(window).trigger('hashchange');
在這樣的架構中,只需要關注Content Area中的部分視圖即可,在該Content Area中還可以使用Ajax + JSON的方式實現更多的功能;
表單的處理
由於採用了上面的AJAX機制,不能再使用以往的表單提交方式,在本架構中,使用下面幾種方式:
1)使用 $.post(url, $('#form').serialize(), callback, "html") 的方式,將傳回值更新到 Content Area中;
2)使用 $.post(url, {'field1','value1'} , callback, "json") 的方式,根據結果,再通過javascript進行頁面跳轉;
D)配套的若干Helper
ajaxMenu,ajaxPager等:由於使用了上面的機制來載入部分視圖,所有的URL都要以 /Home#/Real/Url?para1=value1 的方式來請求,所以寫了一個Helper來完成該功能;分頁也需要做同樣的處理。
E)IoC Container
本例使用了Unity Block作為IoC容器,無他,因為這個比較熟悉;同時將MVC與Unity Container做了整合;
F)表單驗證
由於使用了AJAX架構,unobtrusive擴充的驗證大部分失效,所以直接使用 jquery.validate進行用戶端驗證
G)外掛程式機制
定義IPlugin介面,其中有Initialize方法,在系統啟動時進行初始化,例如初始化Unity Container,MapRoute等等;
外掛程式的使用:直接將外掛程式複製到架構中的外掛程式目錄,並將外掛程式所需要使用的Views檔案複製到架構中的Views目錄中。(暫無更好的解決方案,就這樣搞定。考慮複製到外掛程式目錄,重寫MVC中的視圖引擎的代碼來實現在外掛程式目錄中查詢檢視表)
工作原理:系統啟動時,通過反射載入外掛程式中的Dll,並尋找IPlugin介面,調用其初始化方法,外掛程式在Unity容器中註冊所需要使用的控制器,這樣架構中就可以調用到所需要的控制器以及視圖;
外掛程式格式:外掛程式也採用Asp.net mvc 4 Web APP來寫,最後只使用編譯出的DLL與部分必要的View視圖,其他資源均使用架構中的資源;
三、系統實現
1)資料庫:採用了EntityFramework(Version 5.0) - CodeFirst完成,使用Enable Migrations;
2)資料訪問層:定義倉儲模式,IRepository實現基本的增刪查改功能,
3)資料服務層:根據需要進行定義;
4)Portal:採用了Asp.net MVC 4,Razor視圖引擎,JQuery,JQuery UI, JQuery.Validate, jquery.bbq, Jquery BlockUI 等;
5)為面向內容管理,整合了CkEditor與CkFinder
-------------------
目前系統代碼還比較亂,先發個