Procedura: modificare a livello di codice i nodi della mappa del sito in memoria

Aggiornamento: novembre 2007

I siti Web utilizzano spesso URL dinamici contenenti informazioni che vengono accodate come stringhe di query. Si supponga ad esempio che il sito relativo a un newsgroup o a un forum includa sia URL statici, che fanno riferimento a forum o gruppi, sia URL dinamici per ciascun messaggio inserito. Un URL relativo a un messaggio inserito potrebbe avere il seguente formato: https://www.microsoft.com/newsgroups/ShowPost.aspx?ForumID=2\&PostID=53

L'aggiornamento di una mappa del sito allo scopo di elencare l'URL relativo a ciascun messaggio inserito non rappresenta un metodo efficace poiché i nodi non possono essere aggiunti alla mappa del sito a livello di codice. Tuttavia, quando un utente accede alla pagina di un messaggio, è possibile utilizzare il controllo SiteMapPath per visualizzare il percorso di spostamento fino al nodo principale e aggiungere dinamicamente stringhe di query a ciascun collegamento nel percorso, per identificare il messaggio, il forum o il gruppo. Ad esempio, il percorso di spostamento fino al messaggio indicato sopra potrebbe essere simile al seguente:

Home > Forum List > Post List

La proprietà Url statica del nodo della mappa del sito per i messaggi inseriti può essere impostata su https://www.microsoft.com/newsgroups/ShowPost.aspx. In memoria, tuttavia, è possibile modificare l'URL nel controllo SiteMapPath per identificare il forum e il massaggio specifico.

È possibile modificare i nodi della mappa del sito in memoria utilizzando l'evento SiteMapResolve, come illustrato nella procedura e nell'esempio riportati di seguito.

Per modificare i nodi della mappa del sito a livello di codice

  1. Nel codice di una pagina Web Form creare un metodo per la gestione dell'evento SiteMapResolve. Ad esempio, la seguente dichiarazione crea un metodo denominato ExpandForumPaths.

    private SiteMapNode ExpandForumPaths(Object sender, 
                                         SiteMapResolveEventArgs e)
    
    Private Function ExpandForumPaths(ByVal sender As Object, ByVal e As SiteMapResolveEventArgs) As SiteMapNode
    
  2. Nel gestore eventi ottenere un riferimento al nodo corrente e clonarlo. Ad esempio, se si tratta di un nodo per la gestione dei messaggi di un newsgroup, il codice potrebbe essere simile al seguente.

    SiteMapNode currentNode = SiteMap.CurrentNode.Clone(true);
    SiteMapNode tempNode = currentNode;
    
    Dim currentNode As SiteMapNode = SiteMap.CurrentNode.Clone(True)
    Dim tempNode As SiteMapNode = currentNode
    

    La variabile tempNode restituisce un nodo della mappa del sito presente in memoria che può essere attraversato, modificando ciascuna proprietà Url o altre proprietà. Il riferimento in nodeCopy viene gestito separatamente perché il valore previsto restituito dal gestore eventi è un riferimento al nodo corrente. Tuttavia, nel codice verrà utilizzata la variabile tempNode per spostarsi verso l'alto in modo ricorsivo nella struttura del sito.

    Nota:

    Poiché il nodo clonato è distinto dalla struttura statica del sito, le modifiche alle proprietà Url non vengono mantenute in memoria né salvate su disco.

  3. Modificare le proprietà Url del nodo corrente e del relativo nodo padre in modo da includere le stringhe di query relative agli identificatori di messaggio, forum e gruppo.

    Ad esempio, nel seguente esempio di codice si presuppone l'esistenza di tre metodi per ottenere gli identificatori.

    int forumGroupID = GetMostRecentForumGroupID();
    int forumID = GetMostRecentForumID(forumGroupID);
    int postID = GetMostRecentPostID(forumID);
    
    if (0 != postID)
    {
        tempNode.Url = tempNode.Url + "?PostID=" + postID.ToString();
    }
    
    if ((null != (tempNode = tempNode.ParentNode)) &&
        (0 != forumID))
    {
        tempNode.Url = tempNode.Url + "?ForumID=" + forumID.ToString();
    }
    
    if ((null != (tempNode = tempNode.ParentNode)) &&
        (0 != forumGroupID))
    {
        tempNode.Url = tempNode.Url + "?ForumGroupID=" + forumGroupID.ToString();
    }
    
    Dim forumGroupID As Integer = GetMostRecentForumGroupID()
    Dim forumID As Integer = GetMostRecentForumID(forumGroupID)
    Dim postID As Integer = GetMostRecentPostID(forumID)
    
    If Not (0 = postID) Then
        tempNode.Url = tempNode.Url & "?PostID=" & postID.ToString()
    End If
    
    tempNode = tempNode.ParentNode
    If Not (0 = forumID) And Not (Nothing = tempNode) Then
        tempNode.Url = tempNode.Url & "?ForumID=" & forumID.ToString()
    End If
    
    tempNode = tempNode.ParentNode
    If Not (0 = ForumGroupID) And Not (Nothing = tempNode) Then
        tempNode.Url = tempNode.Url & "?ForumGroupID=" & forumGroupID.ToString()
    End If
    
    Nota:

    Le istruzioni if vengono utilizzate per assicurare che le stringhe di query vengano aggiunte solo ai nodi della mappa del sito esistenti e solo se gli identificatori di gruppo, forum e messaggio sono disponibili.

  4. Restituire il nodo clonato utilizzando la seguente riga di codice.

    return currentNode;
    
    Return currentNode
    
  5. Registrare il gestore eventi nel metodo Page_Load. Il codice potrebbe essere simile a quello riportato nel seguente esempio.

    SiteMap.SiteMapResolve +=
      new SiteMapResolveEventHandler(this.ExpandForumPaths);
    
    AddHandler SiteMap.SiteMapResolve, AddressOf Me.ExpandForumPaths
    
    Nota:

    L'evento SiteMapResolve viene generato quando il provider della mappa del sito accede alla proprietà CurrentNode, come avviene quando il controllo SiteMapPath esegue il rendering di una struttura di spostamento all'interno del sito.

  6. Aggiungere un controllo SiteMapPath nella pagina Web Form per visualizzare la struttura di spostamento. Il controllo SiteMapPath potrebbe essere simile al seguente.

    <asp:SiteMapPath
    id="SiteMapPath1"
    
    RenderCurrentNodeAsLink="true" />
    
  7. Assicurarsi che nel file della mappa del sito sia incluso un nodo per la pagina Web Form. Ad esempio, se la pagina Web Form è denominata ShowPost.aspx, il file Web.sitemap potrebbe risultare simile al seguente.

    <?xml version="1.0" encoding="utf-8" ?>
    <siteMap>
      <siteMapNode
        title="Forum Group" 
        description="Forum Group List"
        url="default.aspx">
        <siteMapNode 
          title="Forum" 
          description="Forum List"
          url="ShowForum.aspx">
          <siteMapNode 
            title="Post" 
            description="Post List" 
            url="ShowPost.aspx" />
        </siteMapNode>
      </siteMapNode>
    </siteMap>
    

