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. 最后,点击这里可以下载代码示例.