방법: 프로그래밍 방식으로 메모리에서 사이트 맵 노드 수정
업데이트: 2007년 11월
웹 사이트에서는 쿼리 문자열로 추가되는 정보가 포함된 동적 URL이 자주 사용됩니다. 예를 들어 뉴스 그룹 또는 포럼 사이트에는 포럼이나 그룹은 물론 각 게시물의 동적 URL을 참조하는 정적 URL이 포함될 수 있습니다. 게시물 URL의 형식은 https://www.microsoft.com/newsgroups/ShowPost.aspx?ForumID=2\&PostID=53과 같습니다.
노드는 사이트 맵에 프로그래밍 방식으로 추가할 수 없으므로 사이트 맵을 업데이트하여 모든 게시물의 URL을 나열하는 것은 효율적인 방법이라 할 수 없습니다. 그러나 사용자가 게시물을 볼 때 SiteMapPath 컨트롤을 사용하여 루트 노드로 되돌아가는 탐색 경로를 표시하고 경로의 각 링크에 게시물, 포럼 또는 그룹을 나타내는 쿼리 문자열을 동적으로 추가할 수 있습니다. 예를 들어 앞의 게시물에 대한 탐색 경로는 다음과 같습니다.
홈 > 포럼 목록 > 게시 목록
Post에 대한 사이트 맵 노드의 정적 Url 속성은 https://www.microsoft.com/newsgroups/ShowPost.aspx로 설정할 수 있습니다. 그러나 메모리에서는 SiteMapPath 컨트롤에 있는 URL을 수정하여 포럼 및 특정 게시물을 식별할 수 있습니다.
다음 프로시저 및 예제와 같이 SiteMapResolve 이벤트를 사용하면 메모리의 사이트 맵 노드를 변경할 수 있습니다.
사이트 맵 노드를 프로그래밍 방식으로 변경하려면
Web Forms 페이지에서 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 이벤트는 SiteMapPath 컨트롤이 탐색 구조를 렌더링하는 경우처럼 사이트 맵 공급자가 CurrentNode 속성에 액세스하면 발생됩니다.
Web Forms 페이지에 SiteMapPath 컨트롤을 추가하여 탐색 구조를 확인합니다. SiteMapPath 컨트롤은 다음과 같습니다.
<asp:SiteMapPath id="SiteMapPath1" RenderCurrentNodeAsLink="true" />
사이트 맵 파일에 Web Forms 페이지에 대한 노드가 있는지 확인합니다. 예를 들어 Web Forms 페이지가 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>
예제
다음 코드 예제는 ASP.NET 웹 페이지에서 SiteMapResolve 이벤트를 처리하여 SiteMapPath 컨트롤에 의해 표시되는 대상 URL을 수정하는 방법을 보여 줍니다. 이 예제에서 현재 페이지는 온라인 게시판 또는 포럼에 있는 게시 페이지입니다. 좀 더 의미 있는 사이트 탐색을 렌더링하려면 SiteMapPath 컨트롤에 의해 표시되는 노드의 URL 끝에 컨텍스트 관련 쿼리 문자열을 추가합니다. 다음 코드를 사용하여 컨트롤을 렌더링합니다.
<asp:SiteMapPath
id="SiteMapPath1"
RenderCurrentNodeAsLink="true" />
<asp:SiteMapPath
id="SiteMapPath1"
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 컨트롤을 참조하십시오.