abp中的菜单加载机制

在abp中菜单的定义与我们传统写的框架不一样,它是在编写代码的时候配置,而我们一般写的通用权限管理系统中,是后期在后台界面中添加的。这一点有很大不同。abp关于菜单的定义及管理挺复杂的。

与菜单相关的结构类、接口及扩展方法类

  • MenuDefinition:定义应用程序的菜单的结构
  • MenuItemDefinition:定义应用程序的菜单项的结构
  • IHasMenuItemDefinitions: 定义子菜单的接口
  • HasMenuItemDefinitionsExtensions:查询子菜单项的扩展方法类
  • MenuItemDefinitionExtensions:操作菜单项的扩展方法类


  • UserMenu:单个用户的菜单结构
  • UserMenuItem:单个用户的菜单中的菜单项

与菜单相关的操作类

这里分为两类,一类是针对应用系统的菜单:

  • NavigationProvider:提供设置应用系统导航菜单及菜单项的方法SetNavigation
  • INavigationProviderContext:Provider模式的上下文接口
  • NavigationProviderContext:Provider模式的上下文类,设置NavigationManager
  • INavigationManager:导航菜单管理应用服务接口
  • NavigationManager:导航菜单管理应用服务类,包括构造默认主菜单,初始化菜单的所有菜单项方法。



    另一类是针对用户菜单的操作:
  • IUserNavigationManager: 用户菜单管理应用服务接口
  • UserNavigationManager:用户菜单管理应用服务类,提供了获取指定用户的菜单, 根据用户权限填充菜单项方法。

上面的所有类及接口都是在Abp这个项目中定义的。

Web.MVC中的菜单应用

菜单的定义

