Ich bin auf dieses Problem gestoßen und, offen gesagt, keine Lösungen zu finden, die mich glücklich gemacht haben ... so borge ich Ideen von hier und dort aus. Meine Lösung ist mehrteilig: a) Lassen Sie den SiteMapProvider die Seite finden, die die Anfrage bearbeitet, und verwenden Sie den Knoten und b) verwenden Sie Standardtechniken, um den sitemapnode von dort zu aktualisieren.
A) Das Problem, mit dem ich fortgefahren bin, ist, dass, wenn ich nicht den richtigen virtuellen Pfad hätte, der SiteMap.CurrentNode null wäre und die SiteMapResolve-Funktion auslöst. Um dies zu lösen ich subclassed XmlSiteMapProvider und overrode 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;
}
}
}
}
Grundsätzlich, wenn die Standardimplementierung der nichts finden, um die Strecke sehen (falls vorhanden) und versuchen, den Knoten zu finden mit Hilfe der virtuellen Pfad absetzen.
Als Referenz hier ist ein Teil meiner Web.Config, Global.asax und Sitemaps:
den Anbieter
<siteMap defaultProvider="RouteBaseSitemapProvider">
<providers>
<add name="RouteBaseSitemapProvider" type="WebFormTools.RouteBaseSitemapProvider" siteMapFile="Web.sitemap" />
</providers>
</siteMap>
Die Route hinzufügen:
routes.MapPageRoute("EvalRoutes",
"Evals/{type}/New.aspx",
"~/Evals/New.aspx");
Und die SiteMap:
<siteMapNode url="~/Evals/New.aspx" title="New Eval - {type}" description="" />
B) I Unterklasse System.Web.UI.Page, treffend benannt Baseclass, das ein Verfahren fügt Handler für das SiteMapResolve Ereignis registrieren:
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;
}
Ich muss noch die URLs entsprechend abbilden haben (das würde verwenden die URL der Seite, die die Route empfängt), die keine Routinginformationen enthält. Ich werde wahrscheinlich ein benutzerdefiniertes Attribut in der Sitemap verwenden, um dem Knoten mitzuteilen, wie die URL gerendert werden soll.
Cool! Vielen Dank. Ich werde eine Lösung posten, die ich mir ausgedacht habe. – Armstrongest
Wie kann ich diese Klasse in meiner Aspx-Seite verwenden? jede Hilfe bitte –