使用mvc的一个简单的web布局

因个人爱好,最近接触ASP.NET mvc开发模式。自己做了一个简单的mvc的布局框架。仅供参考!

下图效果页面:


一开始我想到的是iframe来布局,但是又想了一下既然mvc提供了分部视图就还是用分部视图来做吧。

所以,拆分成模块来看就是以下的内容:


这部分知识在WebForm里面的概念叫母版页。先说一下各个模块的工作和实现:

Top分部:一直为页面的一部分,与其他视图无关。很简单,不介绍。

Meau分部:菜单部分,主要是几个大的分区,每一个菜单下面都有独立的几个子模块,子模块的功能构成体现在Left视图中。

CurrentUser分部:显示当前登录用户的部分,另外提供了一个注销的功能。

Left分部:大模块下的子功能部分,上层业务在Meau视图中,下层业务在Right视图中。

Footer分部:提供页脚显示内容。

从架构来看,我个人喜欢把数据访问层和封装的业务逻辑层单独抽出来。所以我的文件结构是这样的:


设计到逻辑业务的代码我都封装在ViewModel中,先看一下里面有些什么。


BaseViewModel对应的是几个必要视图数据的集合的封装(母版页的数据),所以其他的几个也很明显是各个视图(页面)数据的逻辑层。当然,你会发现有的视图没有逻辑层,是因为在这里没有涉及到逻辑业务,当然,一个更合理的做法是,不管有没有逻辑业务,都应有逻辑层的ViewModel,这里暂不讨论原因。(当然,你可能已经发现了我的Right视图是没有ViewModel的,其实Right视图的逻辑部分在PersonViewModel中,因为Right视图随时会改变,所以我并没有再封装一层,这是我的问题,一开始没有考虑周到,但是并不影响,有兴趣的朋友可以下来自己再封装一层。)

下面看一下怎么给Action传入这些值的。

// GET: Home
        [Authorize]
        [AllFilters]
        public ActionResult Index()
        {
            ViewModel.ViewModel.PersonListViewModel personList = new ViewModel.ViewModel.PersonListViewModel();
            PersonBusinessLayer businessLayer = new PersonBusinessLayer();
            List<Person> persons = businessLayer.GetPerson();
            List<PersonViewModel> listViewModel = new List<PersonViewModel>();
            foreach(var per in persons)
            {
                PersonViewModel personViewModel = new PersonViewModel();
                personViewModel.Name = per.Name;
                personViewModel.Age = per.Age;
                personViewModel.Salary = per.Salary.ToString("C");
                //把工资在3000上下的区别开来
                if (per.Salary > 3000)
                {
                    personViewModel.SalaryColor = "green";
                }
                else
                {
                    personViewModel.SalaryColor = "black";
                }
                listViewModel.Add(personViewModel);
            }
            personList.Persons = listViewModel;
            
            return View("Home", personList);
        }

以上是HomeController的Index方法,也可以说是这个方法调用的页面(可以这样认为,但是实际上是有偏差的)。上面的代码实际上并没有明确告诉前端,哪个分部视图应该给哪个值,其实这部分我把它放在过滤器里面了。关于过滤器及其我也不多介绍,可以上谷歌搜索一下。为什么要用过滤器,主要是考虑到权限的问题,如果一个没有登录的游客在访问我的主页并且还拿到了数据,这显然是不合常理的,我这里的过滤器的作用就是在return View();之前进行身份认证并给必须的分部视图给定初始值。

看一下这两个过滤器的代码:

 public class AuthenticationController : Controller
    {
        // GET: Autnentication
        public ActionResult Login()
        {
            return View();
        }

        [HttpPost]
        [AllowAnonymous]
        public ActionResult WhenLogin(UserDetails user)
        {
            if (ModelState.IsValid)
            {
                PersonBusinessLayer bal = new PersonBusinessLayer();
                UserStatus status = bal.GetUserValidity(user);
                bool IsAdmin = false;
                if (status == UserStatus.AuthenticatedAdmin)
                {
                    IsAdmin = true;
                }
                else if (status == UserStatus.AuthentucatedUser)
                {
                    IsAdmin = false;
                }
                else
                {
                    ModelState.AddModelError("CredentialError", "无效的用户名和密码");
                    return View("Login");
                }
                FormsAuthentication.SetAuthCookie(user.UserName, false);
                Session["IsAdmin"] = IsAdmin;
                return RedirectToAction("Index", "Home");
            }
            else
            {
                return View("Login");
            }
        }

        public ActionResult Logout()
        {
            FormsAuthentication.SignOut();
            return RedirectToAction("Login");
        }
    }
