///
/// Configs
/// added by zbw911
///
[XmlRoot("menulist")]
public class MenuList
{
[XmlElement(ElementName = "group", Type = typeof(Group))]
public Group[] groups;
}
///
/// 每个菜单的单元组
///
public class Group
{
[XmlAttribute(AttributeName = "title")]
public string title;
[XmlArray(ElementName = "node")]
[XmlArrayItem(ElementName = "node")]
public Node[] Nodes;
}
///
/// 每个菜单的结点,每个结点下面还有可能会有菜单
///
public class Node
{
[XmlElement(ElementName = "node")]
public Node[] Nodes;
[XmlAttribute("href")]
public string href { get; set; }
[XmlAttribute("target")]
public string target { get; set; }
[XmlAttribute("rel")]
public string rel { get; set; }
[XmlAttribute("name")]
public string name { get; set; }
[XmlAttribute(AttributeName = "title")]
public string title { get; set; }
[XmlAttribute(AttributeName = "url")]
public string url { get; set; }
}
上面定义的菜单的个结构,菜单由多个group组成,每个group 包含多个 node, node 是自包含,这样实现了无限级联菜单,
其实 group 也是可以 用node 来代替的,
但是,之所谓增加一个 group 无非也是为了使层次稍微清晰一点点。
下面是与之相关的一些测试代码,
public class test { public MenuList t(out string all) { string applicationBaseDirectory = null; //try //{ applicationBaseDirectory = AppDomain.CurrentDomain.BaseDirectory; //} //catch (Exception ex) //{ // //LogLog.Warn(declaringType, "Exception getting ApplicationBaseDirectory. ConfigFile property path [" + m_configFile + "] will be treated as an absolute path.", ex); //} //if (applicationBaseDirectory != null) //{ // Just the base dir + the config file string fullPath2ConfigFile = HttpContext.Current.Server.MapPath("~/App_Data/Memu.xml");// Path.Combine(applicationBaseDirectory, ""); //} //else //{ // fullPath2ConfigFile = m_configFile; //} var mySerializer = new XmlSerializer(typeof(MenuList)); // To read the file, create a FileStream. var myFileStream = File.ReadAllBytes(fullPath2ConfigFile); // Call the Deserialize method and cast to the object type. var _Configuration = (MenuList)mySerializer.Deserialize(new MemoryStream(myFileStream)); var xxx = new MenuList { groups = new[] { new Group { Nodes = new []{ new Node { title = "tit", url = "u", Nodes = new[] { new Node { href = "href", name = "name" }, new Node { href = "href", name = "name" } } } , new Node { href = "href", name = "name" }, new Node { href = "href", name = "name" } }, title = "groptitle", }, new Group { Nodes = new []{ new Node { title = "tit", url = "u" ,Nodes = new []{ new Node { href = "", name = "name", rel = "aaa" , Nodes = new [] { new Node { href = "href", Nodes = new Node[] { new Node { href ="aaaaa" } } } } } } } }, title = "groptitle" }, } }; var stream = new MemoryStream(); //stream.Seek(0, SeekOrigin.Begin); mySerializer.Serialize(stream, xxx); //StreamReader sr = new StreamReader(stream); //string all = sr.ReadToEnd(); //stream.ToArray(); all = System.Text.Encoding.Default.GetString(stream.ToArray()); return _Configuration; } }
这样就可以从 一个 xml文件将之序列化一个 对象,然后再通过这个对象进行菜单的生成操作,
下面是大致的XML文件格式,
-
-
-
-
-
-
-
-
-
最后说一句,实际上,菜单的生成不必要如此复杂,实际上我为的是将权限与菜单的对应放在一起,不去程序中写
if( 有什么权限)
{显示某个菜单}
这样的形式,才使用这样的方案。
实际上,生成菜单与权限对应还有其它方案,如 在 数据库中, 但这个实际上与这个方案类似。
不选择数据库,是因为,菜单的变化真不会有想像中如此那样多的变化,何改再去做一些CURD的方法呢,用最简单的方法来解决这个问题吧。