페이지 라이프 사이클을 이해하는 것은 웹 애플리케이션을 구축할 때, 매우 중요한 과정이라고 생각한다.
라이프 사이클의 과정과 단계를 이해해야지,
디버깅은 물론, 필요할 때 적절한 단계에 기능을 추가하는 등의 컨트롤을 할 수 있고, 추후 장애 해결 등에도 도움이 되기 때문이다.
ASP.NET 페이지 라이프 사이클은 다음의 단계를 거친다.
페이지 라이프 사이클
Page Request
Page Request은 페이지 라이프 사이클이 시작되기 전에 발생한다. 사용자가 페이지를 요청하면 ASP.NET은 페이지를 구문 분석하고 컴파일해야 하는지 여부(즉, 페이지의 수명을 시작하는지 여부)를 결정하거나 페이지를 실행하지 않고 응답으로 캐시된 버전을 보낼지에 대한 여부를 결정한다.
Start
Start 단계에서는 Request 및 Response와 같은 페이지 속성이 설정된다. 이 단계에서 페이지는 요청이 포스트백인지 새 요청인지 확인하고 IsPostBack 속성을 설정한다. 페이지는 또한 UICulture 속성을 설정한다.
Initialization
Initialization 초기화 중에는 페이지의 컨트롤이 사용 가능하며 각 컨트롤의 UniqueID 속성이 설정된다. 마스터 페이지와 테마도 적용된다. 현재 요청이 포스트백인 경우, 포스트백 데이터가 아직 로드되지 않았으며 컨트롤 속성 값도 뷰 상태에서의 값으로 복원되지 않은 상태이다.
Load
로드 중에 현재 요청이 포스트백인 경우 컨트롤 속성은 뷰 상태에서 복구된 정보와 컨트롤 상태로 로드된다.
Postback event handling
이벤트 처리 요청이 포스트백인 경우 컨트롤 이벤트 핸들러가 호출된다. 이후 모든 유효성 검사 컨트롤의 Validate 메서드가 호출되며, 개별 유효성 검사 컨트롤과 페이지의 IsValid 속성을 설정한다. (이 시퀀스에는 예외가 있다: 검증을 일으킨 이벤트의 핸들러는 검증 이후에 호출된다.)
Rendering
렌더링 전에 페이지 및 모든 컨트롤의 뷰 상태가 저장된다. 렌더링 단계 동안 페이지는 각 컨트롤에 대한 렌더 메서드를 호출하며, 페이지의 Response 속성의 OutputStream 개체에 출력을 작성한다.
Unload
Unload 이벤트는 페이지가 완전히 렌더링되고 클라이언트로 전송되고 폐기될 준비가 된 후에 발생한다. 이 시점에서 Response 및 Request와 같은 페이지 속성이 언로드되고 정리가 수행된다.
라이프 사이클 이벤트
각 라이프 사이클 단계에서 페이지는 사용자 정의 코드를 실행할 수 있는 이벤트를 발생시킨다.
컨트롤 이벤트의 경우 이벤트 핸들러를 이벤트에 바인딩하여 코드를 실행하거나 코드에서 직접 처리할 수 있다.
페이지는 자동 이벤트 연결을 지원하며, 이는 특정 이름을 가진 메서드를 찾아서 특정 이벤트가 발생할 때 해당 메서드를 자동으로 실행한다.
@ Page 지시문의 AutoEventWireup 속성이 true로 설정된 경우 페이지 이벤트가 자동으로 Page_event와 같은 이름 규칙을 사용하는 메서드에 바인딩된다.
다음은 페이지 라이프 사이클 이벤트 목록이다.
훨씬 더 많은 이벤트가 있지만, 대부분의 페이지 처리 시나리오에는 사용되지 않는다.
대신 이러한 이벤트는 주로 ASP.NET 웹 페이지의 서버 컨트롤에서 자체 초기화 및 렌더링을 위해 사용된다.
사용자 정의 ASP.NET 서버 컨트롤을 만들려면 이러한 이벤트에 대해 자세히 이해해야 한다.
페이지 라이프 사이클 이벤트
PreInit
시작 단계가 완료되고 초기화 단계가 시작되기 전에 발생한다.
다음과 같은 경우에 이 이벤트를 사용한다:
- IsPostBack 속성을 확인하여 페이지가 처음으로 처리되는지 여부를 확인할 경우 (IsCallback 및 IsCrossPagePostBack 속성도 이 시점에서 설정한다)
- 동적 컨트롤을 생성하거나 다시 생성할 경우
- 마스터 페이지를 동적으로 설정할 경우
- 테마 속성을 동적으로 설정할 경우
- 프로필 속성 값을 읽거나 설정할 경우
Init
모든 컨트롤이 초기화되고 스킨 설정이 적용된 후에 발생한다.
이때 개별 컨트롤의 Init 이벤트는 페이지의 Init 이벤트보다 먼저 발생한다.
컨트롤 속성을 읽거나 초기화하기 위해 이 이벤트를 사용한다.
InitComplete
페이지 초기화 단계가 끝날 때 발생한다.
Init 및 InitComplete 이벤트 사이에는 하나의 작업만 발생하는데,
그 작업은 뷰 상태 변경을 추적하며, ViewState 컬렉션에 추가된 값이 다음 포스트백에서도 유지되도록 한다.
*뷰 상태란, 상태 정보를 의미한다. ex. 체크박스의 선택 여부, 드롭다운 목록의 선택된 항목
뷰 상태 추적이 켜져 있지 않으면 뷰 상태에 추가된 값이 포스트백 간에 손실되게 된다.
일반적으로 컨트롤은 Init 이벤트를 발생시키자마자 뷰 상태 추적을 켜게 된다.
PreLoad
페이지가 자신과 모든 컨트롤에 대한 뷰 상태를 로드하고, 요청과 함께 제공된 포스트백 데이터를 처리한 후에 발생하는 이벤트이다.
Load
페이지 개체는 페이지 개체의 OnLoad 메서드를 호출한 다음,
페이지와 모든 자식 컨트롤에 대해 동일한 작업을 재귀적으로 수행한다.
개별 컨트롤의 Load 이벤트는 페이지의 Load 이벤트 이후에 발생한다.
OnLoad 이벤트 메서드를 사용하여 컨트롤의 속성을 설정하고 데이터베이스 연결을 설정한다.
Control events
특정 컨트롤 이벤트를 처리하기 위해 사용된다.
예를 들어 Button 컨트롤의 Click 이벤트 또는 TextBox 컨트롤의 TextChanged 이벤트와 같은 이벤트를 처리한다.
LoadComplete
이벤트 처리 단계의 끝에 발생한다.
페이지의 모든 다른 컨트롤이 로드되었어야 하는 작업(=모든 컨트롤이 로드된 이후 시작해야 하는 작업)에 사용한다.
PreRender
페이지가 렌더링되기 위해 필요한 모든 컨트롤을 생성한 후에 드디어 발생한다.
(이를 위해 페이지 개체는 각 컨트롤 및 페이지에 대해 EnsureChildControls를 호출한다.)
페이지 개체는 페이지 개체에 대해 PreRender 이벤트를 발생시키며,
재귀적으로 모든 자식 컨트롤에 대해서도 동일한 작업을 수행한다.
개별 컨트롤의 PreRender 이벤트는 페이지의 PreRender 이벤트 이후에 발생한다.
렌더링 단계가 시작되기 전에 페이지 또는 컨트롤 내용에 최종 변경을 수행하기 위해 이 이벤트를 사용한다.
PreRenderComplete
DataSourceID 속성이 설정된 데이터 바인딩 컨트롤의 경우, 해당 컨트롤의 DataBind 메서드를 호출한 후에 발생한다.
SaveStateComplete
페이지와 모든 컨트롤에 대한 뷰 상태 및 컨트롤 상태가 저장된 후에 발생한다.
이 시점에서 페이지나 컨트롤에 대한 변경 사항은 렌더링에 영향을 미치지만,
다음 포스트백에서 변화가 추적되지는 않는다.
Render
Render는 이벤트가 아니며 처리 단계의 이 시점에서 페이지 개체가 각 컨트롤의 이 메서드를 호출한다.
모든 ASP.NET 웹 서버 컨트롤에는 컨트롤의 마크업을 브라우저로 보내기 위한 Render 메서드가 존재한다.
사용자 정의 컨트롤을 만드는 경우 일반적으로 이 메서드를 재정의하여 컨트롤의 마크업을 출력한다.
그러나 사용자 정의 컨트롤이 표준 ASP.NET 웹 서버 컨트롤만 포함하고 사용자 정의 마크업이 없다면,
Render 메서드를 재정의할 필요가 없다.
Unload
각 컨트롤 및 페이지에 대한 이벤트가 발생한 후에 발생한다.
컨트롤에서는 특정 컨트롤의 최종 정리 작업에 사용하고,
페이지 자체에서는 열려 있는 파일 및 데이터베이스 연결을 닫거나 로깅 또는 기타 요청별 작업을 완료하기 위해 사용한다.
언로드 단계에서 페이지와 해당 컨트롤은 이미 렌더링되었으므로 응답 스트림에 추가 변경 사항을 적용할 수는 없다.
추가적인 페이지 라이프 사이클 고려 사항
컨트롤, 페이지, 마스터페이지의 Init, Load
개별 ASP.NET 서버 컨트롤은 페이지 라이프 사이클과 유사한 자체 라이프 사이클을 갖는다.
예를 들어 컨트롤의 Init 및 Load 이벤트는 해당 페이지 이벤트와 동일한 시점에 발생한다.
그러나 Init 및 Load는 각 컨트롤에 대해 역순으로 발생한다.
각 자식 컨트롤에 대한 Init 이벤트(그리고 언로드 이벤트)가 해당 컨테이너의 이벤트가 발생하기 전에 발생한다.(하향식)
그러나 컨테이너의 Load 이벤트는 해당 자식 컨트롤의 Load 이벤트(상향식)보다 먼저 발생한다.
마스터 페이지는 페이지의 자식 컨트롤처럼 작동한다.
마스터 페이지의 Init 이벤트는 페이지의 Init 및 Load 이벤트 이전에 발생하고,
마스터 페이지의 Load 이벤트는 페이지의 Init 및 Load 이벤트 이후에 발생한다.
Page 클래스에서 상속한 클래스인 경우
Page 클래스에서 상속한 클래스를 만들 때 페이지에서 발생한 이벤트를 처리하는 것 외에도,
페이지의 기본 클래스에서 메서드를 재정의할 수 있다.
이벤트 핸들러를 Page_event 문법을 사용하여 만들 때,
페이지의 기본 구현이 암시적으로 호출되며 메서드 내에서 호출할 필요는 없다.
예를 들어 페이지 클래스의 OnLoad 메서드는 항상 호출되며 Page_Load 메서드를 만들지 않더라도 호출된다.
그러나 페이지 OnLoad 메서드를 override 키워드 (Visual Basic에서는 Overrides)를 사용하여 재정의하는 경우,
기본 메서드를 명시적으로 호출해야 한다.
페이지의 OnLoad 메서드를 재정의하는 경우,
페이지에서 base.Load(MyBase.Load in Visual Basic)를 호출하여 기본 구현이 실행되도록 해야 한다.
추가된 컨트롤을 위한 Catch-Up 이벤트
런타임에서 동적으로 생성되거나 데이터 바운드 컨트롤의 템플릿 내에서 선언적으로 생성된 컨트롤의 경우,
이 컨트롤의 이벤트는 초기에 페이지의 다른 컨트롤의 이벤트와 동기화되지 않는다.
예를 들어 런타임에서 추가된 컨트롤의 경우 Init 및 Load 이벤트가 선언적으로 생성된 컨트롤의 경우와 비교하여,
페이지 라이프 사이클의 훨씬 나중에 발생할 수 있다.
따라서 인스턴스화된 이후에 동적으로 추가된 컨트롤 및 데이터 바운드 컨트롤 내에서 선언적으로 생성된 컨트롤은,
추가된 이벤트가 해당 컨트롤이 Controls 컬렉션에 추가된 이벤트와 동기화될 때까지 하나씩 이벤트를 발생시킨다.
데이터 바인딩 컨트롤을 위한 데이터 바인딩 이벤트
페이지 라이프 사이클과 데이터 바인딩 이벤트 간의 관계를 이해하기 위해,
GridView, DetailsView 및 FormView와 같은 데이터 바운드 컨트롤에 존재하는 데이터 바인딩 이벤트를 이해해야 한다.
DataBinding
컨트롤의 DataBinding 이벤트는 페이지의 PreRender 이벤트 이후에 발생한다.
(이는 DataSourceID 속성이 선언적으로 설정된 컨트롤에 해당한다. 그렇지 않은 경우 이 이벤트는 컨트롤의 DataBind 메서드를 호출할 때 발생합니다.)
이 이벤트는 컨트롤을 데이터에 바인딩하는 프로세스의 시작을 나타낸다.
필요한 경우 데이터베이스 연결을 수동으로 열고, 쿼리가 실행되기 전에 매개 변수 값을 동적으로 설정하는 데,
이 이벤트를 사용한다.
RowCreated (GridView 전용), ItemCreated (DataList, DetailsView, SiteMapPath, DataGrid, FormView, Repeater 및 ListView 컨트롤)
컨트롤의 DataBinding 이벤트 이후에 발생한다.
이 이벤트를 사용하여 데이터 바인딩에 의존하지 않는 콘텐츠를 조작한다.
예를 들어 런타임에서 GridView 컨트롤의 헤더나 푸터 행에 서식을 동적으로 추가할 수 있다.
RowDataBound (GridView 전용), ItemDataBound (DataList, SiteMapPath, DataGrid, Repeater 및 ListView 컨트롤)
컨트롤의 RowCreated 또는 ItemCreated 이벤트 이후에 발생한다.
이 이벤트가 발생하면 행 또는 항목에서 데이터를 서식화하거나 관련 데이터를 표시하기 위해,
자식 데이터 소스 컨트롤의 FilterExpression 속성을 설정하는 등의 작업을 수행할 수 있다.
DataBound
데이터 바인딩 컨트롤에서 데이터 바인딩 작업이 완료된 후에 발생한다.
GridView 컨트롤의 경우 모든 행 및 모든 하위 컨트롤에 대해서 데이터 바인딩이 완료된 후에 발생한다.
이 이벤트를 사용하여 데이터 바인딩된 내용을 서식화하거나,
현재 컨트롤의 내용에 필요한 값에 의존하는 다른 컨트롤에서 데이터 바인딩을 시작한다.
중첩된 데이터 바운드 컨트롤
자식 컨트롤이 데이터 바인딩되었지만 해당 컨테이너 컨트롤은 아직 데이터 바인딩되지 않은 경우,
자식 컨트롤의 데이터와 해당 컨테이너 컨트롤의 데이터는 동기화되지 않을 수 있다.
이는 특히 자식 컨트롤의 데이터가 컨테이너 컨트롤의 데이터 바인딩 값을 기반으로 처리하는 경우에 해당된다.
예를 들어, 각 행에 회사 레코드를 표시하는 GridView 컨트롤이 있고, ListBox 컨트롤에서 회사 임원 목록을 표시한다고 가정한다.
목록을 채우려면 ListBox 컨트롤을 데이터 소스 컨트롤(예: SqlDataSource)에 바인딩하고 쿼리에서 회사 ID를 사용하여 회사 임원 데이터를 검색하면 된다.
ListBox 컨트롤의 데이터 바인딩 속성인 DataSourceID 및 DataMember가 선언적으로 설정된 경우,
ListBox 컨트롤은 포스트백 데이터의 기능을 실행하는 컨테이닝 행의 DataBinding 이벤트에서 바인딩을 시도한다.
그러나 행의 CompanyID 필드는 GridView 컨트롤의 RowDataBound 이벤트가 발생하기 전까지 값이 없다.
이 경우 자식 컨트롤(즉, ListBox 컨트롤)은 컨테이너 컨트롤(즉, GridView 컨트롤)이 바인딩되기 전에 바인딩되므로
데이터 바인딩 단계가 동기화되지 않는다.
이러한 상황을 피하려면 ListBox 컨트롤의 데이터 소스 컨트롤을 ListBox 컨트롤 자체의 템플릿 항목에 배치하고,
ListBox의 데이터 바인딩 속성을 선언적으로 설정하지 않고 RowDataBound 이벤트 중에 프로그래밍 방식으로 설정하여,
ListBox 컨트롤이 CompanyID 정보를 사용할 수 있을 때까지 데이터를 바인딩하지 않도록 제어해야 한다.
로그인 컨트롤 이벤트
로그인 컨트롤은 Web.config 파일의 설정을 사용하여 인증을 자동으로 관리할 수 있다.
그러나 컨트롤 작동 방식을 사용자 정의하려거나,
로그인 컨트롤 이벤트가 페이지 라이프 사이클과 어떻게 관련되는지 이해하려면 다음 이벤트를 알고 있어야 한다.
LoggingIn
페이지의 LoadComplete 이벤트 이후에 포스트백 중에 발생한다.
이 이벤트는 로그인 프로세스가 시작되는 지점을 나타낸다.
인증 프로세스를 시작하기 전에 수행해야 하는 작업에 이 이벤트를 사용한다.
Authenticate
LoggingIn 이벤트 이후에 발생한다.
로그인 컨트롤의 기본 인증 동작을 오버라이드하거나 향상시키기 위해 이 이벤트를 사용한다.
LoggedIn
사용자 이름과 비밀번호가 인증된 후에 발생한다.
이 이벤트를 사용하여 다른 페이지로 리디렉션하거나 컨트롤의 텍스트를 동적으로 설정한다.
오류가 발생하거나 인증에 실패한 경우 이 이벤트는 발생하지 않는다.
LoginError
인증에 실패한 경우 발생한다.
이 이벤트를 사용하여 문제를 설명하는 컨트롤의 텍스트를 설정하거나 사용자를 다른 페이지로 이동시키는 데 사용한다.
'Skills > Asp.net' 카테고리의 다른 글
ASP.NET ASMX 파일이란? (0) | 2023.11.08 |
---|---|
licenses.licx를 git 원격저장소, svn에 커밋하면 안되는 이유 (0) | 2023.11.08 |
[Error] 예외 발생: 'System.Data.SqlClient.SqlException'(System.Data.dll) (0) | 2023.09.18 |
[Error] Content 컨트롤은 마스터 페이지를 참조하는 중첩된 마스터 페이지 또는 콘텐츠 페이지에서 최상위 컨트롤이어야 합니다 (0) | 2023.09.13 |
ASPX GetRowValues 메서드를 사용해서 특정 Row 값 접근하기 (0) | 2023.09.12 |