本文实例讲述了C#使用XML序列化操作菜单的方法。分享给大家供大家参考。具体分析如下:
之前的一篇文章《C#递归读取XML菜单数据的方法》没使用XML序列化来操作菜单,而且发现那还有一个问题,就是在XML菜单的某个菜单节点前加上一些注释代码的就不能读取,现在使用XML序列化后可以很方便的读取,故在此写一写。
XML菜单的节点代码如下:
<?xml version="1.0" encoding="utf-8"?> <ZCSoft.Net xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Applications> <Application ID ="OA" Text="OA管理系统"> <Modules> <Module ID="OA_System" Text="系统管理"> <Menus> <Menu ID="OA_System_UserManager" Text="人员管理" URL="System/UserManager/UserManagerList.aspx"> </Menu> <Menu ID="OA_System_RoleManager" Text="角色管理" URL="System/RoleManager/RoleManagerList.aspx"></Menu> <Menu ID="OA_System_LoginLog" Text="登录日志" URL="System/Log/LoginLogList.aspx"></Menu> <Menu ID="OA_System_OperateLog" Text="操作日志" URL="System/Log/OperateLogList.aspx"></Menu> </Menus> </Module> <Module ID="OA_TargetManage" Text="目标管理"> <Menus> <Menu ID="OA_TargetManage_TargetSetup" Text="目标设定" URL="OA/TargetManage/TargetSetupList.aspx"> </Menu> </Menus> </Module> </Modules> </Application> <Applications> </ZCSoft.Net>
这里面有一个节点:Applications(应用程序节点),里面可以放多个Application,而每个Application节点里面只包含一个Modules(模块节点),Modules有多个Module,每个Module又只有一个Menus(菜单节点),而Menus里有多个Menu。而每个节点都有两个公共的属性:ID和Text。
故这里写一个公共的属性类:BaseAttribute,前面记得加上序列化标识Serializable,代码如下:
[Serializable] public class BaseAttribute { [XmlAttribute(AttributeName = "ID")] public string ID { get; set; }[XmlAttribute(AttributeName = "Text")] public string Text { get; set; } }
每个节点都有两个类,一个是列表,一个是实体,实体类需继承公共的类,如下:
[Serializable] public class ApplicationList { public ApplicationList() { this.Applications = new List<Application>(); } [XmlElement(ElementName = "Application")] public List<Application> Applications { get; set; } }[Serializable] public class Application : BaseAttribute { public Application() { this.Modules = new ModuleList(); } [XmlElement(ElementName = "Modules")] public ModuleList Modules { get; set; }
[XmlAttribute(AttributeName = "URL")] public string URL { get; set; } }
[Serializable] public class ModuleList { public ModuleList() { this.modules = new List<Module>(); } [XmlElement(ElementName = "Module")] public List<Module> modules { get; set; } }
[Serializable] public class Module : BaseAttribute { public Module() { this.Display = "True"; this.Menus = new MenuList(); } [XmlElement(ElementName = "Menus")] public MenuList Menus { get; set; }
[XmlAttribute(AttributeName = "Display")] public string Display { get; set; }
[XmlAttribute(AttributeName = "URL")] public string URL { get; set; } }
[Serializable] public class MenuList { public MenuList() { this.Menus = new List<Menu>(); } [XmlElement(ElementName = "Menu")] public List<Menu> Menus { get; set; } }
/// <summary> /// 菜单类 /// </summary> [Serializable] public class Menu : BaseAttribute { public Menu() { this.Securityable = false; this.Popup = false; }
[XmlAttribute(AttributeName = "Popup")] public bool Popup { get; set; }
[XmlAttribute(AttributeName = "Securityable")] public bool Securityable { get; set; }
[XmlAttribute(AttributeName = "URL")] public string URL { get; set; } }
下面几个类是用于操作XML的,代码如下:
[Serializable,XmlRoot("ZCSoft.Net")] public class ZCSoftPlateForm { public ZCSoftPlateForm() { this.Applications = new ApplicationList(); } [XmlElement(ElementName = "Applications")] public ApplicationList Applications { get; set; } }/// <summary> /// 操作XML类 /// </summary> public class LoadFoundationXml { private static ZCSoftPlateForm _FoundationObject; static LoadFoundationXml() { if (_FoundationObject == null) { string path = AppDomain.CurrentDomain.BaseDirectory + "Foundation.xml"; if (File.Exists(path)) { _FoundationObject = Serialization.ToObject<ZCSoftPlateForm>(path); } } } private LoadFoundationXml() { }
public static ZCSoftPlateForm PlateFormObject { get { return _FoundationObject; } } }
最后就是一个序列化操作类,如下:
/// <summary> /// 序列化XML类 /// </summary> public class Serialization { public static T ToObject<T>(string xmlFile) { FileStream stream = null; T local = Activator.CreateInstance<T>(); try { XmlSerializer serializer = new XmlSerializer(typeof(T)); stream = new FileStream(xmlFile, FileMode.Open, FileAccess.Read, FileShare.Read); local = (T)serializer.Deserialize(stream); stream.Close(); } catch { while (stream != null) { stream.Close(); break; } throw new Exception("Xml deserialization failed!"); } return local; } }
在后台可以这样调用,这里没用递归,如下
private static ZCSoftPlateForm plateForm;List<MenuTreeData> list = new List<MenuTreeData>();
plateForm = LoadFoundationXml.PlateFormObject;
//使用操作XML类来读取XML var appList = plateForm.Applications.Applications; foreach (var application in appList) { var appData = new MenuTreeData(); appData.ItemId = 0; appData.TemplateId = 0; appData.ItemCode = application.ID; appData.ItemName = application.Text; appData.ItemType = "Folder"; appData.ItemOrder = 0; appData.Visible = true; appData.ItemUrl = null; appData.ParentItem = null; appData.ApplicationCode = application.ID; appData.ApplicationName = application.Text; appData.ModuleCode = null; appData.ModuleName = null; appData.Securityable = false; appData.Popup = false; list.Add(appData);
if (application.Modules!=null) { foreach (var module in application.Modules.modules) { bool display = module.Display.ToLower() == "true" ? true : false; string parentItem = null;//上一节点ID var modData = new MenuTreeData(); modData.ItemId = 0; modData.TemplateId = 0; modData.ItemCode = module.ID; modData.ItemName = module.Text; modData.ItemType = "Folder"; modData.ItemOrder = 0; modData.Visible = display; modData.ItemUrl = null; if (display) { parentItem = application.ID; }
modData.ParentItem = parentItem; modData.ApplicationCode = application.ID; modData.ApplicationName = application.Text; modData.ModuleCode = module.ID; modData.ModuleName = module.Text; modData.Securityable = false; modData.Popup = false; list.Add(modData);
if (module.Menus!=null) { foreach (var menu in module.Menus.Menus) { var mData = new MenuTreeData(); mData.ItemId = 0; mData.TemplateId = 0; mData.ItemCode = menu.ID; mData.ItemName = menu.Text; mData.ItemType = "Menu"; mData.ItemOrder = 0; mData.Visible = true; mData.ItemUrl = menu.URL; if (display) { /* * 如果该菜单的所属模块中的Display属性设置为可见true * (注意:没有设置则默认为可见),则菜单的上级为Module的ID */ mData.ParentItem = module.ID; } else { /*如果该菜单的所属模块中的Display属性设置为不可见false, * 则菜单的上级为Application的ID */ mData.ParentItem = application.ID; } mData.ApplicationCode = application.ID; mData.ApplicationName = application.Text; mData.ModuleCode = module.ID; mData.ModuleName = module.Text; mData.Securityable = false; mData.Popup = false; list.Add(mData); } } } } }
使用到的菜单实体类:
/// <summary> /// 系统菜单 /// </summary> public class MenuTreeData { public int ItemId { get; set; }public int TemplateId { get; set; }
public string ItemCode { get; set; }
public string ItemName { get; set; }
public string ItemType { get; set; }
public int ItemOrder { get; set; }
public bool Visible { get; set; }
public string ItemUrl { get; set; }
public string ParentItem { get; set; }
public string ApplicationCode { get; set; }
public string ApplicationName { get; set; }
public string ModuleCode { get; set; }
public string ModuleName { get; set; }
public bool Securityable { get; set; }
public bool Popup { get; set; } }
希望本文所述对大家的C#程序设计有所帮助。