public class PersonBusinessLayer
    {
        public List<Person> GetPerson()
        {
            ErpDAL erp = new ErpDAL();
            return erp.Persons.ToList();
        }
        public Person Saveperson(Person p)
        {
            ErpDAL erp = new ErpDAL();
            erp.Persons.Add(p);
            erp.SaveChanges();
            return p;
        }
        public bool IsValidUser(UserDetails u)
        {
            if (u.UserName == "Admin" && u.PassWord == "Admin")
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public UserStatus GetUserValidity(UserDetails u)
        {
            if (u.UserName == "Admin" && u.PassWord == "Admin")
            {
                return UserStatus.AuthenticatedAdmin;
            }
            else if (u.UserName == "Test" && u.PassWord == "Test")
            {
                return UserStatus.AuthentucatedUser;
            }
            else
            {
                return UserStatus.NonAuthenticatedUser;
            }
        }
    }

可以看到在抛出post方法的时候,只要你引用了这个过滤器就会自动的进行WhenLogin的认证。如果当前没有身份认证就会转到Login页面,如果有身份,但是权限不够高的话.......(此处可以添加一些内容,不如给不同权限的用户开放不同的动能等等都是可以实现的,由于我仅仅只是区分了不同用户并没有对其做不一样的操作,所以这里暂不讨论,有兴趣的下来可以参考谷歌)。

public class AllFilters : ActionFilterAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            ViewResult v = filterContext.Result as ViewResult;
            if (v != null)
            {
                BaseViewModel bvm = v.Model as BaseViewModel;
                if (bvm != null)
                {
                    //顶部视图
                    TopViewModel top = new TopViewModel();
                    top.SystemName = "某某某公司员工考勤";
                    bvm.TopData = top;
                    //底部视图
                    FooterViewModel footer = new FooterViewModel();
                    footer.CompanyName = "某某某信息技术有限公司";
                    footer.CopyRight = "1573.cn. All Rights Reserved";
                    footer.Year = DateTime.Now.Year.ToString();
                    bvm.FooterData = footer;
                    //左部视图
                    LeftViewModel left = new LeftViewModel();
                    List<String> list_left = new List<string>();
                    if (v.ViewData.ModelState.Values.Count > 0)
                    {
                        #region ***************** /*/* 设置左边视图中显示的按钮 *\*\ *****************
                        switch (v.ViewData.ModelState.Values.First().Value.AttemptedValue)
                        {
                            case "流程申请":
                                list_left.Add("出差申请");
                                list_left.Add("聚餐申请");
                                list_left.Add("报销申请");
                                break;
                            case "请销假管理":
                                list_left.Add("请假附件");
                                list_left.Add("销假附件");
                                list_left.Add("假条补办");
                                break;
                            default:
                                list_left.Add("上班考勤");
                                list_left.Add("加班考勤");
                                list_left.Add("工作日报");
                                list_left.Add("每日任务栏");
                                break;
                        }
                        #endregion
                    }
                    else
                    {
                        #region ***************** /*/* 初始化左边视图中显示的按钮 *\*\ *****************
                        list_left.Add("上班考勤");
                        list_left.Add("加班考勤");
                        list_left.Add("工作日报");
                        list_left.Add("每日任务栏");
                        #endregion
                    }
                    left.FunctionNames = list_left;
                    bvm.LeftData = left;
                    //当前用户视图
                    CurrentUserViewModel currentuser = new CurrentUserViewModel();
                    currentuser.CurrentUser = HttpContext.Current.User.Identity.Name;
                    bvm.CurrentUserData = currentuser;
                }
            }
        }
    }

当然,这个就是在给必要的分部视图设置初始值啊什么的。

此外,在tabs(选项卡)插件方面,很有趣的事情是踌躇了千遍万遍,本来自己做了一个插件,但是后面的实际的效果就不提了,你懂的。索性后面就引用了jQuery的插件。效率和美观都比我的好了不知道多少倍(毕竟异步无刷新是要比局部刷新人性化的多)。

好了,就说这么多吧,其实我也不知道我在说些什么东西,但是还有很多东西因为篇幅有限我就不一一讨论了,如果有兴趣要源文件的可以私聊我。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值