Frage

Ich möchte "ungefähre" passen Spiele in Web.sitemap

Der Web.sitemap statische Sitemap Anbieter funktioniert gut, außer für eine Sache. ITIS STATIC!

Also, wenn ich würde wie so eine SiteMapNode für jede der 10.000 Artikel auf meiner Seite haben muß:

  • site.com/articles/1/article-title
  • site.com/articles/2/another-article-title
  • site.com/articles/3/another-article-again
  • ...
  • site.com/articles/9999/the-last-article

Gibt es irgendeine Art von Wildcard-Mapping ich mit der SiteMap tut Alles, was nach den Artikeln passen?

Oder vielleicht in meiner Webforms Seite, gibt es eine Möglichkeit, manuell die aktuellen Knoten gesetzt?

Ich habe einen „Bit“ von Hilfe auf dieser Seite gefunden , wenn sie mit dem ASP.Net MVC-Framework dies zu tun, aber für eine gute Lösung für Webforms noch auf der Suche.

Ich denke, was ich tun zu müssen, ist eine benutzerdefinierte SiteMap Provider erstellen

War es hilfreich?

Lösung

Dies ist als Reaktion auf den Kommentar oben. Ich kann nicht den ganzen Code schreiben, aber das ist im Grunde, wie mein Provider funktioniert.

Angenommen, Sie eine Seite article.aspx haben, und es verwendet die Query-String-Parameter „id“ abzurufen und einen Artikel Titel und Körper anzuzeigen. Dann ist dies in Web.sitemap:

<siteMapNode url="/article.aspx" title="(this will be replaced)" param="id" />

Dann Sie diese Klasse erstellen:

public class DynamicSiteMapPath : SiteMapPath
{
  protected override void InitializeItem(SiteMapNodeItem item)
  {
    if (item.ItemType != SiteMapNodeItemType.PathSeparator)
    {
      string url = item.SiteMapNode.Url;
      string param = item.SiteMapNode["param"];

      // get parameter value
      int id = System.Web.HttpContext.Current.Request.QueryString[param];

      // retrieve article from database using id
      <write your own code>

      // override node link
      HyperLink link = new HyperLink();
      link.NavigateUrl = url + "?" + param + "=" + id.ToString();
      link.Text = <the article title from the database>;
      link.ToolTip = <the article title from the database>;
      item.Controls.Add(link);
    }
    else
    {
      // if current node is a separator, initialize as usual
      base.InitializeItem(item);
    }
  }
}

Schließlich Sie diesen Anbieter in Ihrem Code verwenden wie Sie den statischen Anbieter verwenden würden.

<mycontrols:DynamicSiteMapPath ID="dsmpMain" runat="server" />

Meine Klasse ist komplizierter als das, aber das sind die Grundlagen. Statt einen Abfragezeichenfolgeflag Parameter verwenden, können Sie nur die freundliche URL analysieren Sie verwenden, und verwenden Sie diese stattdessen den richtigen Inhalt abzurufen. Um die zusätzlichen db-Lookups bei jeder Anfrage zu minimieren, können Sie einen Caching-Mechanismus zum Provider hinzufügen (Titel des Artikels in der Regel nicht häufig ändern).

Hope, das hilft.

Andere Tipps

Dies ist nicht ganz eine Antwort auf Ihre Frage, die ich denke, aber vielleicht gibt es Ihnen eine Idee. Ich schrieb einmal eine DynamicSiteMapPath Klasse erben SiteMapPath. Ich verwende ein benutzerdefiniertes Attribut in jedem <siteMapNode> Tag in Web.sitemap, wie folgt aus:

<siteMapNode url="dynamicpage.aspx" title="blah" params="id" />

Dann wird die DynamicSiteMapPath Klasse des „id“ Parameterwert, ruft den Inhalt aus der Datenbank und überschreibt die aktuell Sitemap Artikel Knoten mit dem richtigen Titel und Link angezeigt. Es wird eine wenig Arbeit, aber wenn die Bereitstellung von dynamischen Seiten Unterstützung richtig dies ist eine sehr nette Art und Weise getan.

Ich habe in dieses Problem laufen und, ehrlich gesagt, keine Lösungen zu finden, die mich glücklich gemacht ... so borge ich Ideen von hier und dort. Meine Lösung ist mehrteilig: a.) Hat die Sitemap die aktuelle Seite finden Sie die Anforderung bearbeitet und verwendet es Knoten und b) verwenden Standardtechniken für die Aktualisierung der SiteMapNode von dort

A) Das Problem, das ich laufe immer wieder in ist, dass, wenn ich nicht den richtigen virtuellen Pfad habe, die SiteMap.CurrentNode null sein würde und das Feuer der SiteMapResolve Funktion. Um dies zu lösen subclassed ich 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;
            }
        }
    }
}

Im Grunde genommen, wenn die Standardimplementierung den nichts finden, um die Strecke sehen (falls vorhanden) und versucht, den Knoten zu finden, die virtuellen Pfad der Handler.

Als Referenz hier ist ein Teil meiner Web.Config, Global.asax und Sitemaps:

Das Hinzufügen der Anbieter

    <siteMap defaultProvider="RouteBaseSitemapProvider">
  <providers>
    <add name="RouteBaseSitemapProvider" type="WebFormTools.RouteBaseSitemapProvider" siteMapFile="Web.sitemap" />
  </providers>
</siteMap>

Die Route:

            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 (die die URL der Seite verwenden würde die Route empfangen), die sans Routing-Informationen ist. Ich werde wahrscheinlich ein benutzerdefiniertes Attribut in der Sitemap verwenden, um die Knoten zu sagen, wie die URL zu machen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top