我一直在遇到這個問題,坦率地說,沒有找到任何讓我快樂的解決方案......所以我借鑑了來自這裏和那裏的想法。我的解決方案是多方面的:a)讓SiteMapProvider查找處理請求的實際頁面並使用它的節點; b)使用標準技術從那裏更新sitemapnode。
A)我一直遇到的問題是,如果我沒有正確的虛擬路徑,SiteMap.CurrentNode將爲null,並激發SiteMapResolve函數。爲了解決這個我子類XmlSiteMapProvider和推翻CurrentNode:
namespace WebFormTools
{
class RouteBaseSitemapProvider : XmlSiteMapProvider
{
public override SiteMapNode CurrentNode
{
get
{
var node = base.CurrentNode;
if (node == null)
{
// we don't have a node, see if this is from a route
var page = HttpContext.Current.CurrentHandler as System.Web.UI.Page;
if (page != null && page.RouteData != null)
{
// try and get the Virtual path associated with this route
var handler = page.RouteData.RouteHandler as PageRouteHandler;
if (handler != null) {
// try and find that path instead.
node = FindSiteMapNode(handler.VirtualPath);
}
}
}
return node;
}
}
}
}
基本上,如果默認的實現沒有發現什麼,查找路線(如果有的話),並試圖找到使用處理程序的虛擬路徑節點。
僅供參考這裏是我的web.config,Global.asax中和Sitemap文件的一部分:
添加提供商
<siteMap defaultProvider="RouteBaseSitemapProvider">
<providers>
<add name="RouteBaseSitemapProvider" type="WebFormTools.RouteBaseSitemapProvider" siteMapFile="Web.sitemap" />
</providers>
</siteMap>
路線:
routes.MapPageRoute("EvalRoutes",
"Evals/{type}/New.aspx",
"~/Evals/New.aspx");
而且網站地圖:
<siteMapNode url="~/Evals/New.aspx" title="New Eval - {type}" description="" />
B)我子類System.Web.UI.Page,恰當地命名爲BaseClass的,這增加了註冊的處理程序SiteMapResolve事件的方法:
public System.Web.SiteMapNode Process(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<Regex, string>();
// build a list of RegEx to aid in converstion, using RegEx so I can ignore class. Technically I could also
foreach (var key in page.RouteData.Values.Keys)
{
replacements.Add(new Regex(string.Format("\\{{{0}\\}}", key), RegexOptions.IgnoreCase), page.RouteData.Values[key].ToString());
}
// navigate up the nodes
var activeNode = currentNode;
while (activeNode != null)
{
// to the replacements
foreach(var replacement in replacements)
{
activeNode.Title = replacement.Key.Replace(activeNode.Title, replacement.Value);
}
activeNode = activeNode.ParentNode;
}
}
return currentNode;
}
我仍然需要有URL映射適當地(在將使用接收路由的頁面的URL),這是無路由信息。我可能會在站點地圖中使用自定義屬性來告訴節點如何呈現URL。
酷!謝謝。我將發佈一個我也提出的解決方案。 – Armstrongest 2008-11-27 23:54:15