在Asp.net core使用配置Json创建动态目录树

一、前言

  使用动态目录树可以使左边栏中的目录更加灵活,本文介绍如何将目录保存在json配置文件中,再读取出来经过处理后生成目录树。

二、数据结构

  1. TreeMenuNode类名

  将TreeMenuNode类设置成与json格式相对应,注意Children应为List类型。目录的内容包括MenuName,Action,Controller,Icon

    public class TreeMenuNode2
    {
        public int MenuNumber { get; set; }
        public string MenuName { get; set; }
        public string ActionName { get; set; }
        public string ControllerName { get; set; }
        public string Icon { get; set; }
        public List<TreeMenuNode2> Children { get; set; }
    }

  2. Json格式

  作为父级目录的名称,ActionName及ControllerName设为空,方便后期处理。如无Children,需将Children设为空数据

{
  "treemenu3": {
    "MenuNumber": 0,
    "MenuName": "左侧目录",
    "ActionName": "",
    "ControllerName": "",
    "Icon": "fa fa-link",
    "Children": [
      {
        "MenuNumber": 1,
        "MenuName": "设备信息",
        "ActionName": "",
        "ControllerName": "",
        "Icon": "fa fa-link",
        "Children": [
          {
            "MenuNumber": 1000,
            "MenuName": "附属设备",
            "ActionName": "",
            "ControllerName": "",
            "Icon": "fa fa-link",
            "Children": [
              {
                "MenuNumber": 1010,
                "MenuName": "新建附属设备",
                "ActionName": "Create",
                "ControllerName": "Accessory",
                "Icon": "fa fa-link",
                "Children": []
              },
              {
                "MenuNumber": 1020,
                "MenuName": "附属设备列表",
                "ActionName": "Index",
                "ControllerName": "Accessory",
                "Icon": "fa fa-link",
                "Children": []
              }
            ]
          }
        ]
      },
      {
        "MenuNumber": 2,
        "MenuName": "事件管理",
        "ActionName": "",
        "ControllerName": "",
        "Icon": "fa fa-link",
        "Children": [
          {
            "MenuNumber": 2000,
            "MenuName": "设备维护",
            "ActionName": "",
            "ControllerName": "",
            "Icon": "fa fa-link",
            "Children": [
              {
                "MenuNumber": 2010,
                "MenuName": "新建维护信息",
                "ActionName": "Create",
                "ControllerName": "DeviceRepairs",
                "Icon": "fa fa-link",
                "Children": []
              },
              {
                "MenuNumber": 2020,
                "MenuName": "维护记录列表",
                "ActionName": "Index",
                "ControllerName": "DeviceRepairs",
                "Icon": "fa fa-link",
                "Children": []
              }
            ]
          },
          {
            "MenuNumber": 2100,
            "MenuName": "保养维护",
            "ActionName": "",
            "ControllerName": "",
            "Icon": "fa fa-link",
            "Children": [
              {
                "MenuNumber": 2010,
                "MenuName": "新建保养信息",
                "ActionName": "Create",
                "ControllerName": "Devices",
                "Icon": "fa fa-link",
                "Children": []
              },
              {
                "MenuNumber": 2020,
                "MenuName": "保养记录列表",
                "ActionName": "Index",
                "ControllerName": "DeviceRepairs",
                "Icon": "fa fa-link",
                "Children": []
              }
            ]
          }
        ]
      }
    ]
  } 
}

 

三、配置Configuration

关于如何使用类映射配置文件的方法,请参照:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration#custom-config-providers

需安装的Nuget包

Microsoft.Extensions.Configuration
Microsoft.Extensions.Configuration.Json
Microsoft.Extensions.Options.ConfigurationExtensions

1.treemenu.json添加到配置

将treemenu.json保存添加到配置文件中,reloadOnChange表式在Json内容发生变化时,可使用IOptionsSnapshot。

static void Main(string[] args)
{

  var builder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("treemenu.json");
  Configuration = builder.Build();

}

在startup.cs中的配置:

 public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("treemenu.json", optional:false, reloadOnChange: true)              
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }

2.映射Json

 var treeMenu3 = Configuration.GetSection("treemenu3").Get<TreeMenuNode2>();

2.1在Startup.cs

 public void ConfigureServices(IServiceCollection services)
        {
            // Adds services required for using options.
            services.AddOptions();

            // Register the IConfiguration instance which MyOptions binds against.
            services.Configure<TreeMenuNode2>(Configuration.GetSection("treemenu"));
         
            // Add framework services.
            services.AddMvc();
        }

 3. 在Controller使用

    public class HomeController : Controller
    {
        private readonly TreeMenuNode2 _options;       
        public HomeController(IOptionsSnapshot<TreeMenuNode2> optionsAccessor)
        {
            _options = optionsAccessor.Value;           
        }
}

四、重组格式,生成目录树

在后台生成<ul></ul>格式的目录树,此处是在控制台生成相应的格式,可将输出格式复制到网页端进行测试。此处只演示了

 var treeMenu2 = Configuration.GetSection("treemenu3").Get<TreeMenuNode2>();
            Console.WriteLine(" <ul class="sidebar-menu">");
            PrintTreeMenu2(treeMenu2.Children.Find(a => a.MenuNumber == 2));
            Console.WriteLine("</ul>");
 private static void PrintTreeMenu2(TreeMenuNode2 treeMenu)
        {
            if (treeMenu != null)
            {

                if (!String.IsNullOrWhiteSpace(treeMenu.ActionName) && !String.IsNullOrWhiteSpace(treeMenu.ControllerName))
                    Console.WriteLine($"<li><a asp-action="{treeMenu.ActionName}" asp-controller="{treeMenu.ControllerName}"><i class="{treeMenu.Icon}"></i><span>{treeMenu.MenuName}</span></a></li>");

                if (treeMenu.Children != null)
                {
                    Console.WriteLine("<li class="treeview">");
                    if (String.IsNullOrWhiteSpace(treeMenu.ActionName) || String.IsNullOrWhiteSpace(treeMenu.ControllerName))
                    {
                        Console.WriteLine($"<a href="#"><i class="{treeMenu.Icon}"></i> <span>{treeMenu.MenuName}</span><span class="pull-right-container"><i class="fa fa-angle-left pull-right"></i></span></a>");
                    }
                    Console.WriteLine("<ul class="treeview-menu">");
                    foreach (var item in treeMenu.Children)
                        PrintTreeMenu2(item);
                    Console.WriteLine("</ul></li>");
                }
            }
        }

五、网页端的结果

六、结束语

  该篇文章未完善,使用Web时,需在控制器的构造函数中传入(IOptions<TreeMenuNode2> optionsAccessor。

  在Web使用时,可组件成一个String,存在于ViewBag.TreeMenu中,再传入到页面端的相应位置。

原文地址:https://www.cnblogs.com/hahaxi/p/6931690.html