菜单定义在ContosoAbp.Web.Startup命名空间下的ContosoAbpNavigationProvider类中,这里ContosoAbp为自定义的项目名。ContosoAbpNavigationProvide继承自NavigationProvider抽象类,是实际菜单的定义者。这里利用了Provider模式,微软经常用这种模式。

  1. using Abp.Application.Navigation;
  2. using Abp.Authorization;
  3. using Abp.Localization;
  4. using ContosoAbp.Authorization;
  5. namespace ContosoAbp.Web.Startup
  6. {
  7. /// <summary>
  8. /// This class defines menus for the application.
  9. /// 定义应用程序的菜单
  10. /// </summary>
  11. public class ContosoAbpNavigationProvider : NavigationProvider
  12. {
  13. public override void SetNavigation(INavigationProviderContext context)
  14. {
  15. context.Manager.MainMenu
  16. .AddItem(
  17. new MenuItemDefinition( //首页
  18. PageNames.Home,
  19. L("HomePage"),
  20. url: "",
  21. icon: "fas fa-home",
  22. requiresAuthentication: true,
  23. order:0
  24. )
  25. ).AddItem(
  26. new MenuItemDefinition( //空页面
  27. PageNames.Empty,
  28. L("EmptyPage"),
  29. url: "Home/Empty",
  30. icon: "fas fa-home",
  31. requiresAuthentication: false,
  32. order: 1
  33. )
  34. ).AddItem(
  35. new MenuItemDefinition( //附件
  36. PageNames.Attachment,
  37. L("Attachment"),
  38. url: "Attachment",
  39. icon: "fas fa-home",
  40. requiresAuthentication: false,
  41. order: 2
  42. )
  43. ).AddItem(
  44. new MenuItemDefinition( //租户
  45. PageNames.Tenants,
  46. L("Tenants"),
  47. url: "Tenants",
  48. icon: "fas fa-building",
  49. permissionDependency: new SimplePermissionDependency(PermissionNames.Pages_Tenants),
  50. order: 3
  51. )
  52. ).AddItem(
  53. new MenuItemDefinition( // 用户
  54. PageNames.Users,
  55. L("Users"),
  56. url: "Users",
  57. icon: "fas fa-users",
  58. permissionDependency: new SimplePermissionDependency(PermissionNames.Pages_Users),
  59. order: 4
  60. )
  61. ).AddItem(
  62. new MenuItemDefinition( //角色
  63. PageNames.Roles,
  64. L("Roles"),
  65. url: "Roles",
  66. icon: "fas fa-theater-masks",
  67. permissionDependency: new SimplePermissionDependency(PermissionNames.Pages_Roles),
  68. order: 5
  69. )
  70. )
  71. .AddItem(
  72. new MenuItemDefinition( //关于
  73. PageNames.About,
  74. L("About"),
  75. url: "About",
  76. icon: "fas fa-info-circle",
  77. order: 6
  78. )
  79. ).AddItem( // Menu items below is just for demonstration!
  80. new MenuItemDefinition( //多级菜单
  81. "MultiLevelMenu",
  82. L("MultiLevelMenu"),
  83. icon: "fas fa-circle",
  84. order: 7
  85. ).AddItem(
  86. new MenuItemDefinition(
  87. "AspNetBoilerplate",
  88. new FixedLocalizableString("ASP.NET Boilerplate"),
  89. icon: "far fa-circle"
  90. ).AddItem(
  91. new MenuItemDefinition(
  92. "AspNetBoilerplateHome",
  93. new FixedLocalizableString("Home"),
  94. url: "https://aspnetboilerplate.com?ref=abptmpl",
  95. icon: "far fa-dot-circle"
  96. )
  97. ).AddItem(
  98. new MenuItemDefinition(
  99. "AspNetBoilerplateTemplates",
  100. new FixedLocalizableString("Templates"),
  101. url: "https://aspnetboilerplate.com/Templates?ref=abptmpl",
  102. icon: "far fa-dot-circle"
  103. )
  104. ).AddItem(
  105. new MenuItemDefinition(
  106. "AspNetBoilerplateSamples",
  107. new FixedLocalizableString("Samples"),
  108. url: "https://aspnetboilerplate.com/Samples?ref=abptmpl",
  109. icon: "far fa-dot-circle"
  110. )
  111. ).AddItem(
  112. new MenuItemDefinition(
  113. "AspNetBoilerplateDocuments",
  114. new FixedLocalizableString("Documents"),
  115. url: "https://aspnetboilerplate.com/Pages/Documents?ref=abptmpl",
  116. icon: "far fa-dot-circle"
  117. )
  118. )
  119. ).AddItem(
  120. new MenuItemDefinition(
  121. "AspNetZero",
  122. new FixedLocalizableString("ASP.NET Zero"),
  123. icon: "far fa-circle"
  124. ).AddItem(
  125. new MenuItemDefinition(
  126. "AspNetZeroHome",
  127. new FixedLocalizableString("Home"),
  128. url: "https://aspnetzero.com?ref=abptmpl",
  129. icon: "far fa-dot-circle"
  130. )
  131. ).AddItem(
  132. new MenuItemDefinition(
  133. "AspNetZeroFeatures",
  134. new FixedLocalizableString("Features"),
  135. url: "https://aspnetzero.com/Features?ref=abptmpl",
  136. icon: "far fa-dot-circle"
  137. )
  138. ).AddItem(
  139. new MenuItemDefinition(
  140. "AspNetZeroPricing",
  141. new FixedLocalizableString("Pricing"),
  142. url: "https://aspnetzero.com/Pricing?ref=abptmpl#pricing",
  143. icon: "far fa-dot-circle"
  144. )
  145. ).AddItem(
  146. new MenuItemDefinition(
  147. "AspNetZeroFaq",
  148. new FixedLocalizableString("Faq"),
  149. url: "https://aspnetzero.com/Faq?ref=abptmpl",
  150. icon: "far fa-dot-circle"
  151. )
  152. ).AddItem(
  153. new MenuItemDefinition(
  154. "AspNetZeroDocuments",
  155. new FixedLocalizableString("Documents"),
  156. url: "https://aspnetzero.com/Documents?ref=abptmpl",
  157. icon: "far fa-dot-circle"
  158. )
  159. )
  160. )
  161. );
  162. }
  163. private static ILocalizableString L(string name)
  164. {
  165. return new LocalizableString(name, ContosoAbpConsts.LocalizationSourceName);
  166. }
  167. }
  168. }

