zoukankan      html  css  js  c++  java
  • MVC项目小结:动态菜单

    MVC项目小结:动态菜单

         是近项目中应用到了动态菜单,觉的做的还是不错的,这里总结出来,也许有一些做的不对的地方,仁者见仁吧。
         
         菜单需求:

         1:支持多语言。

         2:只支持两级菜单,不需要考虑无限级菜单这种需求。

         3:二级菜单与一级菜单可以动态调整。

             比如我们有一个给用户授权的功能,网站共有两个一级菜单:系统管理员以及二级管理员,之前用户授权的二级菜单出现在系统管理员下来,但后来有人认为应该出现在级 别低点的二级管理员菜单下,这种情况要非常容易的进行调整,这里的容易调整是指不修改任何程序任何配置文件的基础上完成,完成在网页上就能完成。

        4: 菜单的显示需要和登录用户权限结合

               比如系统管理员总共有六个二级菜单,每个二次菜单对应一个功能,只要用户的授权中有其中一项,当用户登录系统后就会出现系统管理员的一级菜单,点击一级菜单,能看到一个自己被授权的二级菜单。
           
         我们采用的是比较传统的用户授权模式,这种方式并不一定是最好的,但适用于我们自己的项目。
         1:User,用户信息。
         2:Role,角色信息。
         3:Function,功能信息,比如数据字典表维护就是一个Function, ControllerName是指mvc程序中Controller路由信息,即去掉Controller后缀的部分,比如HomeController,数据库中就存Home。Name,是一个程序员能认认识的名称,不用于菜单显示,因为我们的菜单需要多语言。
         4:Action,子功能信息,比如数据字典表的查询就是一个Action,删除也属于一个Action。ActionName是指mvc程序中的Action名称,比如HomeController下面有一个类型为ViewResult的Index方法,此时ActionName就存这个Index。Name,也是一个供 程序员参考的名称。
         5:RoleAction,角色与子功能的关系,所有权到每一个子功能Action而不是更高一级的Function。
         6:UserRole,用户与角色的关系。
         
         如何实现二级菜单?
         实现的方式有很多种,但我们选择的是MvcSiteMap,它允许我们对于展示的样式进行自定义的控制,而且支持多语言以及动态菜单。
         
         如何实现菜单多语言?
         MvcSiteMap自身就提供了多语言机制,比如我们可以在配置文件中指定如下菜单,通过资源文件的方式来实现。

    <mvcSiteMapNode title="$resources:SiteMapResources,Page" controller="PageName" action="Index" roles="Regional Admin"/>


         但这是静态菜单(要想修改菜单就需要修改这个配置文件),不符合要求,不能写在配置文件中,因为功能与角色的关系是动态的而非静态固定的,我们需要采用MvcSiteMap提供的动态菜单,但解决的思想还是采用资源文件。     


          在Function以及Action表中,增加了ResourceKey字段,MvcSiteMap读取到Function信息时,显示的名称根据ResourceKey从指定的资源文件中获取,而不是取数据库中的Name字段,从而实现菜单的多语言。


          修改后的sitemap配置文件,配置文件没有具体指明菜单信息,而只是指定了两个动态菜单配置节。

    <mvcSiteMapNode title="LevelOne" dynamicNodeProvider="My.Web.Utility.LevelOneDynamicNodeProvider, My.Web">
         <mvcSiteMapNode title="LevelTwo" dynamicNodeProvider="My.Web.Utility.LevelTwoDynamicNodeProvider, My.Web">
         </mvcSiteMapNode>
       </mvcSiteMapNode>


        需要分别完成上图中的两个菜单Provider,这里就不贴全部的了,MvcSiteMap源码中包含了示例,菜单的Provider变成:

    DynamicNode node = new DynamicNode();
                    var resouceObject = HttpContext.GetGlobalResourceObject("ResourcesMap", menuGroup[j].ResourceKey);
                    if (null == resouceObject) continue;
                    node.Title = resouceObject.ToString();
                    node.Key = menuGroup[j].ResourceKey+"_"+HttpContext.Current.User.Identity.Name;
                    result.Add(node);


         如何实现二级菜单与一级菜单动态调整?
         
         1:定义二级菜单:
             我们提到的Function,它对应的是一个大的功能,比如一个表的增删改查,它有四个功能,但都属于某某表维护的功能,我这里认为一个Function就是一个二级菜单。
         2:定义一级菜单?
             一级菜单是一大堆二级菜单的汇聚,可以按功能类别来分,比如可以将所有的报表页面放在一个一级菜单下面,也可以按其它标准。这里我定义了一个MenuGroup的表,任何Function都可以属于一个MenuGroup,也可以不属于任何一个MenuGrop,因为有些功能,是不能直接放在菜单上的,它往往需要有前置条件才能导航到这些页面。既然Function和MenuGroup之间的关系建立起来了,那么一级二级菜单的关系也就解决了。

               例如一个系统包含100个功能,A地区的客户需要用到其中的50个功能,B地区的客户需要用到其中的80个功能,通过上面的两级菜单定义,可以方便的为不同地区的客户选择对应的功能,也可以自由的组织一级菜单的分组。
         
          下面是数据库表关系图:
                

                    
         
         
         
         
        

     
     
    分类: ASP.NET MVC
    标签: MVC
  • 相关阅读:
    进程与线程
    the art of seo(chapter seven)
    the art of seo(chapter six)
    the art of seo(chapter five)
    the art of seo(chapter four)
    the art of seo(chapter three)
    the art of seo(chapter two)
    the art of seo(chapter one)
    Sentinel Cluster流程分析
    Sentinel Core流程分析
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2860148.html
Copyright © 2011-2022 走看看