Share via


연습: 사용자 지정 서버 컨트롤 개발 및 사용

업데이트: 2007년 11월

이 연습에서는 사용자 지정 ASP.NET 서버 컨트롤을 만들어 컴파일하고 페이지에서 사용하는 방법을 보여 줍니다.

이 연습을 통해 다음과 같은 작업을 수행하는 방법을 배웁니다.

  • ASP.NET 서버 컨트롤 만들기

  • 컨트롤과 관련 멤버에 메타데이터를 추가하여 보안 및 디자인 타임 동작 제어

  • ASP.NET 웹 사이트에서 App_Code 디렉터리를 사용하여 수동 컴파일 단계 없이 컨트롤 테스트

  • 구성 파일 및 컨트롤의 어셈블리에 태그 접두사 지정

  • 컨트롤을 어셈블리로 컴파일하여 Bin 디렉터리에 추가

  • 비트맵을 비주얼 디자이너의 도구 상자 아이콘으로 컨트롤 어셈블리에 포함

  • 컴파일된 컨트롤을 페이지에 사용

Microsoft Visual Studio 2005 같은 비주얼 디자인 도구는 컨트롤 개발 과정을 간소화하지만 사용자 지정 컨트롤을 만들거나 빌드하는 데 반드시 필요하지는 않습니다. 모든 텍스트 편집기를 사용하여 컨트롤을 만들어 Windows SDK(소프트웨어 개발 키트)에 포함된 컴파일러로 명령줄에서 빌드할 수 있습니다. 컨트롤을 만든 방법에 관계없이 비주얼 디자이너에서 디자인 타임에 나타나는 컨트롤의 모양과 동작은 항상 같습니다. 페이지 개발자는 컨트롤을 비주얼 디자이너의 도구 상자에 추가하여 디자인 화면에 끌어 오고 속성 브라우저에서 컨트롤의 속성 및 이벤트에 액세스할 수 있습니다. Visual Studio 2005 같은 일부 비주얼 디자이너의 경우 별도의 작업을 수행하지 않고 사용자 지정 컨트롤에서 IntelliSense 기능을 사용할 수 있습니다.

서버 컨트롤 만들기

이 예제를 통해 만들 WelcomeLabel 컨트롤은 표준 Label 컨트롤과 비슷한 간단한 컨트롤입니다. WelcomeLabel 클래스는 WebControl에서 파생되고, 페이지 개발자가 사이트를 방문하는 사용자에게 표시할 텍스트 문자열을 제공하는 데 사용할 수 있는 Text 속성을 정의합니다. WelcomeLabel은 사용자의 브라우저에서 보낸 머리글에 사용자 이름이 있는 경우 이 텍스트 문자열에 사용자 이름을 추가합니다. 사용자 이름을 가져오는 데 대한 자세한 내용은 User를 참조하십시오. 예를 들어 페이지 개발자가 Text 속성 값을 "Hello"로 설정하면 머리글에 사용자 이름이 있는지 여부에 따라 WelcomeLabel에 "Hello, userName!" 또는 "Hello!"가 렌더링됩니다.