菜单的加载

菜单的加载是利用的视图组件,定义了一个SideBarMenuViewComponent的视图组件,在这个SideBarMenuViewComponent类中,利用IUserNavigationManager获取用户的菜单,返回SideBarMenuViewModel给前端,前端遍历输出菜单及子项。

后端视图组件的定义

  1. using System.Threading.Tasks;
  2. using Abp.Application.Navigation;
  3. using Abp.Runtime.Session;
  4. using Microsoft.AspNetCore.Mvc;
  5. namespace ContosoAbp.Web.Views.Shared.Components.SideBarMenu
  6. {
  7. /// <summary>
  8. /// 侧边栏视图组件
  9. /// </summary>
  10. public class SideBarMenuViewComponent : ContosoAbpViewComponent
  11. {
  12. /// <summary>
  13. /// 侧边栏用户导航管理
  14. /// </summary>
  15. private readonly IUserNavigationManager _userNavigationManager;
  16. /// <summary>
  17. /// Session服务
  18. /// </summary>
  19. private readonly IAbpSession _abpSession;
  20. /// <summary>
  21. /// 构造函数
  22. /// </summary>
  23. /// <param name="userNavigationManager"></param>
  24. /// <param name="abpSession"></param>
  25. public SideBarMenuViewComponent(
  26. IUserNavigationManager userNavigationManager,
  27. IAbpSession abpSession)
  28. {
  29. _userNavigationManager = userNavigationManager;
  30. _abpSession = abpSession;
  31. }
  32. public async Task<IViewComponentResult> InvokeAsync()
  33. {
  34. var model = new SideBarMenuViewModel
  35. {
  36. MainMenu = await _userNavigationManager.GetMenuAsync("MainMenu", _abpSession.ToUserIdentifier())
  37. };
  38. return View(model);
  39. }
  40. }
  41. }

前端遍历输出菜单

  1. @using ContosoAbp.Web.Views.Shared.Components.SideBarMenu
  2. @model SideBarMenuViewModel
  3. @{
  4. var orderedMenuItems = Model.MainMenu.Items.Where(x => x.IsVisible).OrderByCustom().ToList();
  5. }
  6. <nav class="mt-2">
  7. <ul class="nav nav-pills nav-sidebar flex-column nav-flat" data-widget="treeview" role="menu" data-accordion="false">
  8. @{
  9. foreach (var item in orderedMenuItems)
  10. {
  11. @await Html.PartialAsync("Components/SideBarMenu/_MenuItem", item)
  12. }
  13. }
  14. </ul>
  15. </nav>

