Asp.Net 4中使用路由时使用SiteMap

    在ASP.net 4中使用路由新特性时,发现是无法使用默认的SiteMapPath控件的,不起作用.后来终于找到提供一个自定义的SiteMapProvider,从而使得在使用路由规则的页面中可以使用SiteMap.过程如下:

1.         环境准备

Window7(IIS7.5)+VS2010.

2.         首先实现一个自定义的SiteMapProvider,继承自XmlSiteMapProvider,代码如下:

public class RouteSiteMapProvider : XmlSiteMapProvider

    {

      

 public override SiteMapNode CurrentNode

        {

            get

            {

               

                var node = base.CurrentNode;

                if (node == null)

                {

                    var page = HttpContext.Current.CurrentHandler as System.Web.UI.Page;

                    if (page != null && page.RouteData != null)

                    {

                        var handler = page.RouteData.RouteHandler as PageRouteHandler;

                        if (handler != null)

                        {

                            node = FindSiteMapNode(handler.VirtualPath);

                        }

                    }

                }

                return node;

            }

        }

}

3.         在全局类中的Application_Start事件,增加对SiteMapResolve的事件处理,代码如下.

protected void Application_Start(object sender, EventArgs e)

        {

            RegisteRoutes(RouteTable.Routes);

 

            SiteMap.SiteMapResolve += new SiteMapResolveEventHandler(SiteMap_SiteMapResolve);

        }

其中, SiteMap_SiteMapResolve处理代码如下:

SiteMapNode SiteMap_SiteMapResolve(object sender, SiteMapResolveEventArgs e)

        {

            return ProcessNode (e.Provider.CurrentNode.Clone(true));

        }

这里使用传递的参数是e.Provider.CurrentNode.Clone(true),因为后续的代码是需要修改SiteMapNode,如果不调用Clone方法,则会出现SiteMapNode只读,无法修改的异常.

接着, Process方法中的代码是根据SiteMapNode参数,进行相应修改.代码如下:

System.Web.SiteMapNode ProcessNode(System.Web.SiteMapNode currentNode)

        {

            if (currentNode == null)

                return currentNode;

          

            var page = HttpContext.Current.CurrentHandler as System.Web.UI.Page;

            if (page != null && page.RouteData != null)

            {

                Dictionary<Regex, string> replacements = new Dictionary<System.Text.RegularExpressions.Regex, string>();

                foreach (var key in page.RouteData.Values.Keys)

                {

                    replacements.Add(new Regex(string.Format("\\{{{0}\\}}", key), RegexOptions.IgnoreCase), page.RouteData.Values[key].ToString());

                }

 

                var activeNode = currentNode;

                while (activeNode != null)

                {

                    foreach (var replacement in replacements)

                    {

                        activeNode.Title = replacement.Key.Replace(activeNode.Title, replacement.Value);

 

                    }

                    activeNode = activeNode.ParentNode;

                }

 

            }

            return currentNode;

 

        }

这里,只是修改相应的Title,当然,我们还是进行更多的修改.

4.         接着,修改web.config,增加SiteMapProvider,如下:

<siteMap defaultProvider="RouteSiteMapProvider" >

      <providers >

        <add name="RouteSiteMapProvider" type="WebApplication3.RouteSiteMapProvider" siteMapFile="~/Web.sitemap" />

           </providers>

    </siteMap>

 

6.         然后,项目中一个Web.SiteMap文件,内容如下:

<?xml version="1.0" encoding="utf-8" ?>

<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >

 <siteMapNode url="/Default.aspx" title="Asp.Net 4" description="">

    <siteMapNode url="/edit.aspx" title="Edit Items" description="" />

    <siteMapNode url="/show.aspx" title="Show" description="" />

    <siteMapNode url="/Items/Default.aspx" title="Items" description=""/>

 </siteMapNode>

</siteMap>

 

7.        在页面上添加 SiteMapPath控件,然后运行.我们边可以看到相应的SiteMap.

 

8.  最后,点击这里可以下载代码示例.

posted @ 2011-07-04 23:25  ♂风车车  阅读(986)  评论(1编辑  收藏  举报