打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
在Asp.net MVC模式下实现 网站地图 导航
如今格式各样的导航栏、导航菜单已经成了网站不可缺少的一部分,在WebForms中,一般使用SiteMapPath来实现网站地图导航功能。SiteMapPath服务器控件在MVC模式下中仍然可以工作,但是显然无法很好满足C-V结构的分离,还有就是SiteMapPath默认的XML文件的格式已无法满足MVC中http请求的规则。所以有必要做一个在MVC下使用的,并且符合MVC设计规范的导航栏类,以在MVC中取代之前SiteMapPath的应用。

先看项目结构如图:



1:在Global.asax里添加两个路由规则用来测试
C# code
1
2
3
4
5
6
7
public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            string[] nameSpaces = { "TestMvc3.Controllers" };
            routes.MapRoute("default2""Youku/Moive"new { Controller = "Moive", Action = "Index" }, nameSpaces);
            routes.MapRoute("default""{Controller}/{Action}"new { Controller = "Home", Action = "Index" },nameSpaces);
        }


2:添加一个区域UserCenter并添加路由规则

C# code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System.Web.Mvc;  
   
namespace TestMvc3.Areas.UserCenter  
{  
    public class UserCenterAreaRegistration : AreaRegistration  
    {  
        public override string AreaName  
        {  
            get  
            {  
                return "UserCenter";  
            }  
        }  
   
        public override void RegisterArea(AreaRegistrationContext context)  
        {  
            context.MapRoute(  
                "UserCenter_default",  
                "UserCenter/{controller}/{action}",  
                new { action = "Index" }  
            );  
        }  
    }  
}  


3:构建用于导航的XML文件
我们在站点根目录下建立SiteMap.xml文件来写导航规则。里面的area属性是来应对存在区域的情况的。

XML/HTML code
1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?>
<node title="首页" area="" action="Index" controller="Home">
    <node title="电影" area="" action="Index" controller="Moive">
        <node title="详细页" area="" action="Detail" controller="Moive" />
    </node>
    <node title="用户中心" area="UserCenter" action="Index" controller="Home" />
</node>


4:编写用于导航的类MvcSiteMap类,它将遍历SiteMap.xml文件并生成导航链接。
它的核心就是利用UrlHelper类的Action方法和RouteLink方法来比较当前XML节点的属性所生成的链接和当前请求所生成的链接是否相同。这里不能用拼接controller和action字符串来比较的方式,因为可能存在改写过的路由规则。类的代码如下:

C# code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Xml.Linq;
using System.Web.Routing;
namespace TestMvc3
{
    public class MvcSiteMap
    {
        private static XDocument doc = XDocument.Load(HttpContext.Current.Server.MapPath(@"~/SiteMap.xml"));
        private UrlHelper url = null;
        private string currentURL = "";
        public MvcSiteMap()
        {
            url = new UrlHelper(HttpContext.Current.Request.RequestContext);
            currentURL = url.RouteUrl(HttpContext.Current.Request.RequestContext.RouteData.Values).ToLower();
        }
        public MvcHtmlString Navigator()
        {
            XElement c = FindNode(doc.Root);
            Stack<XElement> temp = GetPath(c);
            return MvcHtmlString.Create(BuildPathString(temp));
        }
        private string GetNodeUrl(XElement c)
        {
            return url.Action(c.Attribute("action").Value, c.Attribute("controller").Value, new { area = c.Attribute("area").Value });
        }
        private string BuildPathString(Stack<XElement> m)
        {
            StringBuilder sb = new StringBuilder();
            TagBuilder tb;
            TagBuilder tc = new TagBuilder("span");
            tc.SetInnerText(">>");
            string sp = tc.ToString();
            int count = m.Count;
            for (int x = 1; x <= count; x++)
            {
                XElement c = m.Pop();
                if (x == count)
                {
                    tb = new TagBuilder("span");
                }
                else
                {
                    tb = new TagBuilder("a");
                    tb.MergeAttribute("href", GetNodeUrl(c));
                }
                tb.SetInnerText(c.Attribute("title").Value);
                sb.Append(tb.ToString());
                sb.Append(sp);
            }
            return sb.ToString();
        }
        private Stack<XElement> GetPath(XElement c)
        {
            Stack<XElement> temp = new Stack<XElement>();
            while (c != null)
            {
                temp.Push(c);
                c = c.Parent;
            }
            return temp;
        }
        private bool IsUrlEqual(XElement c)
        {
            string a = GetNodeUrl(c).ToLower();
            return a == currentURL;
        }
        private XElement RecursiveNode(XElement node)
        {
            foreach (XElement c in node.Elements())
            {
                if (IsUrlEqual(c) == true)
                {
                    return c;
                }
                else
                {
                    XElement x = RecursiveNode(c);
                    if (x != null)
                    return x; }
                }
            }
            return null;
        }
        private XElement FindNode(XElement node)
        {
            if (IsUrlEqual(node) == true)
            {
                return node;
            }
            else
            {
                return RecursiveNode(node);
            }
        }
    }
}


在使用的时候一般是在模板页面来使用此类。


效果图:








本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
xml
MVC中的ActionResult
MVC 自定义AuthorizeAttribute实现权限管理
ASP.NET MVC 2生成动态表单的一种最简单的思路
Java程序员应知应会,为什么现在我们不用Servlet了?
解决Spring MVC 对AOP不起作用的问题
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服