abp web.mvc项目中的菜单加载机制的更多相关文章

  1. 2、手把手教你Extjs5(二)项目中文件的加载过程

    上一节中用sencha工具自动创建了一个项目,并且可以在浏览器中查看.现在我们来看看js类加载过程.如下图所示: 1、首先:浏览器中输入 localhost:1841 ,调用 index.html; ...

  2. django中的懒加载机制

    懒加载在前端中的意义: 懒加载的主要目的就是作为服务器前端的优化,减少请求次数或者延迟请求数. 实现原理: 先加载一部分数据,当触发某个条件时利用异步加载剩余的数据,新得到的数据不会影响原有数据的显示 ...

  3. web项目中配置文件的加载顺序

    当一个项目启动时,首先是web.xml: 这里面的配置: 为什么要在web.xml中配置struts的过滤器? 因为一个web项目运行的时需要加载的,或者默认的部分配置都会在web.xml中配置,中间 ...

  4. 关于web项目中静态资源加载不了的一些解决思路

    问题的产生: <!--springMVC前端控制器加载--> <servlet> <servlet-name>springmvc</servlet-name& ...

  5. extjs5(项目中文件的加载过程)

    现在来看看js类加载过程.如下图所示: 1、首先:浏览器中输入 localhost:1841 ,调用 index.html; <!DOCTYPE HTML> <html> &l ...

  6. Spring项目中Properties不能加载多个的问题

    A模块和B模块都分别拥有自己的Spring XML配置,并分别拥有自己的配置文件: A模块 A模块的Spring配置文件如下: <?xml version="1.0" enc ...

  7. 项目中spring容器加载的问题

    今天做一个项目采用的是传统架构,没有采用分布式,部署时出现了异常,信息是: org.springframework.beans.factory.NoSuchBeanDefinitionExceptio ...

  8. Vue编写的页面部署到springboot网站项目中出现页面加载不全问题

    问题描述: 在用Vue脚手架 编写出一个页面之后, 部署到后台项目中, 因为做的是一个页面 按理来说 怎么都能够在服务器上运行 , 我也在自己的node环境测试 , 在同学的springboot上运行 ...

  9. SpringMVC项目中启动自加载Listener

    package com.kuman.cartoon.listener; import java.util.List; import org.springframework.beans.factory. ...

随机推荐

  1. OpenAL试水

    参考了https://wysaid.org/976.html. 这个博客给了一个EGE+OpenAL的demo和源代码.一开始没注意,博主也没有给EGE相关信息.会找不到EGE相关头文件,建议如果要二 ...

  2. adb命令查看手机应用内存使用情况

    adb shell回车 一.procrank VSS >= RSS >= PSS >= USSVSS - Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)是单个 ...

  3. leetcode-0617 合并二叉树

    题目地址https://leetcode-cn.com/problems/merge-two-binary-trees/ 1.递归解法 递归的话我们首先需要递归的终止条件,对于本题而言,递归的终止条件 ...

  4. MySQL不香吗,为什么还要有noSQL?

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是分布式专题的第14篇文章,我们一起来看看NoSQL数据库. 其实我很早就想写写分布式数据库相关的文章,既是我现在正在学习的,也是我很感 ...

  5. 磁盘性能测试工具之fio

    fio是测试磁盘性能的一个非常好的工具,用来对硬件进行压力测试和验证. 注意事项 CentOS 6.5等较老版本的操作系统用fdisk创建分区时,默认为非4KB对齐选择初始磁柱编号,对性能有较大的影响 ...

  6. 文本序列化【通用】word2sequence,文本序列字典保存

    ''' 文本序列化 ''' class WordSequence(): UNK_TAG = "<UNK>" PAD_TAG = "<PAD>&qu ...

  7. /uesr/local/hadoop/tmp/mapred有锁

    原因:  /usr/local/hadoop/tmp/mapred  有锁 解决:修改改文件的权限 在终端输入: cd /usr/local/hadoop/tmp sudo chmod 777 map ...

  8. Java 基础之详解 Java IO

    Java IO基本概念 Java IO:即Java输入/输出系统,区分Java的输入和输出:把自己当成程序, 当你从外边读数据到自己这里就用输入(InputStream/Reader), 向外边写数据 ...

  9. 2019-2020-1 20199326《Linux内核原理与分析》第九周作业

    进程的切换和系统的一般执行过程 中断 中断在本质上都是软件或者硬件发生了某种情形而通知处理器的行为,处理器进而停止正在运行的指令流(当前进程),对这些通知做出相应反应,即转去执行预定义的中断处理程序( ...

  10. SQLI-LABS学习笔记(二)

    逼话少说,如有错误,烦请指出,谢谢 这两天生病,效率很低 第5关 打开页面 发现跟前几题不同,没有直接返回数据.. 加个单引号 You have an error in your SQL syntax ...