1. 程式人生 > >程序員的自我救贖---1.4.3: 核心框架講解(MVC)

程序員的自我救贖---1.4.3: 核心框架講解(MVC)

登錄頁面 就會 技術 virtual mon status pan gpu aac

《前言》

《目錄》

(一) 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)