ASP.NET基于XML导航栏的制作

首先说明,本文为照顾刚入门的新手,有些地方可能会稍微说点基础的东西,高手可以直接忽略。
场景:以前做网站的时候,导航栏的链接都是写死在页面中的,这样不易与维护。于是今天写成了用XML配置的导航栏。用到了LINQ to XML。
先介绍一下功能:
储存导航栏信息的XML文件如下:

双击代码全选

1

2

3

4

5

6

7

8

9

<pre class="brush:xml;toolbar:false;"><?xml version="1.0" encoding="utf-8" ?>

<NavigationMenu>

    <MenuItem Title="Shit" Link="/Fuck" OrderId ="2" Enabled="True" />

    <MenuItem Title="Shitter" Link="/Fucker" OrderId ="1" Enabled="True" />

    <MenuItem Title="Shitting" Link="/Fucking" OrderId ="3" Enabled="True" />

    <MenuItem Title="Shitful" Link="/Fucked" OrderId ="4" Enabled="False" />

    <MenuItem Title="Shitfully" Link="/Fuckly" OrderId ="5" Enabled="True" />

</NavigationMenu></pre><p>

</p>

 

Title是显示名称,Link是URL,OrderId表示排序的序位,Enabled为是否启用。这个菜单将最终被解析为一个ul列表:

双击代码全选

1

2

3

4

5

6

<ul>

    <li><a href="/Fucker">Shitter</a></li>

    <li><a href="/Fuck">Shit</a></li>

    <li><a href="/Fucking">Shitting</a></li>

    <li><a href="/Fuckly">Shitfully</a></li>

</ul>

 

然后我们来看看如何实现:
首先需要给菜单创建一个只包含属性的模型类,它的作用是成为对具体某一个菜单项的描述,系统中传递的将是这样一个模型:

双击代码全选

1

2

3

4

5

6

7

public class MenuItem 

    public string Title { get; set; } 

    public string Link { get; set; } 

    public int OrderId { get; set; } 

    public bool Enabled { get; set; } 

}

 

接下来我们要写一个从XML读取所有菜单项,并返回List<MenuItem>泛型集合的方法。在这个例子里,List<MenuItem>里放的是所有5个MenuItem对象。

双击代码全选

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

<pre class="brush:js;toolbar:false;">private List<MenuItem> GetList() 

    var menuPath = Server.MapPath(@"~App_DataMenu.xml"); 

    if (System.IO.File.Exists(menuPath)) 

    

        XElement root = XElement.Load(menuPath); 

        var menuItems = from el in root.Elements("MenuItem"

                        select new MenuItem() 

                        

                            Title = el.Attribute("Title").Value, 

                            Link = el.Attribute("Link").Value, 

                            OrderId = int.Parse(el.Attribute("OrderId").Value), 

                            Enabled = bool.Parse(el.Attribute("Enabled").Value) 

                        }; 

     

        return menuItems.ToList(); 

    

    else

    

        //throw new System.IO.FileNotFoundException(); 

        return null

    

}</pre><p>

</p>

 

这 个方法里我用了LINQ to XML,这是现在.NET操作XML最方便的办法。但LINQ要求你的Framework版本至少是3.5。在这个方法中,我们首先加载了 Menu.xml文件,然后查找所有MenuItem节点,并把这些节点的属性赋值给new出来的MenuItem对象。创建MenuItem对象的时 候,我使用的语法叫做对象初始化器。在return语句中,我写了ToList(),这样可以确保返回值是List<MenuItem>类 型。
值得注意的是,我并没有把判断Enabled和对OrderId排序的逻辑写在这个方法中。因为判断是否启用和排序这两个操作属于业 务逻辑,与数据 读取无关,所以我们分离了关注点,GetList()是趋于稳定的方法,任何业务需求的改变都不需要修改这个方法,因为它的目的很简单——仅仅是读取数 据。一个方法只做一件事情,这是一个原则。
接下来我们还需要写一个业务方法,从GetList()的菜单项中选择所有Enabled的菜单,并按OrderId升序排列:

双击代码全选

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

<pre class="brush:js;toolbar:false;">private void FetchMenuData() 

    var menuList = GetList(); 

    if (null != menuList && menuList.Count > 0) 

    

        // 查找所有已启用的菜单,并按OrderId升序排列 

        var menuView = (from item in menuList 

                        where item.Enabled 

                        orderby item.OrderId ascending 

                        select item).ToList(); 

     

        rptMenu.DataSource = menuView; 

        rptMenu.DataBind(); 

    

}</pre><p>

</p>

 

为了偷懒,我直接把查询结果绑给了Repeater控件。如果按照三层的思想,我不可以把显示这块写在这个业务方法里。本文不探讨分层,有兴趣的朋友可以看看《ASP.NET设计模式》这本书。
接下来,我们只要在页面上放一个Repeater控件,并在Page_Load的时候调用FetchMenuData()就完成了:

双击代码全选

1

2

3

4

5

6

7

8

<pre class="brush:js;toolbar:false;"><ul>

    <asp:Repeater ID="rptMenu" runat="server">

        <ItemTemplate>

            <li><a href="<%#Eval("Link")%>"><%#Eval("Title")%></a></li>

        </ItemTemplate>

    </asp:Repeater>

</ul></pre><p>

</p>

 

双击代码全选

1

2

3

4

5

6

7

protected void Page_Load(object sender, EventArgs e) 

    if (!Page.IsPostBack) 

    

        FetchMenuData(); 

    

}

 

有图有真相:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Grow your business fast with

Suku