Практическое руководство. Программное изменение узлов карты веб-узла в памяти
Обновлен: Ноябрь 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, как показано в следующей процедуре и в примере.
Программное изменение узлов карты веб-узла
В коде на странице веб-форм создайте метод обработки события SiteMapResolve. Например, в следующем объявлении создается метод под названием ExpandForumPaths:
private SiteMapNode ExpandForumPaths(Object sender, SiteMapResolveEventArgs e)
Private Function ExpandForumPaths(ByVal sender As Object, ByVal e As SiteMapResolveEventArgs) As SiteMapNode
В обработчике событий получите ссылку на текущий узел и скопируйте ее. Например, если узел является сообщением в группе новостей, код может выглядеть следующим образом:
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 будет использоваться для рекурсивного передвижения вверх в структуре переходов.
Примечание. Так как скопированный узел является отдельным от структуры переходов веб-узла, изменения свойств Url не остаются в памяти и не сохраняются на диске.
Измените свойства 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
Примечание. Операторы if используются для обеспечения добавления строк запроса только в существующие узлы карты узла, а также при условии доступности идентификаторов группы новостей, форума или сообщения.
Верните скопированный узел, используя следующий код:
return currentNode;
Return currentNode
Зарегистрируйте обработчик событий в методе Page_Load. Например, код может выглядеть следующим образом:
SiteMap.SiteMapResolve += new SiteMapResolveEventHandler(this.ExpandForumPaths);
AddHandler SiteMap.SiteMapResolve, AddressOf Me.ExpandForumPaths
Примечание. Событие SiteMapResolve происходит, когда поставщик карты узла получает доступ к свойству CurrentNode, например когда элемент управления SiteMapPath отрисовывает структуру переходов.
Добавьте элемент управления SiteMapPath в веб-формы страницы, чтобы увидеть ее структуру переходов. Элемент управления SiteMapPath может выглядеть следующим образом:
<asp:SiteMapPath id="SiteMapPath1" runat="server" RenderCurrentNodeAsLink="true" />
Убедитесь, что узел страницы веб-форм присутствует в файле карты узла. Например, если страница веб-форм называется 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 необходимо редактировать вручную.
Примечание. |
---|
Получение доступа к свойству 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