zoukankan      html  css  js  c++  java
  • 程序员的自我救赎---1.4.3: 核心框架讲解(MVC)

    《前言》

    (一) Winner2.0 框架基础分析

    (二)PLSQL报表系统

    (三)SSO单点登录

    (四) 短信中心与消息中心

    (五)钱包系统

    (六)GPU支付中心

    (七)权限系统

    (八)监控系统

    (九)会员中心

    (十) APP版本控制系统

    (十一)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 或者扫描左侧二维码加群。

  • 相关阅读:
    JSP 隐含对象
    Cookie 和 Session
    Servlet(Server Applet) 详解
    AbstractQueuedSynchronizer 详解
    ThreadLocal 详解
    线程的生命周期
    phpfor函数和foreach函数
    php的while函数
    php的switch函数
    php的if函数
  • 原文地址:https://www.cnblogs.com/demon28/p/7977974.html
Copyright © 2011-2022 走看看