J'ai été confronté à ce problème et, franchement, je n'ai trouvé aucune solution qui m'a fait plaisir ... alors j'emprunte des idées ici et là. Ma solution est en plusieurs parties: a) SiteMapProvider trouve la page réelle traitant la demande et utilise son nœud et b) utilise des techniques standard pour mettre à jour le sitemapnode à partir de là.
A) Le problème que j'ai rencontré est que si je n'avais pas le chemin virtuel correct, SiteMap.CurrentNode serait null et déclencherait la fonction SiteMapResolve. Pour résoudre cela, je XmlSiteMapProvider et l'emportaient sur sous-classé 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;
}
}
}
}
En gros, si l'implémentation par défaut ne trouve rien, regardez la route (le cas échéant) et essayer de trouver le nœud en utilisant le chemin virtuel du gestionnaire.
Pour référence est ici une partie de mon web.config, les fichiers Global.asax et SiteMap:
Ajout du fournisseur
<siteMap defaultProvider="RouteBaseSitemapProvider">
<providers>
<add name="RouteBaseSitemapProvider" type="WebFormTools.RouteBaseSitemapProvider" siteMapFile="Web.sitemap" />
</providers>
</siteMap>
L'itinéraire:
routes.MapPageRoute("EvalRoutes",
"Evals/{type}/New.aspx",
"~/Evals/New.aspx");
Et le SiteMap:
<siteMapNode url="~/Evals/New.aspx" title="New Eval - {type}" description="" />
B) sous-classe I System.Web.UI.Page, porte bien son nom BaseClass, qui ajoute une méthode pour enregistrer les gestionnaires pour l'événement 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;
}
je dois encore avoir les URL carte appropriée (l'utiliseraient la URL de la page recevant l'itinéraire), qui est sans informations de routage. J'utiliserai probablement un attribut personnalisé dans le sitemap pour indiquer au noeud comment rendre l'URL.
Cool! Merci. Je vais poster une solution que j'ai trouvée aussi. – Armstrongest
Comment puis-je utiliser cette classe dans ma page aspx? toute aide s'il vous plaît –