Cómo: Modificar los nodos de mapa de sitio en memoria mediante programación

Actualización: noviembre 2007

Los sitios Web utilizan con frecuencia direcciones URL dinámicas que contienen información que se agrega en forma de cadenas de consulta. Por ejemplo, el sitio de un grupo de noticias o un foro podría incluir direcciones URL estáticas que hicieran referencia a foros o grupos además de las direcciones URL dinámicas de cada publicación. Una dirección URL de una publicación podría tener el formato siguiente: https://www.microsoft.com/newsgroups/ShowPost.aspx? ForumID=2&PostID=53

No resulta eficaz actualizar un mapa del sitio para mostrar la dirección URL de cada publicación porque los nodos no se pueden agregar a un mapa del sitio mediante programación. Sin embargo, cuando un usuario está viendo una publicación, se puede utilizar el control SiteMapPath para mostrar la ruta de desplazamiento de regreso al nodo raíz y agregar dinámicamente las cadenas de consulta a cada vínculo de la ruta de acceso, que identifican la publicación, el foro o el grupo. Por ejemplo, la ruta de desplazamiento de la publicación anterior podría tener el aspecto siguiente:

Inicio > Lista de foros > Lista de publicaciones

La propiedad Url estática del nodo del mapa del sitio de las publicaciones podría establecerse en https://www.microsoft.com/newsgroups/ShowPost.aspx. No obstante, en la memoria puede modificar la dirección URL en el control SiteMapPath para identificar el foro y la publicación especificada.

Puede cambiar los nodos del mapa del sitio en la memoria utilizando el evento SiteMapResolve, como se muestra en el procedimiento y el ejemplo siguiente.

Para cambiar los nodos del mapa del sitio mediante programación

  1. En el código de una página de formularios Web Forms, cree un método para controlar el evento SiteMapResolve. Por ejemplo, la declaración siguiente crea un método denominado ExpandForumPaths.

    private SiteMapNode ExpandForumPaths(Object sender, 
                                         SiteMapResolveEventArgs e)
    
    Private Function ExpandForumPaths(ByVal sender As Object, ByVal e As SiteMapResolveEventArgs) As SiteMapNode
    
  2. En su controlador de eventos, obtenga una referencia al nodo actual y duplíquela. Por ejemplo, si el nodo es una publicación del grupo de noticias, el aspecto del código sería similar a:

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

    La variable tempNode devuelve un nodo del mapa del sitio situado en la memoria que se puede recorrer, al modificar todas las propiedades Url u otras propiedades. Se mantiene la referencia en nodeCopy por separado porque el valor devuelto esperado del controlador de eventos es una referencia al nodo actual. Sin embargo, la variable tempNode se utilizará para desplazar hacia arriba la estructura de exploración de forma recursiva.

    Nota:

    Dado que el nodo duplicado está separado de la estructura estática de exploración del sitio, los cambios realizados en las propiedades Url no se mantienen en la memoria ni es guardan en el disco.

  3. Cambie las propiedades Url del nodo actual y su nodo primario para incluir la información de la cadena de consulta que muestra los identificadores de la publicación, del foro o del grupo.

    Por ejemplo, el ejemplo de código siguiente presupone la existencia de tres métodos que obtienen los identificadores.

    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:

    Las instrucciones if se utilizan para garantizar que las cadenas de consulta sólo se agregan a los nodos del mapa del sitio existentes si y sólo si el grupo, el formulario y los identificadores de la publicación están disponibles.

  4. Devuelva el nodo duplicado utilizando la línea de código siguiente.

    return currentNode;
    
    Return currentNode
    
  5. Registre su controlador de eventos en el método Page_Load. Por ejemplo, el código podría tener el aspecto siguiente.

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

    El evento SiteMapResolve se desencadena cuando el proveedor del mapa del sitio tiene acceso a la propiedad CurrentNode, por ejemplo cuando el control SiteMapPath está representando una estructura de exploración.

  6. Agregue un control SiteMapPath a su página de formularios Web Forms para ver la estructura de exploración. El control SiteMapPath podría parecerse a:

    <asp:SiteMapPath
    id="SiteMapPath1"
    
    RenderCurrentNodeAsLink="true" />
    
  7. Asegúrese de que hay un nodo para la página de formularios Web Forms en el archivo del mapa del sitio. Por ejemplo, si su página de formularios Web Forms se llama a ShowPost.aspx, su archivo Web.sitemap se podría parecer a lo siguiente.

    <?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>
    

Ejemplo

En el ejemplo de código siguiente se ilustra cómo puede controlar el evento SiteMapResolve de una página Web ASP.NET para modificar las direcciones URL de destino mostradas por el control SiteMapPath. En este ejemplo, la página actual es la página de una publicación de un foro o un boletín electrónico en línea. Para representar la exploración del sitio más significativa, las direcciones URL de los nodos mostrados por el control SiteMapPath se anexan con cadenas de consulta relevantes para el contexto. Utilice el código siguiente para representar el control.

<asp:SiteMapPath
id="SiteMapPath1"

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

RenderCurrentNodeAsLink="true" />

Al ejecutar el ejemplo, coloque el cursor sobre los vínculos del control SiteMapPath para ver cómo cambian las direcciones URL.

Este ejemplo no agrega elementos SiteMapNode en el archivo Web.sitemap; el archivo Web.sitemap sólo se puede editar manualmente.

Nota:

El acceso a la propiedad CurrentNode desde dentro del control SiteMapResolveEventHandler es una práctica segura. En este caso, la infraestructura de exploración del sitio de ASP.NET se protege contra la recursividad infinita.

En este ejemplo se presupone que ya existe un archivo de mapa del sitio válido, y que la página actual está por lo menos a tres nodos de profundidad en la estructura de mapa del sitio. Para obtener más información sobre cómo crear mapas del sitio, vea Mapas de sitio de 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;
}

Seguridad

Un aspecto importante al trabajar con cadenas de consulta y datos de formulario es validar los datos que se transfieren. ASP.NET ofrece un conjunto de controles de validación que proporciona una forma eficaz y fácil de usar para comprobar errores y, si es necesario, mostrar mensajes al usuario. Los controles de validación no se han utilizado en el ejemplo anterior para centrar la atención en la tarea de cambiar los nodos del mapa del sitio. Para obtener información sobre cómo agregar validación al código, vea Controles de validación ASP.NET.

Vea también

Conceptos

Eventos en páginas principales y páginas de contenido ASP.NET

Proteger la exploración del sitio de ASP.NET

Proteger el acceso a datos

Referencia

SiteMapResolve

SiteMapNode

SiteMapPath

Context

Otros recursos

Controles de validación ASP.NET

Controlar y provocar eventos

Seguridad de aplicaciones ASP.NET en entornos alojados en host