Esempio

Nell'esempio di codice riportato di seguito viene illustrato come gestire l'evento SiteMapResolve in una pagina ASP.NET per modificare gli URL di destinazione visualizzati dal controllo SiteMapPath. In questo esempio la pagina corrente corrisponde a un messaggio di un forum o di un servizio BBS in linea. Per consentire il rendering di una struttura di spostamento più significativa, agli URL dei nodi visualizzati dal controllo SiteMapPath vengono accodate stringhe di query pertinenti al contesto. Per eseguire il rendering del controllo, utilizzare il codice riportato di seguito.

<asp:SiteMapPath
id="SiteMapPath1"

RenderCurrentNodeAsLink="true" />
<asp:SiteMapPath
id="SiteMapPath1"

RenderCurrentNodeAsLink="true" />

Durante l'esecuzione dell'esempio, posizionare il cursore sui collegamenti nel controllo SiteMapPath per verificare come vengono modificati gli URL.

Questo esempio non aggiunge elementi SiteMapNode nel file Web.sitemap, che può essere modificato solo manualmente.

Nota:

Si consiglia di accedere alla proprietà CurrentNode direttamente dall'oggetto SiteMapResolveEventHandler. In questo caso, l'infrastruttura di esplorazione nel sito ASP.NET impedisce la ricorsione infinita.

In questo esempio si presuppone che esista già un file della mappa del sito valido e che la pagina corrente si trovi almeno al terzo livello nella struttura della mappa del sito. Per ulteriori informazioni sulla creazione di mappe del sito, vedere Mappe del sito ASP.NET.

Private Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)

    ' The ExpandForumPaths method is called to handle
    ' the SiteMapResolve event.
    AddHandler SiteMap.SiteMapResolve, AddressOf Me.ExpandForumPaths

End Sub

