Používání Web.SiteMap s dynamické adresy URL (Routing)

hlasů
9

Rád bych, aby odpovídaly „přibližné“ zápasů v Web.SiteMap

Web.Sitemap static poskytovatel sitemap funguje dobře, až na jednu věc. TO STATIC!

Takže pokud bych musel mít sitemapnode pro každou z 10,000 článků o mé stránky jako tak:

  • 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

Je tam nějaká mapování zástupných mohu dělat s SiteMap aby odpovídala nic pod články?

Nebo snad v mém WebForms Page, je tu způsob, jak ručně nastavit aktuální uzel?

Zjistil jsem si „trochu“ pomoci na této stránce , když dělá to s ASP.NET MVC Framework, ale stále hledají dobré řešení pro WebForms.

Myslím, že budu muset udělat, je vytvořit vlastní SiteMap Provider

Položena 15/11/2008 v 01:48
zdroj uživatelem
V jiných jazycích...                            


3 odpovědí

hlasů
7

To je v reakci na komentář výše. Nemohu psát celý kód, ale to je v podstatě, jak se můj poskytovatel funguje.

Předpokládejme, že máte stránky article.aspx, a používá dotazu parametr řetězec „ID“ načíst a zobrazit název článku a tělo. Pak je to v Web.sitemap:

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

Pak vytvořte tuto třídu:

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);
    }
  }
}

Nakonec pomocí tohoto dodavatele v kódu, stejně jako byste použili statickou zprostředkovatele.

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

Moje třída je mnohem složitější, než to, ale to jsou základy. Namísto použití parametru QueryString, mohli jste právě analyzovat přátelské URL, kterou používáte, a použít místo toho získat správný obsah. Aby se minimalizovaly dodatečné db vyhledávání s každou žádost, můžete přidat mechanismus ukládání do mezipaměti na poskytovatele (název článku obvykle se často nemění).

Snad to pomůže.

Odpovězeno 20/11/2008 v 10:09
zdroj uživatelem

hlasů
2

Byl jsem běží na tento problém a, upřímně řečeno, nemůže najít žádné řešení, které se mi šťastná ... tak jsem si půjčit nápady z sem a tam. Moje řešení je vícedílný: a) mít SiteMapProvider najít aktuální stránku manipulaci žádosti a použít je to uzel a b) použít standardní techniky pro aktualizaci sitemapnode odtamtud.

A) Problém jsem běžel do je, že když jsem neměl správný virtuální cestu, SiteMap.CurrentNode by bylo neúčinné a oheň funkce SiteMapResolve. K vyřešení tohoto problému I podtřídy XmlSiteMapProvider a nedbal 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;
            }
        }
    }
}

Zjednodušeně řečeno, pokud je výchozí implementace nenajde nic, vyhledat trasu (pokud existuje) a pokusit se najít uzel pomocí virtuální cestu psovoda.

Pro porovnání je zde součástí mého Web.config Global.asax a soubory Sitemap:

Přidání poskytovatele

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

Trasa:

            routes.MapPageRoute("EvalRoutes",
            "Evals/{type}/New.aspx",
            "~/Evals/New.aspx");

A SiteMap:

        <siteMapNode url="~/Evals/New.aspx" title="New Eval - {type}"  description="" />

B) I podtřídy System.Web.UI.Page, výstižně pojmenované BaseClass, který přidává metodu k registraci rutiny pro události 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;
    }

I nadále je třeba mít mapovat adresy URL odpovídajícím způsobem (dále bude používat adresu URL stránky, který je příjemcem trasu), který je sans směrovacích informací. Budu pravděpodobně používat vlastní atribut v souboru Sitemap sdělit uzlu, jak k tomu, aby URL.

Odpovězeno 18/12/2010 v 00:10
zdroj uživatelem

hlasů
2

To není úplně odpověď na vaši otázku, myslím, ale možná to vám dává představu. Jednou jsem napsal třídu DynamicSiteMapPath dědí SiteMapPath. Používám vlastní atribut v každé <siteMapNode>značky v Web.sitemap, například takto:

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

Pak třída DynamicSiteMapPath dostane hodnotu parametru „ID“, načte obsah z databáze, a potlačí aktuálně tavené sitemap položka uzel se správným názvem a odkazem. Že to bude trvat trochu práce, ale když udělal správně, to je velmi elegantní způsob, jak zajistit dynamickou podporu stránek.

Odpovězeno 19/11/2008 v 13:26
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more