SiteMap jak jinak ??? Čtěte   otázka

VB.NET, ASP.NET WebForms

Omlouvám se, že sem zase píšu, ale já už vážně nevím jsem z toho na prášky.

tento kód:

    Inherits StaticSiteMapProvider

    Private root As SiteMapNode = Nothing
    Private List As New Dictionary(Of Integer, SiteMapNode)

    Protected Overrides Sub Clear()
        SyncLock Me
            root = Nothing
            List.Clear()
        End SyncLock
    End Sub




    Public Overrides Function BuildSiteMap() As System.Web.SiteMapNode
        SyncLock Me

            Clear()

            If root Is Nothing Then         'pokud je třeba generovat, generujeme

                Clear()

                'vytvořit kořenovou položku

                root = New SiteMapNode(Me, Guid.NewGuid().ToString(), Me.UrlRoot, Me.TitleRoot)


                'podpoložky natáhnout z databáze

                Dim con As New SqlConnection(ConfigurationManager.ConnectionStrings(Me.ConnectionStringName).ConnectionString)

                Dim TopicCom As New SqlCommand(Me.CommandTopic, con)

                Dim PostCom As New SqlCommand(Me.CommandPost, con)

                con.Open()

                Dim TopicReader As SqlDataReader = TopicCom.ExecuteReader()

                While TopicReader.Read()

                    Dim Topic As New SiteMapNode(Me, TopicReader(Me.UrlTopic), String.Format(Me.UrlFormatTopic, TopicReader(Me.UrlTopic)), TopicReader(Me.TitleTopic), TopicReader(Me.TitleTopic))

                    AddNode(Topic, root)

                    List.Add(TopicReader(Me.UrlTopic), Topic)

                End While

                TopicReader.Close()

                Dim PostReader As SqlDataReader = PostCom.ExecuteReader()

                While PostReader.Read()

                    Dim Post As New SiteMapNode(Me, Guid.NewGuid().ToString(), String.Format(Me.UrlFormatPost, PostReader(Me.UrlPost)), PostReader(Me.TitlePost))

                    AddNode(Post, List(PostReader(Me.IdTopicPost)))

                End While

                PostReader.Close()

                con.Close()



            End If



            Return root         'vrátíme kořenovou položku



        End SyncLock


    End Function

Když to mám jako v tomto kódu tak mi to vyhodí hlášku:Bylo nalezeno více uzlů se stejnou adresou URL /Grr/ListTopic.aspx?Id=2. Zprostředkovatel XmlSiteMapProvider vyžaduje, aby uzly mapy webu měly jedinečné adresy URL.

což není možné, protože zaprvé jsem všechny data smazal metodou clear() a za druhé v databasi mam jen jeden zaznam takže by to tuto hlášku nemělo vyhodit už protože v databasi je jen jeden záznam. => nemůže být chyba v DB.

Pokud nastavím url třeba takto "" aby to prostě url nedělalo žádnou, tak si to prozměnu vymislí hlášku:

Bylo nalezeno více uzlů se stejným klíčem 2. Zprostředkovatel XmlSiteMapProvider vyžaduje, aby uzly mapy webu měly jedinečné klíče.

což není možné ze stejného důvodu jako minule v DB je 1 záznam a minulou vytvořenou nodu jsem smazal methodou clear()

v obou těchto chybách je červeně označný tento řádek:

AddNode(Topic, root)

tedy slinkování.Už ze zoufalosti jsem zkoušel slinkovat třeba takto:

root.childnodes.Add(Topic)

Ale nato aby to fungovalo by to bylo moc jednoduché tak si to prozměnu vymislelo že jsem vyčerpal počet připojení k databasi.(což zdůraznuji neni pravda)

Předpokládám, že když udělám v methodě Clear() toto:

root = Nothing

že se nastaví na nothing i childnodes což jsou v mém případě Topici u kterých to dělá chybu.Předpokládám tak i protože když jsem zkoušel smazat samotné topici třeba takto :

root.childnodes.Clear()    'nebo
root.childnodes = nothing

tak to vyhodilo chybu.

