Поделиться через


Практическое руководство. Программное изменение узлов карты веб-узла в памяти

Обновлен: Ноябрь 2007

Веб-узлы нередко используют динамическую URL-информацию, добавляемую в строки запросов. Например, узел группы новостей или форум могут содержать статические URL-адреса, указывающие на форумы или группы, а также динамические URL-адреса каждого сообщения. URL-адрес сообщения может иметь следующий формат: https://www.microsoft.com/newsgroups/ShowPost.aspx?ForumID=2\&PostID=53.

Обновление карты узла с получением URL-адреса каждого сообщения не является эффективным методом, поскольку узлы карты не могут добавляться в карту веб-узла программно. Вместе с тем при просмотре пользователем сообщения можно использовать элемент управления SiteMapPath для отображения обратного пути к корневому узлу и динамического добавления строк запросов в каждую ссылку в пути, указывающих на сообщение, форум или группу новостей. Например, путь к предыдущему сообщению может выглядеть следующим образом:

Главная > Список форумов > Список сообщений.

Статическое свойство Url узла карты веб-узла для сообщений может быть установлено аналогично https://www.microsoft.com/newsgroups/ShowPost.aspx. Но в памяти можно изменять URL-адрес в элементе управления SiteMapPath, чтобы иметь возможность идентифицировать форум и сообщение.

Можно изменять узлы карты веб-узлов в памяти при помощи события SiteMapResolve, как показано в следующей процедуре и в примере.

Программное изменение узлов карты веб-узла

  1. В коде на странице веб-форм создайте метод обработки события SiteMapResolve. Например, в следующем объявлении создается метод под названием ExpandForumPaths:

    private SiteMapNode ExpandForumPaths(Object sender, 
                                         SiteMapResolveEventArgs e)
    
    Private Function ExpandForumPaths(ByVal sender As Object, ByVal e As SiteMapResolveEventArgs) As SiteMapNode
    
  2. В обработчике событий получите ссылку на текущий узел и скопируйте ее. Например, если узел является сообщением в группе новостей, код может выглядеть следующим образом:

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

    Переменная tempNode возвращает узел карты веб-узла в памяти, который может быть получен путем изменения свойств Url или других свойств. Ссылка в nodeCopy обрабатывается отдельно, поскольку ожидаемое возвращенное значение в обработчике событий является ссылкой на текущий узел. Однако переменная tempNode будет использоваться для рекурсивного передвижения вверх в структуре переходов.

    ms178425.alert_note(ru-ru,VS.90).gifПримечание.

    Так как скопированный узел является отдельным от структуры переходов веб-узла, изменения свойств Url не остаются в памяти и не сохраняются на диске.

  3. Измените свойства Url текущего узла и его родительского узла, с тем чтобы включить информацию из строки запроса, которая указывает на идентификатор сообщения, форума или группы новостей.

    Например, в следующем примере кода предполагается существование трех методов получения идентификаторов:

    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
    
    ms178425.alert_note(ru-ru,VS.90).gifПримечание.

    Операторы if используются для обеспечения добавления строк запроса только в существующие узлы карты узла, а также при условии доступности идентификаторов группы новостей, форума или сообщения.

  4. Верните скопированный узел, используя следующий код:

    return currentNode;
    
    Return currentNode
    
  5. Зарегистрируйте обработчик событий в методе Page_Load. Например, код может выглядеть следующим образом:

    SiteMap.SiteMapResolve +=
      new SiteMapResolveEventHandler(this.ExpandForumPaths);
    
    AddHandler SiteMap.SiteMapResolve, AddressOf Me.ExpandForumPaths
    
    ms178425.alert_note(ru-ru,VS.90).gifПримечание.

    Событие SiteMapResolve происходит, когда поставщик карты узла получает доступ к свойству CurrentNode, например когда элемент управления SiteMapPath отрисовывает структуру переходов.

  6. Добавьте элемент управления SiteMapPath в веб-формы страницы, чтобы увидеть ее структуру переходов. Элемент управления SiteMapPath может выглядеть следующим образом:

    <asp:SiteMapPath
    id="SiteMapPath1"
    runat="server"
    RenderCurrentNodeAsLink="true" />
    
  7. Убедитесь, что узел страницы веб-форм присутствует в файле карты узла. Например, если страница веб-форм называется ShowPost.aspx, файл Web.sitemap может выглядеть следующим образом.

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

Пример

В следующем примере кода показывается, как обработать событие SiteMapResolve на веб-странице ASP.NET для изменения целевых URL-адресов, которые отображаются при помощи SiteMapPath. В этом примере текущая страница является отправленной на подключенную к сети доску объявлений или форум. Для более информативной визуализации структуры перехода веб-узла URL-адреса узлов, отображаемые элементом управления SiteMapPath, добавляются со строками запросов, связанных с содержимым. Для отрисовки элемента используйте следующий код:

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

При выполнении следующего кода расположите курсор на ссылках в элементе управления SiteMapPath, чтобы увидеть изменения вида URL-адресов.

Данный пример не позволяет добавить элементы SiteMapNode в файл Web.sitemap; файл Web.sitemap необходимо редактировать вручную.

ms178425.alert_note(ru-ru,VS.90).gifПримечание.

Получение доступа к свойству CurrentNode безопасно в классе SiteMapResolveEventHandler. Среда структуры переходов веб-узла ASP.NET защищается в этом случае от бесконечной рекурсии.

В данном примере предполагается, что корректный файл карты узлов уже существует, а также что текущая страница содержит в структуре переходов по крайней мере три вложенных узла. Дополнительные сведения о картах веб-узлов см. в разделе Карты узла 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;
}

Безопасность

Важный аспект работы со строками запросов и данным в формах — проверка передаваемых данных. В ASP.NET предоставляется набор проверяющих элементов управления, обеспечивающих простой и эффективный способ поиска ошибок и, при необходимости, отображения соответствующих сообщений. Проверяющие элементы управления не использовались в примере выше, поскольку внимание было обращено на редактирование узлов карты веб-узла. Сведения о проверке кода см. в разделе Проверяющие элементы управления ASP.NET.

См. также

Основные понятия

События на главных страницах и страницах содержимого ASP.NET

Безопасность системы навигации веб-узла ASP.NET

Безопасность доступа к данным

Ссылки

SiteMapResolve

SiteMapNode

SiteMapPath

Context

Другие ресурсы

Проверяющие элементы управления ASP.NET

Обработка и вызов событий

Безопасность приложений ASP.NET в средах выполнения