程序員的自我救贖---1.4.3: 核心框架講解(MVC)
《前言》
《目錄》
(一) Winner2.0 框架基礎分析
(二) 短信中心
(三)SSO單點登錄
(四)PLSQL報表系統
(五)錢包系統
(六)GPU支付中心
(七)權限系統
(八)監控系統
(九)會員中心
(十)消息中心
(十一)Winner前端框架與RPC接口規範講解
(十二)上層應用案例
(十三)番外篇
《核心框架講解》
核心框架講解的最後一篇文章,也是第一章最後一篇文章。在.net裏,我也不曉得現在有多少團隊用的Asp.net 多少用的.net MVC。
其實Winner框架裏面是有一套基於Asp.net 寫,但是主要宗旨是做兩件事: 1,驗證是否需要登錄,2,驗證是否有權限。
額外再封裝了一些,彈框,帶參數跳轉等等一些工具方法。 主要思路是分成了兩個基類: TopPageBase 和 CommonPageBase,
TopPageBase 只有前端工具給不需要登錄的頁面繼承的。 CommonPageBase繼承了TopPageBase給需要登錄並驗證權限的界面繼承的。
在MVC的時代裏,Winner框架的前端做的事情差不多,只是我們采取的方式不同。 首先我們從基類TopPageBase說起:
TopPageBase 做的事情不多,最主要的是提供Json的序列化,也是因為我們MVC主要以json的格式返回。
using System.Collections;using System.Collections.Generic; using System.Data; using System.Text; using System.Web.Mvc; using Winner.Framework.Core.DataAccess; using Winner.Framework.Core.Interface; using Winner.Framework.MVC.Models.Account; using Winner.Framework.Utils.Model; namespace Winner.Framework.MVC.Controllers {// // 摘要: // 所有控制器基類 public class TopControllerBase : Controller { public TopControllerBase(); // // 摘要: // 當前登陸用戶信息 protected virtual UserInfo SysUser { get; } // // 摘要: // 返回枚舉集合 // // 參數: // all: // 是否支持所有 // // allText: // 如果支持所有則顯示的文本 // // 類型參數: // EnumType: // 枚舉類型 protected virtual JsonResult EnumsResult<EnumType>(bool all = false, string allText = "=全部="); // // 摘要: // 返回枚舉集合Json // // 參數: // allName: // 所有項名稱 // // allValue: // 所有項數值 // // 類型參數: // EnumType: // 枚舉類型 // // ValueType: // 枚舉值類型 protected virtual JsonResult EnumsResult<EnumType, ValueType>(string allName = "", ValueType allValue = default(ValueType)); // // 摘要: // 返回操作失敗對象 // // 參數: // message: // 失敗原因 protected virtual JsonResult FailResult(string message = ""); // // 摘要: // 返回操作失敗對象 // // 參數: // message: // 失敗原因 // // code: // 狀態碼 protected virtual JsonResult FailResult(string message, int code = 0); protected override JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior); // // 摘要: // 返回Json數據格式(兼容IE、火狐等瀏覽器) // // 參數: // data: // 需要返回的數據 // // 類型參數: // T: // 需要返回的數據類型 protected virtual JsonResult JsonResult<T>(T data); // // 摘要: // 返回DAL集合對象查詢的結果(註意:只用於EasyUI) // // 參數: // dacb: // 集合對象 // // vfp: // 值格式處理委托,為空則不處理 // // 類型參數: // T: // DAL集合對象類型 protected virtual JsonResult ListViewResult<T>(T dacb, ValueFormatProvider vfp = null) where T : DataAccessCollectionCore; // // 摘要: // 退出登陸 protected virtual void Logout(); // // 摘要: // 返回操作成功結果 // // 參數: // content: // 需要返回的數據 protected virtual JsonResult SuccessResult(object content = null); // // 摘要: // 返回DAL集合對象查詢的結果 // // 參數: // dacb: // 集合對象 // // vfp: // 值格式處理委托,為空則不處理 // // 類型參數: // T: // DAL集合對象類型 protected virtual JsonResult SuccessResultList<T>(T dacb, ValueFormatProvider vfp = null) where T : DataAccessCollectionCore; // // 參數: // list: // // changePage: // // 類型參數: // T: protected virtual JsonResult SuccessResultList<T>(List<T> list, IChangePage changePage = null); // // 摘要: // 系統代理登陸 // // 參數: // identity: // 用戶賬戶 // // error: // 錯誤信息 // // 類型參數: // T: // 用戶身份類型 protected virtual FuncResult SysProxyLogin<T>(T identity); // // 摘要: // DataTable 對象 轉換為Dictionary字典類型的ArrayList // // 參數: // dt: // DataTable // // vfp: // 值格式處理委托 protected virtual ArrayList ToArrayList(DataTable dt, ValueFormatProvider vfp = null); } }
這裏要 額外說一些:UserInfo 這個對象,當用戶登錄後,我們框架會幫我們裝載一個當前登錄用戶的對象,這樣就方便我們當前用戶數據,
比如 登錄賬戶,用戶姓名等等。
這裏我不群闡述每個JsonResult類型的返回有什麽不同,上面都有註釋,基本都能看明白,我們下面看一下 如何驗證登錄和權限的。
在這之前,我需要引用一篇博客園的文章:http://www.cnblogs.com/lxhbky/p/6344813.html
這篇文章寫的很詳細,Winner也是采用的這種方法,用了特性類來做的驗證:
using System; using System.Collections.Generic; using System.Dynamic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; using Winner.Framework.MVC.GlobalContext; using Winner.Framework.Utils.Model; namespace Winner.Framework.MVC { /// <summary> /// 驗證身份:檢查訪問權限 /// </summary> public class AuthRightAttribute : AuthLoginAttribute { /// <summary> /// 實例化一個新的驗證對象 /// </summary> /// <param name="ignore">是否忽略檢查</param> public AuthRightAttribute(bool ignore = false) : base(ignore) { } /// <summary> /// 權限驗證,繼承登陸驗證 /// </summary> /// <param name="context"></param> protected override bool OnAuthorizationing(AuthorizationContext context) { //1.判斷是否登陸成功 if (!base.OnAuthorizationing(context)) { return false; } //2.忽略權限檢查 if (GlobalConfig.IgnoreCheckRight) { return true; } //3.如果是Ajax請求則不檢查權限 if (base.ContextProvider.IsAjaxRequest && GlobalConfig.IgnoreAjaxRequestCheckRight) { return true; } //4.獲取路徑,如:/區域/控制器/動作/ string url = string.Empty; if (!string.IsNullOrEmpty(ContextProvider.Area)) { url = "/" + ContextProvider.Area; } url += string.Format("/{0}/{1}/", ContextProvider.Controller, ContextProvider.Action); //5.判斷權限 if (!ApplicationContext.HaveRight(ApplicationContext.Current.User.UserId, url)) { //無法跳轉到根目錄下 //context.Result = new RedirectToRouteResult(new RouteValueDictionary(new { Controller = "Home", action = "Right" })); if (base.ContextProvider.IsAjaxRequest) { OutputResult("此功能未授權,請聯系管理員!", -2); } else { //TODO:未測試 指定Default的路由器下的 context.Result = new RedirectToRouteResult("Default", new RouteValueDictionary(new { Controller = "Home", action = "Right" })); } return false; } return true; } } }
控制器之需要打上特性類的標簽就可以驗證是否等於以及權限。
當然這裏我們用到了權限系統 和 SSO 登錄系統,後面的篇章中會單獨寫到這一塊。
Winner.Framework.MVC 最重要的兩件事就是 驗證登錄 和 獲取權限。
這裏額外要講一個Winner解決的開發中常見的問題:調試免登錄模式
其實,這是一個非常簡單的功能,但是非常實用,我們一般開發的時候經常從登錄開始做起,當然有SSO的話就不需要開發登錄。
但是也會遇到,開發其他需要登錄的頁面的時候,每次都要先登錄,我在未接觸Winner的時候就有這樣過,但是當時不覺得是個問題,
用過Winner之後就知道,這能節省很多開發時間。
以前幾乎每次開發中想運行界面看看效果的時候,每次都需要跳到登錄頁面登錄一下,每次都輸入很操蛋。 Winner框架中特別針對這個細節
做了一個配置讀取:
從Web.Config 中讀取,是否檢查權限,是否檢查有登錄,在開發模式下我們就不檢查是否有登錄,這樣開發起來直接運行就行,不用每次都
輸入賬號,密碼。
雖然是個小細節,但是很實用。最後關於MVC這一塊,我們還有一個小功能可以講一下,Winner捕捉了全局一次,發現異常就會自動跳轉到
配置的錯誤頁面,這個我相信很多公司也是這麽做的,雖然沒上面特別的,但是這些細節功能都非常實用。
private void RedirectDefaultError(ExceptionContext filterContext) { string controllerName = (string)filterContext.RouteData.Values["controller"]; string actionName = (string)filterContext.RouteData.Values["action"]; HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName); filterContext.Result = new ViewResult { ViewName = "Error", MasterName = "", ViewData = new ViewDataDictionary<HandleErrorInfo>(model), TempData = filterContext.Controller.TempData }; filterContext.ExceptionHandled = true; filterContext.HttpContext.Response.Clear(); filterContext.HttpContext.Response.StatusCode = 500; filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; }
差不多了,關於Winner.Framework.MVC就介紹到這裏,關於前端在後面的單獨講SSO的篇章中會再次細講這一塊。
有興趣一起探討Winner框架的朋友可以加我們QQ群:261083244 或者掃描左側二維碼加群。
程序員的自我救贖---1.4.3: 核心框架講解(MVC)