Možná ještě proč tohle všechno dělám chci udělat ze static nestatic (aby při každém aktualizování tahalo z database to že chudinka database bude utlačovaná mi zatím vážně nevadí hlavně ať si to nevymíšlí hloupé chyby)

Dále nevím co dodat jestli jsem tak blbej a nevidím tam triviální chybu a vi ano tak mi prosím řekněte kde!

PS : omlouvám se

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Potíž je v tom, že SiteMapProvider v ASP.NET počítá s tím, že SiteMapa musí být velká a nebude najdenou natažená v paměti - bude se dotahovat postupně. StaticSiteMapProvider dědí ze SiteMapProvider a ten počítá s tím, že SiteMapa se vytvoří jednou a pak už taková zůstane.

Proto se nedá sahat do kolekce ChildNodes, nemůžeš ji zvenčí upravovat atd. Proto se jednotlivé položky SiteMapy prolinkovávají přes AddNode, která tu vazbu udělá sama a sáhne do kolekce ChildNodes. Je to taky kvůli tomu, aby se SiteMapa nedala jednodueš rozbít.

Neomlouvej se, problém je v tom, že tohle je dost složitá věc a jako začátečník s tím máš oprávněně problémy. Doporučuji přečíst si seriál o .NET Frameworku, který teď píšu (ten pro pokročilé), zejména pak načíst si dědičnost, ať je ti to jasné.

Aby tohle fungovalo, mělo by stačit do metody Clear přidat řádek

 MyBase.Clear() 

Ty totiž v metodě Clear smažeš svoje data, ale nezavoláš metodu Clear z třídy, kterou dědíš. A ta metoda může něco dělat (a ona opravdu dělá - smaže celou SiteMapu). Ty jen nastavíš kořenovou položku na Nothing, ale to nestačí - objekty v paměti zůstanou a jsou někde ve třídě StaticSiteMapProvider nebo níž drženy v nějaké kolekci.

nahlásit spamnahlásit spam 2 / 2 odpovědětodpovědět

Děkuji za vysvětlení.Po přidání MyBase.Clear() se sice už žádné záludné chyby neukazují což mi udělalo velikou radost ,ale hnedka po tom jsem zjistil že se vypsala pouze kořenová položka. Podpoložky (topici) se nevypsaly :(. Kdybyste měl někdy zase čas a věděl v čem je nyní problém tak prosím odpovězte.

PS: Dnes jsem přečetl seriál o .NET Frameworku, hodně věcí jsem věděl a hodně se dozvěděl těším se na další díly.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tohle se bude blbě hledat, doporučuju, abys to generování sitemapy odkrokoval. Hoď si tam breakpoint a uvidíš.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Krokování to už jsem někde slyšel vyzkouším. DĚKUJI

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Vzhledem k tomu, že se na to ptá velké množství začátečníků, v nejbližších dnech o tom udělám screencast na www.mstv.cz.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Zajímavé při krokování to ukázalo zde chybu:

AddNode(Topic, root)

se známou hláškou :)) , :\Bylo nalezeno více uzlů se stejnou adresou URL /Grr/ListTopic.aspx?Id=8. Zprostředkovatel XmlSiteMapProvider vyžaduje, aby uzly mapy webu měly jedinečné adresy URL.

Nechápu jak je možné že při krokování to chybu ukáže, ale normálně ne. Ale ještě zajímavější je hláška chyby, když jsem přeci data smazal ne ?? (při sledování uzlu root taky nemá žádné childnodes )

Tak radši zde ještě nynější methodu clear()

    Protected Overrides Sub Clear()
        SyncLock Me
            root = Nothing
            List.Clear()
            MyBase.Clear()
        End SyncLock
    End Sub

Když smažu methodu clear() nad podmínou tak se vše chová normálně tudíš se podle očekávání vytvoří sitemapa jen jednou. Ovšem když smažu clear() za podmínou a před nechám ukáže to tu chybu to samé když dám pryč podmínku (která tam je beztak k ničemu) a nechám tam jen jeden clear().

Z toho vyplívá, že jsem vlastně nic nezjistil a vše zůstalo přistaru a já pořát nevím co s tím.

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback