작성자: 스콧 미첼
사용자 친화적인 웹 사이트의 일반적인 특징 중 하나는 일관된 사이트 전체 페이지 레이아웃 및 탐색 체계를 가지고 있다는 것입니다. 이 자습서에서는 쉽게 업데이트할 수 있는 모든 페이지에서 일관된 모양과 느낌을 만드는 방법을 알아봅니다.
소개
사용자 친화적인 웹 사이트의 일반적인 특징 중 하나는 일관된 사이트 전체 페이지 레이아웃 및 탐색 체계를 가지고 있다는 것입니다. ASP.NET 2.0에는 사이트 전체 페이지 레이아웃과 탐색 체계를 모두 구현하는 것을 크게 간소화하는 두 가지 새로운 기능인 마스터 페이지와 사이트 탐색이 도입되었습니다. 마스터 페이지를 사용하면 개발자가 지정된 편집 가능한 지역이 있는 사이트 전체 템플릿을 만들 수 있습니다. 그런 다음 이 서식 파일을 사이트의 ASP.NET 페이지에 적용할 수 있습니다. 이러한 ASP.NET 페이지는 마스터 페이지의 지정된 편집 가능한 영역에 대한 콘텐츠만 제공해야 하며 마스터 페이지의 다른 모든 태그는 마스터 페이지를 사용하는 모든 ASP.NET 페이지에서 동일합니다. 이 모델을 사용하면 개발자가 사이트 전체 페이지 레이아웃을 정의하고 중앙 집중화하여 쉽게 업데이트할 수 있는 모든 페이지에서 일관된 모양과 느낌을 쉽게 만들 수 있습니다.
사이트 탐색 시스템은 페이지 개발자가 사이트 맵을 정의하는 메커니즘과 프로그래밍 방식으로 쿼리할 해당 사이트 맵에 대한 API를 모두 제공합니다. 새 탐색 웹은 메뉴, TreeView 및 SiteMapPath를 제어하므로 일반적인 탐색 사용자 인터페이스 요소에서 사이트 맵의 전체 또는 일부를 쉽게 렌더링할 수 있습니다. 기본 사이트 탐색 공급자를 사용합니다. 즉, 사이트 맵이 XML 형식의 파일에 정의됩니다.
이러한 개념을 설명하고 자습서 웹 사이트를 더 쉽게 사용할 수 있도록 하기 위해 사이트 전체 페이지 레이아웃을 정의하고, 사이트 맵을 구현하고, 탐색 UI를 추가하는 이 단원을 살펴보겠습니다. 이 자습서의 끝부분에는 자습서 웹 페이지를 빌드하기 위한 세련된 웹 사이트 디자인이 있습니다.
그림 1: 이 자습서의 최종 결과(전체 크기 이미지를 보려면 클릭)
1단계: 마스터 페이지 만들기
첫 번째 단계는 사이트의 마스터 페이지를 만드는 것입니다. 현재 웹 사이트는 Typed DataSet(Northwind.xsd
App_Code
폴더의 경우), BLL 클래스(폴더의 모든 ProductsBLL.cs
항목), 데이터베이스(CategoriesBLL.cs
App_Code
폴더의 경우), 구성 파일(NORTHWND.MDF
App_Data
Web.config
) 및 CSS 스타일시트 파일(Styles.css
)로만 구성됩니다. 첫 번째 두 자습서에서 DAL과 BLL을 사용하는 것을 보여주는 페이지와 파일을 정리했습니다. 이후 자습서에서 이러한 예제를 더 자세히 살펴볼 예정입니다.
그림 2: 프로젝트의 파일
마스터 페이지를 만들려면 솔루션 탐색기에서 프로젝트 이름을 마우스 오른쪽 단추로 클릭하고 새 항목 추가를 선택합니다. 그런 다음 템플릿 목록에서 마스터 페이지 유형을 선택하고 이름을 지정 Site.master
합니다.
그림 3: 웹 사이트에 새 마스터 페이지 추가(전체 크기 이미지를 보려면 클릭)
마스터 페이지에서 사이트 전체 페이지 레이아웃을 정의합니다. 디자인 보기를 사용하고 필요한 레이아웃 또는 웹 컨트롤을 추가하거나 원본 보기에서 직접 태그를 추가할 수 있습니다. 내 마스터 페이지에서 외부 파일에 정의된 CSS 설정을 사용하여 위치 지정 및 스타일에 Style.css
트를 사용합니다. 아래 표시된 태그에서는 알 수 없지만 CSS 규칙은 탐색 <div>
콘텐츠가 절대적으로 배치되어 왼쪽에 표시되고 고정 너비가 200픽셀이 되도록 정의됩니다.
Site.master
<%@ Master Language="C#" AutoEventWireup="true"
CodeFile="Site.master.cs" Inherits="Site" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Working with Data Tutorials</title>
<link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="wrapper">
<form id="form1" runat="server">
<div id="header">
<span class="title">Working with Data Tutorials</span>
<span class="breadcrumb">
TODO: Breadcrumb will go here...</span>
</div>
<div id="content">
<asp:contentplaceholder id="MainContent"
runat="server">
<!-- Page-specific content will go here... -->
</asp:contentplaceholder>
</div>
<div id="navigation">
TODO: Menu will go here...
</div>
</form>
</div>
</body>
</html>
마스터 페이지는 정적 페이지 레이아웃과 마스터 페이지를 사용하는 ASP.NET 페이지에서 편집할 수 있는 영역을 모두 정의합니다. 이러한 콘텐츠 편집 가능 영역은 콘텐츠 내에서 볼 수 있는 ContentPlaceHolder 컨트롤로 <div>
표시됩니다. 마스터 페이지에는 단일 ContentPlaceHolder(MainContent
)가 있지만 마스터 페이지에는 여러 ContentPlaceHolders가 있을 수 있습니다.
위에 태그를 입력하면 디자인 보기로 전환하면 마스터 페이지의 레이아웃이 표시됩니다. 이 마스터 페이지를 사용하는 모든 ASP.NET 페이지는 지역에 대한 마크업을 지정할 수 있는 일관된 레이아웃을 갖게 됩니다.
그림 4: 마스터 페이지, 디자인 보기를 통해 볼 때(전체 크기 이미지를 보려면 클릭)
2단계: 웹 사이트에 홈페이지 추가
마스터 페이지가 정의되면 웹 사이트의 ASP.NET 페이지를 추가할 준비가 된 것입니다. 먼저 우리 웹사이트의 홈페이지인 Default.aspx
를 추가해 봅시다. 솔루션 탐색기에서 프로젝트 이름을 마우스 오른쪽 단추로 클릭하고 새 항목 추가를 선택합니다. 템플릿 목록에서 웹 양식 옵션을 선택하고 파일 Default.aspx
이름을 지정합니다. 또한 "마스터 페이지 선택" 확인란을 선택합니다.
그림 5: 새 웹 양식 추가, 마스터 선택 페이지 확인란 확인란(전체 크기 이미지를 보려면 클릭)
확인 단추를 클릭하면 이 새 ASP.NET 페이지에서 사용해야 하는 마스터 페이지를 선택하라는 메시지가 표시됩니다. 프로젝트에 여러 마스터 페이지가 있을 수 있지만 하나만 있습니다.
그림 6: 이 ASP.NET 페이지에서 사용해야 하는 마스터 페이지 선택(전체 크기 이미지를 보려면 클릭)
마스터 페이지를 선택하면 새 ASP.NET 페이지에 다음 태그가 포함됩니다.
Default.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent"
Runat="Server">
</asp:Content>
@Page
지시문에는 사용된 마스터 페이지 파일(MasterPageFile="~/Site.master"
)에 대한 참조가 있으며, ASP.NET 페이지의 태그에는 마스터 페이지에 정의된 각 ContentPlaceHolder 컨트롤에 대한 콘텐츠 컨트롤이 포함되어 있으며, 컨트롤은 ContentPlaceHolderID
콘텐츠 컨트롤을 특정 ContentPlaceHolder에 매핑합니다. 콘텐츠 컨트롤은 해당 ContentPlaceHolder에 표시할 태그를 배치하는 위치입니다.
@Page
지시문의 Title
특성을 홈으로 설정하고 일부 환영 콘텐츠를 콘텐츠 컨트롤에 추가합니다.
Default.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" Title="Home" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent"
Runat="Server">
<h1>Welcome to the Working with Data Tutorial Site</h1>
<p>This site is being built as part of a set of tutorials that
illustrate some of the new data access and databinding features in
ASP.NET 2.0 and Visual Web Developer.</p>
<p>Over time, it will include a host of samples that
demonstrate:</p>
<ul>
<li>Building a DAL (data access layer),</li>
<li>Using strongly typed TableAdapters and DataTables</li>
<li>Master-Detail reports</li>
<li>Filtering</li>
<li>Paging,</li>
<li>Two-way databinding,</li>
<li>Editing,</li>
<li>Deleting,</li>
<li>Inserting,</li>
<li>Hierarchical data browsing,</li>
<li>Hierarchical drill-down,</li>
<li>Optimistic concurrency,</li>
<li>And more!</li>
</ul>
</asp:Content>
Title
지시문의 @Page
특성을 사용하면 요소가 마스터 페이지에 정의되어 있더라도 <title>
ASP.NET 페이지에서 페이지의 제목을 설정할 수 있습니다. 을 사용하여 Page.Title
프로그래밍 방식으로 제목을 설정할 수도 있습니다. 또한 마스터 페이지의 스타일시트 참조(예: Style.css
)는 마스터 페이지를 기준으로 ASP.NET 페이지의 디렉터리에 관계없이 모든 ASP.NET 페이지에서 작동하도록 자동으로 업데이트됩니다.
디자인 보기로 전환하면 브라우저에서 페이지가 어떻게 표시되는지 확인할 수 있습니다. 편집 가능한 콘텐츠 영역만 편집할 수 있는 ASP.NET 페이지의 디자인 보기에서 마스터 페이지에 정의된 비 ContentPlaceHolder 태그가 회색으로 표시됩니다.
그림 7: ASP.NET 페이지의 디자인 보기에 편집 가능한 영역과 편집할 수 없는 영역이 모두 표시됩니다(전체 크기 이미지를 보려면 클릭).
브라우저에서 Default.aspx
페이지를 방문하면, ASP.NET 엔진은 페이지의 마스터 페이지 콘텐츠와 ASP.NET 콘텐츠를 자동으로 병합하여 요청한 브라우저로 전송할 최종 HTML로 렌더링합니다. 마스터 페이지의 콘텐츠가 업데이트되면 이 마스터 페이지를 사용하는 모든 ASP.NET 페이지에는 다음에 요청될 때 해당 콘텐츠가 새 마스터 페이지 콘텐츠와 다시 표시됩니다. 즉, 마스터 페이지 모델을 사용하면 전체 사이트에 변경 내용이 즉시 반영되는 단일 페이지 레이아웃 템플릿(마스터 페이지)을 정의할 수 있습니다.
웹 사이트에 추가 ASP.NET 페이지 추가
잠시 시간을 내어 다양한 보고 데모를 보관할 사이트에 ASP.NET 페이지 스텁을 추가해 보겠습니다. 총 35개 이상의 데모가 있으므로 모든 스텁 페이지를 만드는 대신 처음 몇 가지를 만들어 보겠습니다. 데모에는 여러 범주가 있으므로 데모를 더 잘 관리하려면 범주에 대한 폴더를 추가합니다. 지금은 다음 세 개의 폴더를 추가합니다.
BasicReporting
Filtering
CustomFormatting
마지막으로 그림 8의 솔루션 탐색기에 표시된 대로 새 파일을 추가합니다. 각 파일을 추가할 때는 "마스터 페이지 선택" 확인란을 선택해야 합니다.
그림 8: 다음 파일 추가
2단계: 사이트 맵 만들기
소수의 페이지로 구성된 웹 사이트를 관리하는 문제 중 하나는 방문자가 사이트를 탐색할 수 있는 간단한 방법을 제공하는 것입니다. 먼저 사이트의 탐색 구조를 정의해야 합니다. 다음으로, 이 구조는 메뉴 또는 이동 경로와 같은 탐색 가능한 사용자 인터페이스 요소로 변환되어야 합니다. 마지막으로 새 페이지가 사이트에 추가되고 기존 페이지가 제거됨에 따라 이 전체 프로세스를 유지 관리하고 업데이트해야 합니다. ASP.NET 2.0 이전에는 개발자가 사이트의 탐색 구조를 만들고 유지 관리하며 탐색 가능한 사용자 인터페이스 요소로 변환하는 작업을 직접 진행했습니다. 그러나 ASP.NET 2.0을 사용하면 개발자는 매우 유연한 기본 제공 사이트 탐색 시스템을 활용할 수 있습니다.
ASP.NET 2.0 사이트 탐색 시스템은 개발자가 사이트 맵을 정의한 다음 프로그래밍 방식 API를 통해 이 정보에 액세스할 수 있는 수단을 제공합니다. ASP.NET는 사이트 맵 데이터를 특정 방식으로 형식화된 XML 파일에 저장하는 사이트 맵 공급자를 포함하고 있습니다. 그러나 사이트 탐색 시스템은 공급자 모델을 기반으로 하므로 사이트 맵 정보를 직렬화하는 다른 방법을 지원하도록 확장할 수 있습니다. Jeff Prosise의 문서인 대기 중인 SQL 사이트 맵 공급자는 사이트 맵 을 SQL Server 데이터베이스에 저장하는 사이트 맵 공급자를 만드는 방법을 보여 줍니다. 또 다른 옵션은 파일 시스템 구조에 따라 사이트 맵 공급자를 만드는 것입니다.
그러나 이 자습서에서는 ASP.NET 2.0과 함께 제공되는 기본 사이트 맵 공급자를 사용하겠습니다. 사이트 맵을 만들려면 솔루션 탐색기에서 프로젝트 이름을 마우스 오른쪽 단추로 클릭하고 새 항목 추가를 선택한 다음 사이트 맵 옵션을 선택합니다. 이름을 그대로 Web.sitemap
두고 추가 단추를 클릭합니다.
그림 9: 프로젝트에 사이트 맵 추가(전체 크기 이미지를 보려면 클릭)
사이트 맵 파일은 XML 파일입니다. Visual Studio는 사이트 맵 구조에 대한 IntelliSense를 제공합니다. 사이트 맵 파일에는 노드가 <siteMap>
루트 노드여야 하며, 이 노드에는 정확히 하나의 <siteMapNode>
자식 요소가 포함되어야 합니다. 그런 다음 첫 번째 <siteMapNode>
요소에는 임의의 수의 하위 <siteMapNode>
요소가 포함될 수 있습니다.
파일 시스템 구조를 모방하도록 사이트 맵을 정의합니다. 즉, 세 폴더 각각에 대한 <siteMapNode>
요소를 추가하고, 해당 폴더의 각 ASP.NET 페이지에 대한 자식 <siteMapNode>
요소를 다음과 같이 추가합니다.
Web.sitemap
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="~/Default.aspx" title="Home" description="Home">
<siteMapNode title="Basic Reporting"
url="~/BasicReporting/Default.aspx"
description="Basic Reporting Samples">
<siteMapNode url="~/BasicReporting/SimpleDisplay.aspx"
title="Simple Display"
description="Displays the complete contents
of a database table." />
<siteMapNode url="~/BasicReporting/DeclarativeParams.aspx"
title="Declarative Parameters"
description="Displays a subset of the contents
of a database table using parameters." />
<siteMapNode url="~/BasicReporting/ProgrammaticParams.aspx"
title="Setting Parameter Values"
description="Shows how to set parameter values
programmatically." />
</siteMapNode>
<siteMapNode title="Filtering Reports"
url="~/Filtering/Default.aspx"
description="Samples of Reports that Support Filtering">
<siteMapNode url="~/Filtering/FilterByDropDownList.aspx"
title="Filter by Drop-Down List"
description="Filter results using a drop-down list." />
<siteMapNode url="~/Filtering/MasterDetailsDetails.aspx"
title="Master-Details-Details"
description="Filter results two levels down." />
<siteMapNode url="~/Filtering/DetailsBySelecting.aspx"
title="Details of Selected Row"
description="Show detail results for a selected item in a GridView." />
</siteMapNode>
<siteMapNode title="Customized Formatting"
url="~/CustomFormatting/Default.aspx"
description="Samples of Reports Whose Formats are Customized">
<siteMapNode url="~/CustomFormatting/CustomColors.aspx"
title="Format Colors"
description="Format the grid s colors based
on the underlying data." />
<siteMapNode
url="~/CustomFormatting/GridViewTemplateField.aspx"
title="Custom Content in a GridView"
description="Shows using the TemplateField to
customize the contents of a field in a GridView." />
<siteMapNode
url="~/CustomFormatting/DetailsViewTemplateField.aspx"
title="Custom Content in a DetailsView"
description="Shows using the TemplateField to customize
the contents of a field in a DetailsView." />
<siteMapNode url="~/CustomFormatting/FormView.aspx"
title="Custom Content in a FormView"
description="Illustrates using a FormView for a
highly customized view." />
<siteMapNode url="~/CustomFormatting/SummaryDataInFooter.aspx"
title="Summary Data in Footer"
description="Display summary data in the grids footer." />
</siteMapNode>
</siteMapNode>
</siteMap>
사이트 맵은 사이트의 다양한 섹션을 설명하는 계층 구조인 웹 사이트의 탐색 구조를 정의합니다. 각 <siteMapNode>
Web.sitemap
요소는 사이트의 탐색 구조에 있는 섹션을 나타냅니다.
그림 10: 사이트 맵이 계층적 탐색 구조를 나타냅니다(전체 크기 이미지를 보려면 클릭).
ASP.NET .NET Framework의 SiteMap 클래스를 통해 사이트 맵의 구조를 노출합니다. 이 클래스에는 CurrentNode
사용자가 현재 방문 중인 섹션에 대한 정보를 반환하는 RootNode
속성이 있습니다. 이 속성은 사이트 맵의 루트를 반환합니다(홈, 사이트 맵에서).
CurrentNode
및 RootNode
속성 모두에는 사이트 맵 계층 구조를 탐색할 수 있도록 하는 , ParentNode
, ChildNodes
, NextSibling
등의 속성을 가진 PreviousSibling
인스턴스를 반환합니다.
3단계: 사이트 맵을 기반으로 메뉴 표시
ASP.NET 2.0의 데이터에 액세스하는 작업은 ASP.NET 1.x처럼 프로그래밍 방식으로 또는 새 데이터 원본 컨트롤을 통해 선언적으로 수행할 수 있습니다. 관계형 데이터베이스 데이터에 액세스하기 위한 SqlDataSource 컨트롤, ObjectDataSource 컨트롤, 클래스 등의 데이터에 액세스하기 위한 SqlDataSource 컨트롤과 같은 몇 가지 기본 제공 데이터 원본 컨트롤이 있습니다. 사용자 고유의 사용자 지정 데이터 원본 컨트롤을 만들 수도 있습니다.
데이터 원본 컨트롤은 ASP.NET 페이지와 기본 데이터 간의 프록시 역할을 합니다. 데이터 원본 컨트롤의 검색된 데이터를 표시하기 위해 일반적으로 페이지에 다른 웹 컨트롤을 추가하고 데이터 원본 컨트롤에 바인딩합니다. 웹 컨트롤을 데이터 원본 컨트롤에 바인딩하려면 웹 컨트롤의 DataSourceID
속성을 데이터 원본 컨트롤 ID
의 속성 값으로 설정하기만 하면 됩니다.
사이트 맵의 데이터 작업을 지원하기 위해 ASP.NET 웹 사이트의 사이트 맵에 웹 컨트롤을 바인딩할 수 있는 SiteMapDataSource 컨트롤을 포함합니다. TreeView 및 메뉴의 두 웹 컨트롤은 일반적으로 탐색 사용자 인터페이스를 제공하는 데 사용됩니다. 사이트 맵 데이터를 이러한 두 컨트롤 중 하나에 바인딩하려면 속성이 적절하게 설정된 TreeView 또는 Menu 컨트롤과 함께 SiteMapDataSource를 DataSourceID
페이지에 추가하면 됩니다. 예를 들어 다음 태그를 사용하여 마스터 페이지에 메뉴 컨트롤을 추가할 수 있습니다.
<div id="navigation">
<asp:Menu ID="Menu1" runat="server"
DataSourceID="SiteMapDataSource1">
</asp:Menu>
<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" />
</div>
내보내는 HTML을 보다 세부적으로 제어하기 위해 다음과 같이 SiteMapDataSource 컨트롤을 반복기 컨트롤에 바인딩할 수 있습니다.
<div id="navigation">
<ul>
<li><asp:HyperLink runat="server" ID="lnkHome"
NavigateUrl="~/Default.aspx">Home</asp:HyperLink></li>
<asp:Repeater runat="server" ID="menu"
DataSourceID="SiteMapDataSource1">
<ItemTemplate>
<li>
<asp:HyperLink runat="server"
NavigateUrl='<%# Eval("Url") %>'>
<%# Eval("Title") %></asp:HyperLink>
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
<asp:SiteMapDataSource ID="SiteMapDataSource1"
runat="server" ShowStartingNode="false" />
</div>
SiteMapDataSource 컨트롤은 루트 사이트 맵 노드(홈, 사이트 맵), 다음 수준(기본 보고, 필터링 보고서 및 사용자 지정된 서식) 등으로 시작하여 한 번에 한 수준씩 사이트 맵 계층 구조를 반환합니다. SiteMapDataSource를 Repeater에 바인딩할 때, 반환된 첫 번째 수준의 각 ItemTemplate
인스턴스를 열거하고 SiteMapNode
을(를) 인스턴스화합니다. 특정 SiteMapNode
의 속성에 접근하기 위해, 우리는 Eval(propertyName)
을 사용하여 HyperLink 컨트롤의 각 SiteMapNode
의 Url
및 Title
속성을 가져올 수 있습니다.
위의 반복기 예제는 다음 마크업을 렌더링합니다.
<li>
<a href="/Code/BasicReporting/Default.aspx">Basic Reporting</a>
</li>
<li>
<a href="/Code/Filtering/Default.aspx">Filtering Reports</a>
</li>
<li>
<a href="/Code/CustomFormatting/Default.aspx">
Customized Formatting</a>
</li>
이러한 사이트 맵 노드(기본 보고, 필터링 보고서 및 사용자 지정된 서식 지정)는 첫 번째가 아니라 렌더링되는 사이트 맵의 두 번째 수준으로 구성됩니다. SiteMapDataSource의 ShowStartingNode
속성이 False로 설정되어 SiteMapDataSource가 루트 사이트 맵 노드를 우회하고 대신 사이트 맵 계층 구조의 두 번째 수준을 반환하여 시작하기 때문입니다.
기본 보고, 필터링 보고서 및 사용자 지정된 서식 SiteMapNode
에 대한 자식을 표시하려면 초기 반복기 ItemTemplate
에서 다른 반복기를 추가할 수 있습니다. 다음과 같이 이 두 번째 반복기는 SiteMapNode
인스턴스의 ChildNodes
속성에 바인딩됩니다.
<asp:Repeater runat="server" ID="menu" DataSourceID="SiteMapDataSource1">
<ItemTemplate>
<li>
<asp:HyperLink runat="server"
NavigateUrl='<%# Eval("Url") %>'>
<%# Eval("Title") %></asp:HyperLink>
<asp:Repeater runat="server"
DataSource='<%# ((SiteMapNode) Container.DataItem).ChildNodes %>'>
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>
<asp:HyperLink runat="server"
NavigateUrl='<%# Eval("Url") %>'>
<%# Eval("Title") %></asp:HyperLink>
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
</li>
</ItemTemplate>
</asp:Repeater>
이 두 반복기는 다음과 같은 태그를 생성합니다(간결성을 위해 일부 태그가 제거됨).
<li>
<a href="/Code/BasicReporting/Default.aspx">Basic Reporting</a>
<ul>
<li>
<a href="/Code/BasicReporting/SimpleDisplay.aspx">
Simple Display</a>
</li>
<li>
<a href="/Code/BasicReporting/DeclarativeParams.aspx">
Declarative Parameters</a>
</li>
<li>
<a href="/Code/BasicReporting/ProgrammaticParams.aspx">
Setting Parameter Values</a>
</li>
</ul>
</li>
<li>
<a href="/Code/Filtering/Default.aspx">Filtering Reports</a>
...
</li>
<li>
<a href="/Code/CustomFormatting/Default.aspx">
Customized Formatting</a>
...
</li>
그림 11: 두 개의 리피터와 일부 CSS로 구성된 메뉴
이 메뉴는 마스터 페이지에 있으며 정의된 사이트 맵에 Web.sitemap
바인딩됩니다. 즉, 사이트 맵에 대한 변경 내용은 마스터 페이지를 사용하는 Site.master
모든 페이지에 즉시 반영됩니다.
ViewState 사용 안 림
모든 ASP.NET 컨트롤은 필요에 따라 해당 상태를 뷰 상태로 유지할 수 있으며 렌더링된 HTML에서 숨겨진 양식 필드로 직렬화됩니다. 뷰 상태는 데이터 웹 컨트롤에 바인딩된 데이터와 같은 포스트백에서 프로그래밍 방식으로 변경된 상태를 기억하기 위해 컨트롤에서 사용됩니다. 뷰 상태는 포스트백에서 정보를 기억할 수 있도록 허용하지만, 클라이언트로 전송해야 하는 태그의 크기를 증가시키고 면밀히 모니터링하지 않으면 페이지가 심하게 부풀어 오를 수 있습니다. 데이터 웹 컨트롤, 특히 GridView는 페이지에 수십 킬로바이트 이상의 태그를 추가하는 것으로 특히 악명이 높습니다. 이러한 증가는 광대역 또는 인트라넷 사용자에게는 무시할 수 있지만, 보기 상태는 전화 접속 사용자의 왕복 시간에 몇 초를 더할 수 있습니다.
보기 상태의 영향을 보려면 브라우저에서 페이지를 방문한 다음 웹 페이지에서 보낸 원본을 봅니다(Internet Explorer에서 보기 메뉴로 이동하여 원본 옵션을 선택).
페이지 추적을 켜면 페이지의 각 컨트롤에서 사용하는 뷰 상태 할당을 확인할 수도 있습니다. 뷰 상태 정보는 __VIEWSTATE
태그 바로 다음 <div>
요소에 위치한 <form>
이름의 숨겨진 양식 필드에서 직렬화됩니다. 뷰 상태는 웹 양식이 사용 중인 경우에만 유지됩니다. ASP.NET 페이지의 선언적 구문에 <form runat="server">
이 포함되어 있지 않으면, 렌더링된 태그에 숨겨진 양식 필드 __VIEWSTATE
이 없습니다.
__VIEWSTATE
마스터 페이지에서 생성된 양식 필드는 페이지의 생성된 태그에 약 1,800바이트를 추가합니다. 사이트맵 데이터 소스 컨트롤의 내용이 뷰 상태에 저장되기 때문에, 이 추가적인 부하는 주로 반복기 컨트롤에서 발생합니다. 1,800바이트의 추가가 크게 중요하지 않아 보일 수 있지만, 많은 필드와 레코드가 있는 GridView를 사용할 때 보기 상태는 쉽게 10배 이상 팽창할 수 있습니다.
뷰 상태는 페이지 또는 컨트롤 수준에서 속성 EnableViewState
를 false
로 설정하여 렌더링된 마크업의 크기를 줄임으로써 비활성화할 수 있습니다. 데이터 웹 컨트롤의 뷰 상태는 포스트백에서 데이터 웹 컨트롤에 바인딩된 데이터를 유지하므로 데이터 웹 컨트롤에 대한 뷰 상태를 사용하지 않도록 설정하면 데이터가 각 포스트백에 바인딩되어야 합니다. ASP.NET 버전 1.x에서 이 책임은 페이지 개발자의 어깨에 떨어졌습니다. 그러나 ASP.NET 2.0을 사용하면 필요한 경우 데이터 웹 컨트롤이 각 포스트백의 데이터 원본 제어에 다시 바인딩됩니다.
페이지의 보기 상태를 줄이려면 Repeater 컨트롤의 EnableViewState
속성을 false
.로 설정해 보겠습니다. 이 작업은 디자이너의 속성 창을 통해 수행하거나 원본 보기에서 선언적으로 수행할 수 있습니다. 이렇게 변경한 후에는 Repeater의 선언적 태그가 다음과 같이 표시됩니다.
<asp:Repeater runat="server" ID="menu" DataSourceID="SiteMapDataSource1"
EnableViewState="False">
<ItemTemplate>
... <i>ItemTemplate contents omitted for brevity</i> ...
</ItemTemplate>
</asp:Repeater>
이 변경 후 페이지의 렌더링된 뷰 상태 크기가 52바이트로 축소되어 보기 상태 크기가 97% 절감되었습니다. 이 시리즈의 자습서에서는 렌더링된 태그의 크기를 줄이기 위해 기본적으로 데이터 웹 컨트롤의 뷰 상태를 사용하지 않도록 설정합니다. 대부분의 예제에서 EnableViewState
속성은 언급 없이 false
로 설정됩니다. 유일한 시간 보기 상태는 데이터 웹 컨트롤이 예상된 기능을 제공하려면 사용하도록 설정해야 하는 시나리오에서 설명합니다.
4단계: 브레드크럼 내비게이션 추가
마스터 페이지를 완료하려면 각 페이지에 탐색 경로 UI 요소를 추가하겠습니다. 경로 표시기는 사이트 계층 구조 내에서 사용자의 현재 위치를 빠르게 보여줍니다. ASP.NET 2.0에서 이동 경로를 추가하는 것은 페이지에 SiteMapPath 컨트롤을 쉽게 추가할 수 있습니다. 코드가 필요하지 않습니다.
사이트의 경우 헤더 <div>
에 다음 컨트롤을 추가합니다.
<span class="breadcrumb">
<asp:SiteMapPath ID="SiteMapPath1" runat="server">
</asp:SiteMapPath>
</span>
사이트의 경로 표시기는 사용자가 사이트 맵 계층 구조 내에서 방문 중인 현재 페이지와 해당 사이트 맵 노드의 모든 "상위" 항목을 루트(홈페이지, 사이트 맵에서)까지 보여줍니다.
그림 12: 사이트 맵 계층 구조에서 현재 페이지와 그 상위 페이지를 표시하는 브레드크럼ب 항목
5단계: 각 섹션의 기본 페이지 추가
이 사이트의 자습서는 각 범주에 대한 폴더와 해당 폴더 내의 ASP.NET 페이지로 제공되는 기본 보고, 필터링, 사용자 지정 서식 등의 다양한 범주로 구분됩니다. 또한 각 폴더에는 페이지가 Default.aspx
포함됩니다. 이 기본 페이지의 경우 현재 섹션에 대한 모든 자습서를 표시해 보겠습니다. 즉, Default.aspx
폴더 내의 BasicReporting
에 대해 우리는 SimpleDisplay.aspx
, DeclarativeParams.aspx
, 및 ProgrammaticParams.aspx
로의 링크를 제공합니다. 여기에서는 SiteMap
클래스와 데이터 웹 컨트롤을 사용하여 Web.sitemap
에 정의된 사이트 맵을 기반으로 이 정보를 표시할 수 있습니다.
반복기를 사용하여 순서가 지정되지 않은 목록을 다시 표시해 보겠습니다. 이번에는 자습서의 제목과 설명을 표시합니다. 이를 수행하기 위한 태그와 코드는 각 Default.aspx
페이지에 대해 반복되어야 하므로 사용자 정의 컨트롤에서 이 UI 논리를 캡슐화할 수 있습니다. 웹 사이트에 UserControls
라는 폴더를 만들고, 웹 사용자 정의 컨트롤 형식의 새 항목 SectionLevelTutorialListing.ascx
을 그 폴더에 추가한 다음, 다음 태그를 추가합니다.
그림 13: 폴더에 UserControls
새 웹 사용자 컨트롤 추가(전체 크기 이미지를 보려면 클릭)
SectionLevelTutorialListing.ascx
<%@ Control Language="CS" AutoEventWireup="true"
CodeFile="SectionLevelTutorialListing.ascx.cs"
Inherits="UserControls_SectionLevelTutorialListing" %>
<asp:Repeater ID="TutorialList" runat="server" EnableViewState="False">
<HeaderTemplate><ul></HeaderTemplate>
<ItemTemplate>
<li><asp:HyperLink runat="server"
NavigateUrl='<%# Eval("Url") %>'
Text='<%# Eval("Title") %>'></asp:HyperLink>
- <%# Eval("Description") %></li>
</ItemTemplate>
<FooterTemplate></ul></FooterTemplate>
</asp:Repeater>
SectionLevelTutorialListing.ascx.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class UserControls_SectionLevelTutorialListing : UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
// If SiteMap.CurrentNode is not null,
// bind CurrentNode ChildNodes to the GridView
if (SiteMap.CurrentNode != null)
{
TutorialList.DataSource = SiteMap.CurrentNode.ChildNodes;
TutorialList.DataBind();
}
}
}
이전 Repeater 예제에서는 SiteMap
데이터를 선언적으로 Repeater에 바인딩했습니다. 그러나 SectionLevelTutorialListing
사용자 컨트롤은 프로그래밍 방식으로 이 작업을 수행합니다.
Page_Load
이벤트 처리기에서 이 페이지의 URL이 사이트 맵의 노드에 매핑되는지 확인합니다. 해당 <siteMapNode>
항목이 없는 페이지에서 이 사용자 컨트롤을 사용하는 경우, SiteMap.CurrentNode
가 반환되며 데이터는 Repeater에 바인딩되지 않습니다. 컬렉션이 존재한다고 CurrentNode
가정했을 때, 해당 ChildNodes
컬렉션을 Repeater에 바인딩합니다. 각 섹션의 Default.aspx
페이지가 해당 섹션 내의 모든 자습서의 부모 노드가 되도록 사이트 맵이 설정되었으므로 이 코드는 아래 스크린샷과 같이 섹션의 모든 자습서에 대한 링크와 설명을 표시합니다.
이 반복기가 만들어지면 각 폴더의 페이지를 열고 Default.aspx
디자인 보기로 이동한 후 솔루션 탐색기에서 자습서 목록을 표시할 디자인 화면으로 사용자 컨트롤을 끌어 놓기만 하면 됩니다.
그림 14: 사용자 정의 컨트롤이 추가 Default.aspx
되었습니다(전체 크기 이미지를 보려면 클릭).
그림 15: 기본 보고 자습서가 나열됩니다(전체 크기 이미지를 보려면 클릭).
요약
사이트 맵이 정의되고 마스터 페이지가 완료되면 이제 데이터 관련 자습서에 대한 일관된 페이지 레이아웃 및 탐색 체계가 제공됩니다. 사이트에 추가하는 페이지 수에 관계없이 사이트 전체 페이지 레이아웃 또는 사이트 탐색 정보를 업데이트하는 것은 이 정보가 중앙 집중화되기 때문에 빠르고 간단한 프로세스입니다. 특히 페이지 레이아웃 정보는 마스터 페이지 Site.master
와 사이트 맵에서 정의됩니다 Web.sitemap
. 사이트 전체의 페이지 레이아웃과 탐색 메커니즘을 구현하기 위해 코드를 작성할 필요가 없었으며, Visual Studio에서 WYSIWYG 디자이너 지원을 완전히 유지하고 있습니다.
데이터 액세스 계층 및 비즈니스 논리 계층을 완료하고 일관된 페이지 레이아웃 및 사이트 탐색을 정의했으므로 일반적인 보고 패턴을 탐색할 준비가 완료되었습니다. 다음 세 자습서에서는 GridView, DetailsView 및 FormView 컨트롤의 BLL에서 검색된 데이터를 표시하는 기본 보고 작업을 살펴보겠습니다.
행복한 프로그래밍!
추가 읽기
이 자습서에서 설명하는 항목에 대한 자세한 내용은 다음 리소스를 참조하세요.
- ASP.NET 마스터 페이지 개요
- ASP.NET 2.0의 마스터 페이지
- ASP.NET 2.0 디자인 템플릿
- ASP.NET 사이트 탐색 개요
- ASP.NET 2.0의 사이트 탐색 검사
- ASP.NET 2.0 사이트 탐색 기능
- ASP.NET 보기 상태 이해
- 방법: ASP.NET 페이지에 추적 기능 활성화
- ASP.NET 사용자 컨트롤
작성자 정보
7개의 ASP/ASP.NET 책의 저자이자 4GuysFromRolla.com 창립자인 Scott Mitchell은 1998년부터 Microsoft 웹 기술을 연구해 왔습니다. Scott은 독립 컨설턴트, 트레이너 및 작가로 일합니다. 그의 최신 책은 Sams Teach Yourself ASP.NET 2.0 in 24 Hours입니다. 그에게 mitchell@4GuysFromRolla.com으로 연락할 수 있습니다.
특별히 감사드립니다.
이 자습서 시리즈는 많은 유용한 검토자가 검토했습니다. 이 자습서의 수석 검토자는 Liz Shulok, Dennis Patterson 및 Hilton Giesenow였습니다. 예정된 MSDN 문서를 검토하는 데 관심이 있으신가요? 그렇다면 mitchell@4GuysFromRolla.com으로 메시지를 보내 주세요.