鉴于之前写的一篇博文没使用XML序列化来操作菜单,而且发现那还有一个问题,就是在XML菜单的某个菜单节点前加上一些注释代码的就不能读取,现在使用XML序列化后可以很方便的读取,故在此写一写。
XML菜单的节点代码如下: 复制代码 1 <?xml version="1.0" encoding="utf-8"?> 2 <ZCSoft.Net xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 3 <Applications> 4 <Application ID ="OA" Text="OA管理系统"> 5 <Modules> 6 <Module ID="OA_System" Text="系统管理"> 7 <Menus> 8 <Menu ID="OA_System_UserManager" Text="人员管理" URL="System/UserManager/UserManagerList.aspx"> </Menu> 9 <Menu ID="OA_System_RoleManager" Text="角色管理" URL="System/RoleManager/RoleManagerList.aspx"></Menu> 10 <Menu ID="OA_System_LoginLog" Text="登录日志" URL="System/Log/LoginLogList.aspx"></Menu> 11 <Menu ID="OA_System_OperateLog" Text="操作日志" URL="System/Log/OperateLogList.aspx"></Menu> 12 </Menus> 13 </Module> 14 15 <Module ID="OA_TargetManage" Text="目标管理"> 16 <Menus> 17 <Menu ID="OA_TargetManage_TargetSetup" Text="目标设定" URL="OA/TargetManage/TargetSetupList.aspx"> 18 </Menu> 19 </Menus> 20 </Module> 21 </Modules> 22 </Application> 23 <Applications> 24 </ZCSoft.Net> 复制代码 这里面有一个节点:Applications(应用程序节点),里面可以放多个Application,而每个Application节点里面只包含一个Modules(模块节点),Modules有多个Module,每个Module又只有一个Menus(菜单节点),而Menus里有多个Menu。而每个节点都有两个公共的属性:ID和Text。 故这里写一个公共的属性类:BaseAttribute,前面记得加上序列化标识Serializable,代码如下: 复制代码 1 [Serializable] 2 public class BaseAttribute 3 { 4 [XmlAttribute(AttributeName = "ID")] 5 public string ID { get; set; } 6 7 [XmlAttribute(AttributeName = "Text")] 8 public string Text { get; set; } 9 } 复制代码 每个节点都有两个类,一个是列表,一个是实体,实体类需继承公共的类,如下: 复制代码 1 [Serializable] 2 public class ApplicationList 3 { 4 public ApplicationList() 5 { 6 this.Applications = new List<Application>(); 7 } 8 [XmlElement(ElementName = "Application")] 9 public List<Application> Applications { get; set; } 10 } 11 12 [Serializable] 13 public class Application : BaseAttribute 14 { 15 public Application() 16 { 17 this.Modules = new ModuleList(); 18 } 19 [XmlElement(ElementName = "Modules")] 20 public ModuleList Modules { get; set; } 21 22 [XmlAttribute(AttributeName = "URL")] 23 public string URL { get; set; } 24 } 25 26 27 [Serializable] 28 public class ModuleList 29 { 30 public ModuleList() 31 { 32 this.modules = new List<Module>(); 33 } 34 [XmlElement(ElementName = "Module")] 35 public List<Module> modules { get; set; } 36 } 37 38 [Serializable] 39 public class Module : BaseAttribute 40 { 41 public Module() 42 { 43 this.Display = "True"; 44 this.Menus = new MenuList(); 45 } 46 [XmlElement(ElementName = "Menus")] 47 public MenuList Menus { get; set; } 48 49 [XmlAttribute(AttributeName = "Display")] 50 public string Display { get; set; } 51 52 [XmlAttribute(AttributeName = "URL")] 53 public string URL { get; set; } 54 } 55 56 57 [Serializable] 58 public class MenuList 59 { 60 public MenuList() 61 { 62 this.Menus = new List<Menu>(); 63 } 64 [XmlElement(ElementName = "Menu")] 65 public List<Menu> Menus { get; set; } 66 } 67 68 /// <summary> 69 /// 菜单类 70 /// </summary> 71 [Serializable] 72 public class Menu : BaseAttribute 73 { 74 public Menu() 75 { 76 this.Securityable = false; 77 this.Popup = false; 78 } 79 80 [XmlAttribute(AttributeName = "Popup")] 81 public bool Popup { get; set; } 82 83 [XmlAttribute(AttributeName = "Securityable")] 84 public bool Securityable { get; set; } 85 86 [XmlAttribute(AttributeName = "URL")] 87 public string URL { get; set; } 88 } 复制代码 下面几个类是用于操作XML的,代码如下: 复制代码 1 [Serializable,XmlRoot("ZCSoft.Net")] 2 public class ZCSoftPlateForm 3 { 4 public ZCSoftPlateForm() 5 { 6 this.Applications = new ApplicationList(); 7 } 8 [XmlElement(ElementName = "Applications")] 9 public ApplicationList Applications { get; set; } 10 } 11 12 /// <summary> 13 /// 操作XML类 14 /// </summary> 15 public class LoadFoundationXml 16 { 17 private static ZCSoftPlateForm _FoundationObject; 18 static LoadFoundationXml() 19 { 20 if (_FoundationObject == null) 21 { 22 string path = AppDomain.CurrentDomain.BaseDirectory + "Foundation.xml"; 23 if (File.Exists(path)) 24 { 25 _FoundationObject = Serialization.ToObject<ZCSoftPlateForm>(path); 26 } 27 } 28 } 29 private LoadFoundationXml() 30 { 31 } 32 33 public static ZCSoftPlateForm PlateFormObject 34 { 35 get 36 { 37 return _FoundationObject; 38 } 39 } 40 } 复制代码 最后就是一个序列化操作类,如下: 复制代码 1 /// <summary> 2 /// 序列化XML类 3 /// </summary> 4 public class Serialization 5 { 6 public static T ToObject<T>(string xmlFile) 7 { 8 FileStream stream = null; 9 T local = Activator.CreateInstance<T>(); 10 try 11 { 12 XmlSerializer serializer = new XmlSerializer(typeof(T)); 13 stream = new FileStream(xmlFile, FileMode.Open, FileAccess.Read, FileShare.Read); 14 local = (T)serializer.Deserialize(stream); 15 stream.Close(); 16 } 17 catch 18 { 19 while (stream != null) 20 { 21 stream.Close(); 22 break; 23 } 24 throw new Exception("Xml deserialization failed!"); 25 } 26 return local; 27 } 28 } 复制代码 在后台可以这样调用,这里没用递归,如下 复制代码 1 private static ZCSoftPlateForm plateForm; 2 3 List<MenuTreeData> list = new List<MenuTreeData>(); 4 5 plateForm = LoadFoundationXml.PlateFormObject; 6 7 //使用操作XML类来读取XML 8 var appList = plateForm.Applications.Applications; 9 foreach (var application in appList) 10 { 11 var appData = new MenuTreeData(); 12 appData.ItemId = 0; 13 appData.TemplateId = 0; 14 appData.ItemCode = application.ID; 15 appData.ItemName = application.Text; 16 appData.ItemType = "Folder"; 17 appData.ItemOrder = 0; 18 appData.Visible = true; 19 appData.ItemUrl = null; 20 appData.ParentItem = null; 21 appData.ApplicationCode = application.ID; 22 appData.ApplicationName = application.Text; 23 appData.ModuleCode = null; 24 appData.ModuleName = null; 25 appData.Securityable = false; 26 appData.Popup = false; 27 list.Add(appData); 28 29 if (application.Modules!=null) 30 { 31 foreach (var module in application.Modules.modules) 32 { 33 bool display = module.Display.ToLower() == "true" ? true : false; 34 string parentItem = null;//上一节点ID 35 var modData = new MenuTreeData(); 36 modData.ItemId = 0; 37 modData.TemplateId = 0; 38 modData.ItemCode = module.ID; 39 modData.ItemName = module.Text; 40 modData.ItemType = "Folder"; 41 modData.ItemOrder = 0; 42 modData.Visible = display; 43 modData.ItemUrl = null; 44 if (display) 45 { 46 parentItem = application.ID; 47 } 48 49 modData.ParentItem = parentItem; 50 modData.ApplicationCode = application.ID; 51 modData.ApplicationName = application.Text; 52 modData.ModuleCode = module.ID; 53 modData.ModuleName = module.Text; 54 modData.Securityable = false; 55 modData.Popup = false; 56 list.Add(modData); 57 58 if (module.Menus!=null) 59 { 60 foreach (var menu in module.Menus.Menus) 61 { 62 var mData = new MenuTreeData(); 63 mData.ItemId = 0; 64 mData.TemplateId = 0; 65 mData.ItemCode = menu.ID; 66 mData.ItemName = menu.Text; 67 mData.ItemType = "Menu"; 68 mData.ItemOrder = 0; 69 mData.Visible = true; 70 mData.ItemUrl = menu.URL; 71 72 if (display) 73 { 74 /* 75 * 如果该菜单的所属模块中的Display属性设置为可见true 76 * (注意:没有设置则默认为可见),则菜单的上级为Module的ID 77 */ 78 mData.ParentItem = module.ID; 79 } 80 else 81 { 82 /*如果该菜单的所属模块中的Display属性设置为不可见false, 83 * 则菜单的上级为Application的ID 84 */ 85 mData.ParentItem = application.ID; 86 } 87 mData.ApplicationCode = application.ID; 88 mData.ApplicationName = application.Text; 89 mData.ModuleCode = module.ID; 90 mData.ModuleName = module.Text; 91 mData.Securityable = false; 92 mData.Popup = false; 93 list.Add(mData); 94 } 95 } 96 } 97 } 98 } 复制代码 使用到的菜单实体类: 复制代码 1 /// <summary> 2 /// 系统菜单 3 /// </summary> 4 public class MenuTreeData 5 { 6 public int ItemId { get; set; } 7 8 public int TemplateId { get; set; } 9 10 public string ItemCode { get; set; } 11 12 public string ItemName { get; set; } 13 14 public string ItemType { get; set; } 15 16 public int ItemOrder { get; set; } 17 18 public bool Visible { get; set; } 19 20 public string ItemUrl { get; set; } 21 22 public string ParentItem { get; set; } 23 24 public string ApplicationCode { get; set; } 25 26 public string ApplicationName { get; set; } 27 28 public string ModuleCode { get; set; } 29 30 public string ModuleName { get; set; } 31 32 public bool Securityable { get; set; } 33 34 public bool Popup { get; set; } 35 }