Private Function ExpandForumPaths(ByVal sender As Object, ByVal e As SiteMapResolveEventArgs) As SiteMapNode
    ' The current node represents a Post page in a bulletin board forum.
    ' Clone the current node and all of its relevant parents. This
    ' returns a site map node that a developer can then
    ' walk, modifying each node.Url property in turn.
    ' Since the cloned nodes are separate from the underlying
    ' site navigation structure, the fixups that are made do not
    ' effect the overall site navigation structure.
    Dim currentNode As SiteMapNode = SiteMap.CurrentNode.Clone(True)
    Dim tempNode As SiteMapNode = currentNode

    ' Obtain the recent IDs.
    Dim forumGroupID As Integer = GetMostRecentForumGroupID()
    Dim forumID As Integer = GetMostRecentForumID(forumGroupID)
    Dim postID As Integer = GetMostRecentPostID(forumID)

    ' The current node, and its parents, can be modified to include
    ' dynamic querystring information relevant to the currently
    ' executing request.
    If Not (0 = postID) Then
        tempNode.Url = tempNode.Url & "?PostID=" & postID.ToString()
    End If

    tempNode = tempNode.ParentNode
    If Not (0 = forumID) And Not (tempNode Is Nothing) Then
        tempNode.Url = tempNode.Url & "?ForumID=" & forumID.ToString()
    End If

    tempNode = tempNode.ParentNode
    If Not (0 = ForumGroupID) And Not (tempNode Is Nothing) Then
        tempNode.Url = tempNode.Url & "?ForumGroupID=" & forumGroupID.ToString()
    End If

    Return currentNode

End Function



...


' These methods are just placeholders for the example.
' One option is to use the HttpContext or e.Content object
' to obtain the ID.
Private Function GetMostRecentForumGroupID() As Integer
    Return 24
End Function

Private Function GetMostRecentForumID(ByVal forumGroupId As Integer) As Integer
    Return 128
End Function

Private Function GetMostRecentPostID(ByVal forumId As Integer) As Integer
    Return 317424
End Function
private void Page_Load(object sender, EventArgs e)
{
    // The ExpandForumPaths method is called to handle
    // the SiteMapResolve event.
    SiteMap.SiteMapResolve +=
      new SiteMapResolveEventHandler(this.ExpandForumPaths);
}

private SiteMapNode ExpandForumPaths(Object sender, SiteMapResolveEventArgs e)
{
    // The current node represents a Post page in a bulletin board forum.
    // Clone the current node and all of its relevant parents. This
    // returns a site map node that a developer can then
    // walk, modifying each node.Url property in turn.
    // Since the cloned nodes are separate from the underlying
    // site navigation structure, the fixups that are made do not
    // effect the overall site navigation structure.
    SiteMapNode currentNode = SiteMap.CurrentNode.Clone(true);
    SiteMapNode tempNode = currentNode;

    // Obtain the recent IDs.
    int forumGroupID = GetMostRecentForumGroupID();
    int forumID = GetMostRecentForumID(forumGroupID);
    int postID = GetMostRecentPostID(forumID);

    // The current node, and its parents, can be modified to include
    // dynamic querystring information relevant to the currently
    // executing request.
    if (0 != postID)
    {
        tempNode.Url = tempNode.Url + "?PostID=" + postID.ToString();
    }

    if ((null != (tempNode = tempNode.ParentNode)) &&
        (0 != forumID))
    {
        tempNode.Url = tempNode.Url + "?ForumID=" + forumID.ToString();
    }

    if ((null != (tempNode = tempNode.ParentNode)) &&
        (0 != forumGroupID))
    {
        tempNode.Url = tempNode.Url + "?ForumGroupID=" + forumGroupID.ToString();
    }

    return currentNode;
}


...


// These methods are just placeholders for the example.
// One option is to use the HttpContext or e.Content object
// to obtain the ID.
private int GetMostRecentForumGroupID()
{
    return 24;
}

private int GetMostRecentForumID(int forumGroupId)
{
    return 128;
}

private int GetMostRecentPostID(int forumId)
{
    return 317424;
}

Sicurezza

Un aspetto importante dell'utilizzo di stringhe di query e dati di form consiste nella convalida dei dati che vengono passati. In ASP.NET viene fornito un gruppo di controlli di convalida con i quali è possibile identificare gli errori in modo facile ma potente e, se necessario, visualizzare i messaggi all'utente. Nell'esempio precedente i controlli di convalida non sono stati utilizzati per concentrare l'attenzione sull'attività di modifica dei nodi della mappa del sito. Per informazioni sull'aggiunta della convalida al codice, vedere Convalida dei controlli ASP.NET.

Vedere anche

Concetti

Eventi nelle pagine master e nelle pagine di contenuto ASP.NET

Protezione del sistema di spostamento all'interno dei siti ASP.NET

Protezione dell'accesso ai dati

Riferimenti

SiteMapResolve

SiteMapNode

SiteMapPath

Context

Altre risorse

Convalida dei controlli ASP.NET

Gestione e generazione di eventi

Protezione delle applicazioni ASP.NET in ambienti host