사용자 지정 서버 컨트롤에 대한 코드를 만들려면

  1. WelcomeLabel.cs 또는 WelcomeLabel.vb라는 파일을 만듭니다.

  2. 컨트롤의 소스 파일에 다음 코드를 추가합니다.

    ' WelcomeLabel.vb
    Option Strict On
    Imports System
    Imports System.ComponentModel
    Imports System.Security.Permissions
    Imports System.Web
    Imports System.Web.UI
    Imports System.Web.UI.WebControls
    
    Namespace Samples.AspNet.VB.Controls
        < _
        AspNetHostingPermission(SecurityAction.Demand, _
            Level:=AspNetHostingPermissionLevel.Minimal), _
        AspNetHostingPermission(SecurityAction.InheritanceDemand, _
            Level:=AspNetHostingPermissionLevel.Minimal), _
        DefaultProperty("Text"), _
        ToolboxData( _
            "<{0}:WelcomeLabel runat=""server""> </{0}:WelcomeLabel>") _
        > _
        Public Class WelcomeLabel
            Inherits WebControl
            < _
            Bindable(True), _
            Category("Appearance"), _
            DefaultValue(""), _
            Description("The welcome message text."), _
            Localizable(True) _
            > _
            Public Overridable Property Text() As String
                Get
                    Dim s As String = CStr(ViewState("Text"))
                    If s Is Nothing Then s = String.Empty
                    Return s
                End Get
                Set(ByVal value As String)
                    ViewState("Text") = value
                End Set
            End Property
    
            Protected Overrides Sub RenderContents( _
                ByVal writer As HtmlTextWriter)
                writer.WriteEncodedText(Text)
                If Context IsNot Nothing Then
                    Dim s As String = Context.User.Identity.Name
                    If (s IsNot Nothing) AndAlso (s <> String.Empty) Then
                        Dim split() As String = s.Split("\".ToCharArray)
                        Dim n As Integer = split.Length - 1
                        If (split(n) <> String.Empty) Then
                            writer.Write(", ")
                            writer.Write(split(n))
                        End If
                    End If
                End If
                writer.Write("!")
            End Sub
        End Class
    End Namespace
    
    // WelcomeLabel.cs
    using System;
    using System.ComponentModel;
    using System.Security.Permissions;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace Samples.AspNet.CS.Controls
    {
        [
        AspNetHostingPermission(SecurityAction.Demand,
            Level = AspNetHostingPermissionLevel.Minimal),
        AspNetHostingPermission(SecurityAction.InheritanceDemand, 
            Level=AspNetHostingPermissionLevel.Minimal),
        DefaultProperty("Text"),
        ToolboxData("<{0}:WelcomeLabel runat=\"server\"> </{0}:WelcomeLabel>")
        ]
        public class WelcomeLabel : WebControl
        {
            [
            Bindable(true),
            Category("Appearance"),
            DefaultValue(""),
            Description("The welcome message text."),
            Localizable(true)
            ]
            public virtual string Text
            {
                get
                {
                    string s = (string)ViewState["Text"];
                    return (s == null) ? String.Empty : s;
                }
                set
                {
                    ViewState["Text"] = value;
                }
            }
    
            protected override void RenderContents(HtmlTextWriter writer)
            {
                writer.WriteEncodedText(Text);
                if (Context != null)
                {
                    string s = Context.User.Identity.Name;
                    if (s != null && s != String.Empty)
                    {
                        string[] split = s.Split('\\');
                        int n = split.Length - 1;
                        if (split[n] != String.Empty)
                        {
                            writer.Write(", ");
                            writer.Write(split[n]);
                        }
                    }
                }
                writer.Write("!");
            }
        }
    }
    

코드 설명

다음 코드 설명은 이 연습에 나오는 단계를 수행하는 데 반드시 필요한 것은 아니므로 처음에는 건너뛸 수 있습니다. 그러나 컨트롤을 처음 제작하는 경우에는 최소한 이 연습을 완료한 후에라도 코드 설명을 읽는 것이 좋습니다.

컨트롤이 UI(사용자 인터페이스) 요소 또는 클라이언트의 보이는 다른 요소를 렌더링하는 경우 System.Web.UI.WebControls.WebControl이나 파생 클래스에서 컨트롤을 파생시켜야 합니다. 컨트롤이 클라이언트 브라우저에서 보이지 않는 요소(예: 숨겨진 요소 또는 meta 요소)를 렌더링할 경우에는 System.Web.UI.Control에서 컨트롤을 파생시킵니다. WebControl 클래스는 Control에서 파생되고 Font, ForeColorBackColor 같은 스타일 관련 속성을 추가합니다. 또한 WebControl에서 파생되는 컨트롤은 별도의 추가 작업 없이도 ASP.NET의 테마 기능에 참여합니다.

Button, Label 또는 Image 컨트롤 같은 기존 컨트롤의 기능을 확장하는 컨트롤은 해당하는 기존 컨트롤에서 파생시킬 수 있습니다. WelcomeLabel은 Label 컨트롤의 기능을 확장하므로 Label에서 파생될 수 있습니다. 그러나 이 연습에서는 WebControl에서 WelcomeLabel을 파생시켜 속성과 속성 메타데이터를 정의하는 방법을 보여 줍니다.

WelcomeLabel은 Text 속성 하나만 정의하고 뷰 상태를 사용하여 속성 값을 저장합니다. 뷰 상태를 사용하면 다시 게시할 때마다 Text 값이 유지됩니다. 다시 게시가 수행될 때마다 페이지가 다시 만들어지고 뷰 상태에서 값이 복원됩니다. Text 값이 뷰 상태에 저장되지 않은 경우에는 다시 게시할 때마다 속성 값이 기본값 Empty로 설정됩니다. WebControl에서 상속된 ViewState 속성은 데이터 값을 저장하는 사전입니다. String 키를 사용하여 값을 입력하고 검색합니다. 이 경우 "Text"는 키로 사용됩니다. 사전의 항목은 먼저 Object로 형식화되고 나중에 이 형식을 속성 형식으로 캐스팅해야 합니다. 자세한 내용은 ASP.NET 상태 관리 개요를 참조하십시오.

WelcomeLabel 컨트롤은 상속된 RenderContents 메서드를 재정의하여 Text 속성을 렌더링합니다. RenderContents 메서드에 전달된 매개 변수는 HtmlTextWriter 형식의 개체이며 이 개체는 태그와 기타 HTML 및 HTML 변형 태그를 렌더링하는 메서드가 포함된 유틸리티 클래스입니다.

WelcomeLabel은 문자열 연결을 수행한 다음 Write 메서드를 호출하는 대신 HtmlTextWriter 개체의 Write 메서드를 연속해서 호출합니다. 이렇게 하면 HtmlTextWriter 개체가 출력 스트림에 직접 기록하므로 성능이 향상됩니다. 문자열을 연결하려면 문자열을 만드는 데 시간과 메모리가 필요하고 그 다음에 스트림에 기록됩니다. 컨트롤에서 렌더링을 구현하는 경우 이 연습에서 설명한 패턴을 따르십시오.

참고:

일반적으로 컨트롤이 WebControl에서 파생되고 단일 요소를 렌더링하는 경우 Render 메서드가 아니라 RenderContents 메서드를 재정의하여 컨트롤 태그의 내용을 렌더링해야 합니다. WebControlRender 메서드는 컨트롤의 여는 태그와 스타일 특성을 렌더링한 후 RenderContents를 호출합니다. Render 메서드를 재정의하여 내용을 작성하면 WebControlRender 메서드에 기본으로 제공된 스타일 렌더링 논리가 컨트롤에서 없어집니다. WebControl에서 파생되는 컨트롤을 렌더링하는 데 대한 자세한 내용은 웹 컨트롤 렌더링 예제를 참조하십시오.

WelcomeLabel에 적용되는 특성은 공용 언어 런타임과 디자인 타임 도구에서 사용하는 메타데이터를 포함합니다.

클래스 수준에서 WelcomeLabel은 다음과 같은 특성으로 표시되어 있습니다.

  • AspNetHostingPermissionAttribute는 코드 액세스 보안 특성입니다. 이 특성을 사용하면 JIT 컴파일러에서는 WelcomeLabel에 연결되는 코드에 AspNetHostingPermission 권한이 부여되어 있는지 검사합니다. ASP.NET의 모든 공용 클래스는 이 특성으로 표시됩니다. 부분적으로 신뢰할 수 있는 호출자에 대한 보안 검사를 위해 AspNetHostingPermissionAttribute를 컨트롤에 적용해야 합니다.

  • DefaultPropertyAttribute는 컨트롤의 기본 속성을 지정하는 디자인 타임 특성입니다. 비주얼 디자이너의 속성 브라우저에서는 일반적으로 페이지 개발자가 디자인 화면의 컨트롤을 클릭하면 기본 속성이 강조 표시됩니다.

  • ToolboxDataAttribute는 요소의 형식 문자열을 지정합니다. 이 문자열은 도구 상자의 컨트롤을 두 번 클릭하거나 디자인 화면으로 끌어 오면 해당 컨트롤의 태그가 됩니다. WelcomeLabel의 경우 이러한 형식 문자열을 통해 다음 요소가 만들어집니다.

    <aspSample:WelcomeLabel > </aspSample:WelcomeLabel>
    

또한 WelcomeLabel 컨트롤은 WebControl 기본 클래스에서 ParseChildrenAttributePersistChildrenAttribute라는 두 개의 특성을 상속 받습니다. 이러한 특성은 ParseChildren(true)과 PersistChildren(false)으로 적용됩니다. 이 두 특성은 상호 작용하거나 ToolboxDataAttribute 특성과 함께 사용되어 자식 요소가 속성으로 해석되거나 속성이 특성으로 유지되도록 합니다.

WelcomeLabel의 Text 속성에 적용되는 다음 특성은 일반적으로 컨트롤의 모든 공용 속성에 적용할 표준 디자인 타임 특성입니다.

  • BindableAttribute는 비주얼 디자이너에 대해 속성을 데이터에 바인딩할 수 있는지 여부를 지정하며 true 또는 false로 설정됩니다. 예를 들어 Visual Studio 2005에서 속성이 Bindable(true)로 표시되어 있으면 이 속성이 DataBindings 대화 상자에 표시됩니다. 그러나 속성이 이 특성으로 표시되어 있지 않으면 속성 브라우저에서는 속성 값을 Bindable(false)로 가정합니다.

  • CategoryAttribute는 비주얼 디자이너의 속성 브라우저에서 속성을 분류하는 방법을 지정합니다. 예를 들어 Category("Appearance") 특성을 설정하면 페이지 개발자가 속성 브라우저에서 범주 보기를 사용하는 경우 속성 브라우저에서 모양 범주에 속성이 표시됩니다. 속성 브라우저에서 기존 범주에 해당하는 문자열 인수를 지정하거나 새 범주를 직접 만들 수 있습니다.

  • DescriptionAttribute는 속성에 대한 간단한 설명을 지정합니다. Visual Studio 2005의 속성 브라우저에서는 선택한 속성에 대한 설명이 속성 창 아래쪽에 표시됩니다.

  • DefaultValueAttribute는 속성의 기본값을 지정합니다. 이 값은 속성 접근자(getter)에서 반환하는 기본값과 같아야 합니다. Visual Studio 2005에서 DefaultValueAttribute를 사용하면 페이지 개발자는 속성 창에서 바로 가기 메뉴를 표시한 다음 다시 설정 단추를 클릭하여 속성 값을 기본값으로 다시 설정할 수 있습니다.

  • LocalizableAttribute는 비주얼 디자이너에 대해 속성을 지역화할 수 있는지 여부를 지정하며 true 또는 false로 설정됩니다. 속성이 Localizable(true)로 표시되면 비주얼 디자이너에서는 지역화된 리소스를 serialize할 때 이 속성을 포함합니다. 지역화할 수 있는 속성에 대해 컨트롤이 폴링되면 비주얼 디자이너에서는 culture 중립적인 리소스 파일 또는 기타 지역화 소스에 이 속성 값을 유지합니다.

    참고:

    ASP.NET 버전 1.0 및 1.1에서는 ASP.NET 지역화 모델이 다르므로 이 버전의 사용자 지정 서버 컨트롤에는 LocalizableAttribute를 적용할 수 없습니다.

컨트롤과 관련 멤버에 적용되는 디자인 타임 특성은 런타임에 컨트롤의 동작에 영향을 주지 않지만 컨트롤이 비주얼 디자이너에서 사용되는 경우 개발자의 작업 환경을 향상시킵니다. 서버 컨트롤에 대한 디자인 타임, 구문 분석 타임 및 런타임 특성의 전체 목록을 보려면 사용자 지정 서버 컨트롤의 메타데이터 특성을 참조하십시오.

App_Code 디렉터리를 사용하여 컴파일 단계 없이 컨트롤 테스트

ASP.NET의 동적 컴파일 기능을 사용하면 컨트롤을 어셈블리로 컴파일하지 않고도 페이지의 컨트롤을 테스트할 수 있습니다. ASP.NET에서는 ASP.NET 웹 사이트의 루트 아래에 있는 App_Code 디렉터리에 추가된 코드를 동적으로 컴파일합니다. 따라서 컨트롤을 수동으로 어셈블리로 컴파일하지 않고도 페이지에서 App_Code 디렉터리에 있는 소스 파일의 클래스에 액세스할 수 있습니다. 컨트롤의 소스 파일을 App_Code 디렉터리에 추가하는 경우 컨트롤 코드를 변경하면 이 컨트롤을 사용하는 페이지에 해당 변경 내용이 즉시 반영됩니다.

참고:

App_Code 디렉터리는 ASP.NET 1.0 및 1.1 버전에 없었던 새로운 기능입니다. 컨트롤을 처음 테스트할 때 App_Code 디렉터리를 사용할지 여부를 선택할 수 있습니다. 다음에 나오는 "컨트롤을 어셈블리로 컴파일" 단원의 내용과 같이 서버 컨트롤 빌드의 주요 단계는 이전 버전과 동일합니다.

ASP.NET 웹 사이트 및 App_Code 디렉터리를 만들려면

  1. ServerControlsTest라는 웹 사이트를 만듭니다. IIS에서 이 사이트를 ServerControlsTest라는 가상 디렉터리로 만들 수 있습니다. IIS 가상 디렉터리를 만들고 구성하는 데 대한 자세한 내용은 방법: IIS 5.0 및 6.0에서 가상 디렉터리 만들기 및 구성을 참조하십시오.

  2. 웹 사이트의 루트 디렉터리(웹 응용 프로그램 루트라고도 함) 바로 아래에 App_Code 디렉터리를 만듭니다.

  3. 컨트롤의 소스 파일(WelcomeLabel.cs 또는 WelcomeLabel.vb)을 App_Code 디렉터리에 복사합니다.

태그 접두사 만들기

태그 접두사는 컨트롤을 페이지에서 선언적으로 만드는 경우 컨트롤의 형식 이름 앞에 나오는 접두사입니다(예: <asp:Table />의 "asp"). ASP.NET의 경우 컨트롤을 페이지에서 선언적으로 사용하려면 컨트롤의 네임스페이스에 매핑되는 태그 접두사가 필요합니다. 페이지 개발자는 다음 예제와 같이 사용자 지정 컨트롤을 사용하는 각 페이지에 @ Register 지시문을 추가하여 태그 접두사/네임스페이스 매핑을 제공할 수 있습니다.

<%@ Register TagPrefix="aspSample" 
        Namespace="Samples.AspNet.CS.Controls"%>

[Visual Basic]

<%@ Register TagPrefix="aspSample" 
        Namespace="Samples.AspNet.VB.Controls"%>
참고:

ASP.NET 2.0의 @ Register 지시문은 ASP.NET 1.0 및 ASP.NET 1.1의 지시문과 같습니다. 이전 버전의 ASP.NET에서 사용되는 Register 지시문에 대해 잘 알고 있는 경우, 이전 Register 지시문에는 컨트롤 어셈블리의 이름을 지정하는 assembly 특성이 없음을 알 수 있습니다. assembly 특성이 없는 경우 ASP.NET에서는 어셈블리가 App_Code 디렉터리의 소스 파일에서 동적으로 컴파일된다고 가정합니다.

각 .aspx 페이지에서 @ Register 지시문을 사용하는 대신 페이지 개발자는 Web.config 파일에 태그 접두사/네임스페이스 매핑을 지정할 수 있습니다. 이 방법은 사용자 지정 컨트롤이 웹 응용 프로그램의 여러 페이지에 사용될 경우 유용합니다. 다음 절차에서는 Web.config 파일에 태그 접두사 매핑을 지정하는 방법을 설명합니다.

Web.config 파일에서 태그 접두사 매핑을 추가하려면

  1. 웹 사이트의 루트 디렉터리에 Web.config라는 텍스트 파일을 만듭니다(없는 경우).

  2. 비어 있는 새 Web.config 파일을 만든 경우에는 다음 코드를 파일에 복사하고 파일을 저장합니다.

    <?xml version="1.0"?>
    <configuration>
      <system.web>    
       <pages>
         <controls>
           <add tagPrefix="aspSample"            namespace="Samples.AspNet.CS.Controls">       </add>
         </controls>
       </pages>
      </system.web>
    </configuration>
    
    <?xml version="1.0"?>
    <configuration>
      <system.web>    
       <pages>
         <controls>
           <add tagPrefix="aspSample"            namespace="Samples.AspNet.VB.Controls">       </add>
         </controls>
       </pages>
      </system.web>
    </configuration>
    

    강조 표시된 섹션은 태그 접두사 "aspSample"을 Samples.AspNet.CS.Controls 또는 Samples.AspNet.VB.Controls 네임스페이스에 매핑하는 태그 접두사 엔트리를 보여 줍니다.

  3. Web.config 파일이 이미 있는 경우에는 이전 단계의 강조 표시된 텍스트를 구성 파일에서 controls 요소의 자식 요소로 추가합니다. Web.config 파일에 controls 및 pages 요소가 없는 경우에는 이전 단계에서 설명한 대로 두 요소를 만듭니다.

    참고:

    태그 접두사 엔트리는 pages 섹션 아래에 있는 controls 섹션의 자식이어야 하고 pages 섹션은 system.web의 자식이어야 합니다.

구성 파일에 태그 접두사 매핑을 지정한 후에는 웹 사이트의 페이지에서 WelcomeLabel 컨트롤을 선언적으로(<aspSample:WelcomeLabel />로) 사용할 수 있습니다.

참고:

태그 접두사의 구성 엔트리는 ASP.NET 2.0에 새로 추가된 기능입니다. ASP.NET 1.0 및 1.1에서는 사용자 지정 컨트롤을 사용한 각 페이지의 @ Register 지시문에 태그 접두사 매핑이 지정되었습니다.

컨트롤을 사용할 페이지 만들기

사용자 지정 컨트롤을 사용하는 페이지를 만들려면

  1. 웹 사이트에 WelcomeLabelTest.aspx라는 텍스트 파일을 만듭니다.

  2. 다음 태그를 WelcomeLabelTest.aspx 파일에 복사하고 파일을 저장합니다.

    <%@ Page Language="VB"%>
    <!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 id="Head1" >
        <title>WelcomeLabel Test</title>
      </head>
      <body>
        <form id="form1" >
          <div>
            <aspSample:WelcomeLabel Text="Hello" ID="WelcomeLabel1" 
               BackColor="Wheat" ForeColor="SaddleBrown" />
          </div>
        </form>
      </body>
    </html>
    
    <%@ Page Language="C#"%>
    <!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 id="Head1" >
        <title>WelcomeLabel Test</title>
      </head>
      <body>
        <form id="form1" >
          <div>
            <aspSample:WelcomeLabel Text="Hello" ID="WelcomeLabel1" 
               BackColor="Wheat" ForeColor="SaddleBrown" />
          </div>
        </form>
      </body>
    </html>
    
  3. 주소 표시줄에 다음 URL을 입력하여 브라우저에 WelcomeLabelTest.aspx를 표시합니다.

    https://localhost/ServerControlsTest/WelcomeLabelTest.aspx
    
  4. 컨트롤의 소스 코드를 변경합니다. 예를 들어 RenderContents 메서드의 끝에 다음 코드 줄을 입력하여 추가 문자열을 작성합니다.

    writer.Write("Testing how the App_Code directory works.");
    
    writer.Write("Testing how the App_Code directory works.")
    
  5. 브라우저에서 WelcomeLabelTest.aspx 페이지를 새로 고칩니다.

    컨트롤을 컴파일하지 않았지만 컨트롤의 변경 내용이 페이지에 적용됨을 확인할 수 있습니다.

WelcomeLabel 컨트롤에 대해 명시적으로 정의한 Text 속성뿐만 아니라 직접 정의하지 않은 BackColor 및 ForeColor 속성이 페이지의 컨트롤 인스턴스에 표시됩니다. WelcomeLabel 컨트롤은 WebControl 기본 클래스로부터의 상속을 통해 이러한 속성 및 기타 스타일 관련 속성을 가져옵니다. 또한 별도의 작업을 수행하지 않고도 WelcomeLabel에 스킨을 할당할 수 있으며 테마의 일부로 이 컨트롤을 사용할 수 있습니다.

컨트롤을 어셈블리로 컴파일

App_Code 디렉터리를 사용하면 컨트롤을 컴파일하지 않고도 테스트할 수 있지만 컨트롤을 개체 코드로 다른 개발자에게 배포하려면 컴파일해야 합니다. 또한 어셈블리로 컴파일되지 않은 컨트롤은 비주얼 디자이너의 도구 상자에 추가할 수 없습니다.

컨트롤을 어셈블리로 컴파일하려면

  1. 다음 단계를 수행하여 사용자 컴퓨터의 Windows 환경 변수 PATH에 .NET Framework 설치 경로가 포함되도록 설정합니다.

    1. Windows에서 내 컴퓨터를 마우스 오른쪽 단추로 클릭하고 속성을 선택한 다음 고급 탭, 환경 변수 단추를 차례로 클릭합니다.

    2. 시스템 변수 목록에서 Path 변수를 두 번 클릭합니다.

    3. 변수 값 텍스트 상자에서 기존 값의 끝에 세미콜론(;)을 추가한 후 .NET Framework 설치 경로를 입력합니다. 일반적으로 .NET Framework는 Windows 설치 디렉터리에서 \Microsoft.NET\Framework\versionNumber에 설치됩니다.

    4. 확인을 클릭하여 각 대화 상자를 닫습니다.

  2. 이 연습의 첫 번째 절차를 수행하여 소스 파일용으로 만든 디렉터리에서 다음 명령을 실행합니다.

    참고:

    이 디렉터리는 테스트를 위해 컨트롤의 소스 파일을 복사한 App_Code 디렉터리와 다릅니다.

    csc /t:library /out:Samples.AspNet.CS.Controls.dll /r:System.dll /r:System.Web.dll *.cs
    
    vbc /t:library /out:Samples.AspNet.VB.Controls.dll /r:System.dll /r:System.Web.dll *.vb
    

    /t:library 컴파일러 옵션을 사용하면 컴파일러에서 실행 어셈블리 대신 라이브러리를 만듭니다. /out 옵션은 어셈블리에 사용할 이름을 제공하고 /r 옵션은 어셈블리에 링크된 어셈블리를 나열합니다.

예제를 독립적으로 유지하기 위해 이 연습에서는 컨트롤이 하나만 있는 어셈블리를 만듭니다. 일반적으로 .NET Framework 디자인 지침에 따르면 적은 수의 클래스만 포함된 어셈블리를 만들지 않는 것이 좋습니다. 또한 쉽게 배포할 수 있도록 가능한 적은 수의 어셈블리를 만들어야 합니다.

컨트롤 어셈블리에 아이콘 포함

Visual Studio 2005 같은 비주얼 디자이너에서는 일반적으로 기본 아이콘(예: 기어 이미지)을 사용하여 도구 상자에 컨트롤을 표시합니다. 옵션으로 컨트롤의 어셈블리에 16x16 픽셀 비트맵을 포함하여 도구 상자에서 컨트롤의 모양을 사용자 지정할 수 있습니다. 규칙에 따라 비주얼 디자이너에서는 비트맵의 최하위 왼쪽 픽셀을 투명한 색으로 사용합니다.

컨트롤의 어셈블리에 아이콘을 포함하려면

  1. 16x16 픽셀 비트맵을 컨트롤에 대한 도구 상자 아이콘으로 가져오거나 새로 만듭니다.

  2. 비트맵 이름을 WelcomeLabel.bmp로 지정합니다.

  3. WelcomeLabel 컨트롤의 소스 파일이 있는 CustomControlsCS 또는 CustomControlsVB 디렉터리에 비트맵 파일을 추가합니다.

  4. 소스 파일이 포함된 디렉터리에서 다음 명령을 실행합니다.

    csc /res:WelcomeLabel.bmp,Samples.AspNet.CS.Controls.WelcomeLabel.bmp 
    /t:library /out:Samples.AspNet.CS.Controls.dll /r:System.dll 
    /r:System.Web.dll *.cs
    
    vbc /res:WelcomeLabel.bmp,Samples.AspNet.VB.Controls.WelcomeLabel.bmp 
    /t:library /out:Samples.AspNet.VB.Controls.dll /r:System.dll 
    /r:System.Web.dll *.vb
    

    이 명령은 컨트롤을 컴파일하고 비트맵을 어셈블리에 리소스로 포함합니다. 포함된 비트맵 리소스의 이름은 이 비트맵이 연결되는 컨트롤의 네임스페이스로 한정된 이름과 정확히 일치하도록 지정해야 합니다. 예를 들어 컨트롤의 이름이 Samples.AspNet.CS.Controls.WelcomeLabel인 경우 포함된 비트맵의 이름은 Samples.AspNet.CS.Controls.WelcomeLabel.bmp여야 합니다. 이 명명 규칙으로 인해 비주얼 디자이너에서는 비트맵을 자동으로 컨트롤의 도구 상자 아이콘으로 사용하게 됩니다. 이 명명 규칙을 사용하지 않는 경우에는 ToolboxBitmapAttribute를 컨트롤에 적용하여 포함된 비트맵 리소스의 이름을 지정해야 합니다.

TagPrefixAttribute를 사용하여 태그 접두사/네임스페이스 매핑 제공

이 연습의 앞부분에서 App_Code 디렉터리를 사용할 때 페이지 개발자가 페이지 또는 Web.config 파일에 태그 접두사를 지정하는 방법을 확인했습니다. 선택적으로 어셈블리 수준의 System.Web.UI.TagPrefixAttribute 특성을 포함하여 비주얼 디자이너에서 컨트롤에 사용할 기본 태그 접두사를 지정할 수도 있습니다. TagPrefixAttribute 특성은 비주얼 디자이너가 페이지의 Register 지시문 또는 Web.config 파일에서 태그 접두사 매핑을 찾지 못한 경우 사용할 태그 접두사를 제공하므로 유용합니다. 도구 상자의 컨트롤을 처음으로 두 번 클릭하거나 페이지로 끌어 오면 태그 접두사가 페이지에 등록됩니다.

TagPrefixAttribute 특성을 사용하려는 경우 컨트롤과 함께 컴파일되는 별도의 파일에 이 특성을 지정할 수 있습니다. 규칙에 따라 이 파일의 이름은 AssemblyInfo.cs 또는 AssembyInfo.vb처럼 AssemblyInfo.languageExtension으로 지정됩니다. 다음 절차에서는 TagPrefixAttribute 메타데이터를 지정하는 방법을 설명합니다.

참고:

컨트롤의 어셈블리에 TagPrefixAttribute를 지정하지 않고 페이지 개발자가 페이지 또는 Web.config 파일에 태그 접두사/네임스페이스 매핑을 지정하지 않는 경우 비주얼 디자이너에서 기본 태그 접두사를 만들 수 있습니다. 예를 들어 Visual Studio 2005에서는 도구 상자에서 컨트롤을 끌어 오면 이 컨트롤에 대해 cc1 같은 고유한 태그가 만들어집니다.

TagPrefixAttribute를 사용하여 네임스페이스/태그 접두사 매핑을 추가하려면

  1. 소스 코드 디렉터리에 AssemblyInfo.cs 또는 AssemblyInfo.vb라는 파일을 만들고 다음 코드를 파일에 추가합니다.

    using System;
    using System.Web.UI;
    [assembly: TagPrefix("Samples.AspNet.CS.Controls", "aspSample")]
    
    Imports System
    Imports System.Web.UI
    <Assembly: TagPrefix("Samples.AspNet.VB.Controls", "aspSample")> 
    

    태그 접두사 특성은 Samples.AspNet.CS.Controls 또는 Samples.AspNet.VB.Controls 네임스페이스와 aspSample 접두사 간에 매핑을 만듭니다.

  2. 포함 리소스가 있는지 여부에 관계없이 이전에 사용된 컴파일 명령을 사용하여 모든 소스 파일을 다시 컴파일합니다.

컴파일된 사용자 지정 컨트롤을 ASP.NET 페이지에 사용

컴파일된 버전의 사용자 지정 컨트롤을 테스트하려면 웹 사이트의 페이지에서 컨트롤의 어셈블리에 액세스할 수 있도록 설정해야 합니다.

웹 사이트에서 컨트롤의 어셈블리에 액세스할 수 있도록 설정하려면

  1. 웹 사이트의 루트 아래에 Bin 디렉터리를 만듭니다.

  2. 컨트롤 어셈블리(Samples.AspNet.CS.Controls.dll 또는 Samples.AspNet.VB.Controls.dll)를 Bin 디렉터리에 복사합니다.

  3. App_Code 디렉터리에서 컨트롤의 소스 파일을 삭제합니다.

    소스 파일을 삭제하지 않으면 컴파일된 어셈블리와 ASP.NET에서 동적으로 생성된 어셈블리 둘 다에 컨트롤 형식이 유지됩니다. 이렇게 되면 컨트롤을 로드할 때 모호한 참조가 만들어지고 컨트롤이 사용되는 페이지에서 컴파일러 오류가 발생합니다.

이 연습에서 만든 어셈블리는 ASP.NET 웹 사이트의 Bin 디렉터리에 배치하여 웹 사이트의 페이지에서 컨트롤을 사용할 수 있도록 해야 하므로 전용 어셈블리라고 합니다. 복사본이 설치되어 있지 않은 다른 응용 프로그램에서는 이 어셈블리에 액세스할 수 없습니다. 공유 웹 호스팅 응용 프로그램에 대해 컨트롤을 만드는 경우 일반적으로 컨트롤을 전용 어셈블리에 패키지합니다. 그러나 전용 호스팅 환경에서 사용할 컨트롤을 만들거나 ISP가 모든 고객이 사용할 수 있도록 설정하는 컨트롤 모음을 만들 경우에는 전역 어셈블리 캐시에 설치된 강력한 이름의 공유 어셈블리에 컨트롤을 패키지해야 합니다. 자세한 내용은 어셈블리 및 전역 어셈블리 캐시 사용을 참조하십시오.

이제 Web.config 파일에서 만든 태그 접두사 매핑을 수정하여 컨트롤의 어셈블리 이름을 지정해야 합니다.

Web.config 파일에서 태그 접두사 매핑을 수정하려면

  • Web.config 파일을 편집하여 addtagPrefix 요소에 assembly 특성을 추가합니다.

    <controls>
      <add tagPrefix="aspSample"   
        namespace="Samples.AspNet.CS.Controls" 
        assembly="Samples.AspNet.CS.Controls">
      </add>
    </controls>
    
    <controls>
      <add tagPrefix="aspSample"   
        namespace="Samples.AspNet.VB.Controls" 
        assembly="Samples.AspNet.VB.Controls">
      </add>
    </controls>
    

assembly 특성은 컨트롤을 포함하는 어셈블리의 이름을 지정하고 addtagPrefix 요소는 태그 접두사를 네임스페이스 및 어셈블리 조합에 매핑합니다. ASP.NET에 의해 App_Code 디렉터리의 소스 파일에서 동적으로 어셈블리가 생성되면 어셈블리 특성이 필요하지 않습니다. 어셈블리 특성이 사용되지 않는 경우 ASP.NET은 App_Code 디렉터리에서 동적으로 생성된 어셈블리로부터 컨트롤 형식을 로드합니다.

사용자 지정 컨트롤을 사용하는 페이지를 보려면

  • 주소 표시줄에 다음 URL을 입력하여 브라우저에 WelcomeLabelTest.aspx 페이지를 표시합니다.

    https://localhost/ServerControlsTest/WelcomeLabelTest.aspx
    

Visual Studio 2005 같은 비주얼 디자이너에서 컨트롤을 사용하는 경우 도구 상자에 컨트롤 추가, 도구 상자의 컨트롤을 디자인 화면으로 끌어 오기, 속성 브라우저에서 속성 및 이벤트 액세스 등의 작업을 수행할 수 있습니다. 또한 Visual Studio 2005에서는 페이지 디자이너의 소스 뷰 및 코드 편집기에서 컨트롤에 대해 IntelliSense 기능이 완벽하게 제공됩니다. 페이지 개발자가 컨트롤 태그를 클릭하는 경우 속성 브라우저 지원 및 script 블록의 문 완성 기능을 예로 들 수 있습니다.

참고:

대부분의 비주얼 디자이너에서는 사용자 지정 컨트롤을 디자이너의 도구 상자에 추가할 수 있습니다. 자세한 내용은 디자이너 설명서를 참조하십시오.

다음 단계

이 연습에서는 간단한 사용자 지정 ASP.NET 서버 컨트롤을 개발하고 페이지에서 이 컨트롤을 사용하는 방법을 확인했습니다. 또한 속성을 정의하고 컨트롤을 어셈블리로 컴파일하는 방법을 배웠습니다. 렌더링, 속성 정의, 상태 관리, 합성 컨트롤 구현 등에 대한 자세한 내용은 사용자 지정 ASP.NET 서버 컨트롤 개발을 참조하십시오.

이 연습에서는 컨트롤에 사용자 지정 도구 상자 아이콘을 제공할 수 있음을 확인했습니다. 또한 디자인 타임 메타데이터를 추가하여 컨트롤에 대해 속성 브라우저 지원 기능을 사용자 지정하는 방법을 배웠습니다. GridView 같은 복합 컨트롤은 디자인 타임과 런타임에 서로 다른 사용자 인터페이스를 제공하는 비주얼 디자이너 클래스를 사용하여 디자인 타임 환경을 향상시킵니다. 서버 컨트롤에 대한 ASP.NET 2.0 디자이너 개체 모델은 ASP.NET 1.0 및 1.1에서 제공하는 모델과 상당히 다릅니다. ASP.NET 2.0에서 컨트롤에 대한 사용자 지정 디자이너 클래스를 구현하는 데 대한 내용은 ASP.NET 컨트롤 디자이너 개요를 참조하십시오.

ASP.NET 2.0에서 서버 컨트롤은 어댑터 클래스를 사용하여 클라이언트 브라우저 또는 장치에 대해 다양한 동작을 정의할 수 있습니다. 자세한 내용은 ASP.NET 서버 컨트롤의 어댑터 개발을 참조하십시오.

브라우저의 종류가 다르거나 종류는 같더라도 버전이 다르면 지원하는 기능이 달라집니다. ASP.NET 서버 컨트롤은 .aspx 페이지를 요청한 브라우저를 자동으로 확인하고 해당 브라우저에 적합하게 생성된 HTML 태그의 서식을 지정합니다. 그러나 이전 버전의 브라우저에서 렌더링할 수 없는 컨트롤 기능도 있으므로 페이지가 모든 브라우저에서 원하는 방식으로 나타나게 하려면 가능한 많은 종류의 브라우저에서 페이지 출력을 확인하는 것이 좋습니다. 자세한 내용은 ASP.NET 웹 서버 컨트롤 및 브라우저 기능을 참조하십시오.

참고 항목

기타 리소스

사용자 지정 ASP.NET 서버 컨트롤 개발