使用Abp官网的模板生成的基于AbpZero模块的项目,导航菜单的定义代码在Web项目App_Start目录下,文件名为<项目名称>NavigationProvider.cs的代码中,比如,我的Abp项目名称为jiagoushi_cm.MyPlat,Web项目的名称为jiagoushi_cm.MyPlat.Web,导航菜单的代码为MyPlatNavigationProvider.cs,模板生成的代码大致如下:
using Abp.Application.Navigation;
using Abp.Localization;
using jiagoushi_cn.MyPlat.Authorization;
namespace jiagoushi_cn.MyPlat.Web
{
/// <summary>
/// This class defines menus for the application.
/// It uses ABP's menu system.
/// When you add menu items here, they are automatically appear in angular application.
/// See Views/Layout/_TopMenu.cshtml file to know how to render menu.
/// </summary>
public class MyPlatNavigationProvider : NavigationProvider
{
public override void SetNavigation(INavigationProviderContext context)
{
context.Manager.MainMenu
.AddItem(
new MenuItemDefinition(
PageNames.Home,
L("HomePage"),
url: "",
icon: "home",
requiresAuthentication: true,
)
).AddItem(
new MenuItemDefinition(
PageNames.Tenants,
L("Tenants"),
url: "Tenants",
icon: "business",
requiredPermissionName: PermissionNames.Pages_Tenants,
)
).AddItem(
new MenuItemDefinition(
PageNames.Users,
L("Users"),
url: "Users",
icon: "people",
requiredPermissionName: PermissionNames.Pages_Users,
)
);
}
private static ILocalizableString L(string name)
{
return new LocalizableString(name, MyPlatConsts.LocalizationSourceName);
}
}
}
采用硬编码的方式添加菜单的数据。
菜单的初始化代码在WebModel的预处理函数中:
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Abp.Hangfire;
using Abp.Hangfire.Configuration;
using Abp.Zero.Configuration;
using Abp.Modules;
using Abp.Web.Mvc;
using Abp.Web.SignalR;
using jiagoushi_cn.MyPlat.Api;
using Castle.MicroKernel.Registration;
using Hangfire;
using Microsoft.Owin.Security;
using Abp.Collections.Extensions;
using jiagoushi_cn.MyPlat.Navigation;
namespace jiagoushi_cn.MyPlat.Web
{
[DependsOn(
typeof(MyPlatDataModule),
typeof(MyPlatApplicationModule),
typeof(MyPlatWebApiModule),
typeof(AbpWebSignalRModule),
//typeof(AbpHangfireModule), - ENABLE TO USE HANGFIRE INSTEAD OF DEFAULT JOB MANAGER
typeof(AbpWebMvcModule))]
public class MyPlatWebModule : AbpModule
{
public override void PreInitialize()
{
//Enable database based localization
Configuration.Modules.Zero().LanguageManagement.EnableDbLocalization();
//Configure navigation/menu
Configuration.Navigation.Providers.Add<MyPlatNavigationProvider>();
//Configure Hangfire - ENABLE TO USE HANGFIRE INSTEAD OF DEFAULT JOB MANAGER
//Configuration.BackgroundJobs.UseHangfire(configuration =>
//{
// configuration.GlobalConfiguration.UseSqlServerStorage("Default");
//});
}
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
IocManager.IocContainer.Register(
Component
.For<IAuthenticationManager>()
.UsingFactoryMethod(() => HttpContext.Current.GetOwinContext().Authentication)
.LifestyleTransient()
);
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
}
在初始化函数中,将MyPlatNavigationProvider加载到Configuration中。
如果我们希望从数据库或者文件等持久化数据源中读取菜单数据,可以修改MyPlatNavigationProvider 中的代码,需要注意的是:
- 如果从数据库中读取数据,不能使用基于EfRepositoryBase的仓储(原因参见以前的分析文章),可以直接使用DbContext。
- 无法实现动态加载,数据源中的数据改变后,需要重启应用才能刷新菜单数据。