.net Global.asax lifecycle
Global.asax 란?
Global.asax 파일은 예전 ASP에서 사용되었던 global.asa 파일에서 사용되었던 내용을 .NET 환경에서 사용할 수 있도록 만든 파일입니다. Global 이란 뜻처럼, 전역 데이터를 관리할 수 있을뿐 아니라 웹 사이트의 시작과 종료, 새로운 사용자의 접속 시도 및 접속 종료시 등 여러가지 프로그래밍 코드를 작성할 수 있는 곳입니다.
어떠한 Event 들이 존재하는가?
아래 그림은 사용자들이 접속시, 실행되는 Event 순서입니다.

그 이외에 Applictaion 이 시작/종료 시 1번만 실행되는 Event
- Application_Init
- Application_Start
- Application_Dispose
- Application_End
Session 이 시작/종료 될 때 실행되는 Event
- Session_Start
- Session_End
출처: https://im-first-rate.tistory.com/12 [웃으면 1류다]
[ASP.NET] Global.asax 을 알아보자.
Global.asax 란? Global.asax 파일은 예전 ASP에서 사용되었던 global.asa 파일에서 사용되었던 내용을 .NET 환경에서 사용할 수 있도록 만든 파일입니다. Global 이란 뜻처럼, 전역 데이터를 관리할 수 있을뿐
im-first-rate.tistory.com
Web.config 파일은 ASP.NET에 새롭게 추가된 설정 파일로서 다양한 옵션들을 통해 ASP.NET 웹 응용 프로그램의 실행을 관리할 수 있는 파일입니다.
Global.asax 파일
Global.asax 파일은 기존의 ASP에서 사용되던 global.asa 파일의 기능을 더욱 확장한 새로운 전역 파일입니다. 이 파일은 웹 응용 프로그램의 루트 디렉터리에 존재하여 웹 응용 프로그램이 처음 시작하거나 완전히 종료될 때, 새로운 사용자가 웹 사이트에 처음 접속하였거나 떠날 때, 또는 매번 사용자의 요청이 웹 서버로 전송될 때 등 다양한 상황에 따라 알맞은 프로그램 코드를 실행시킬 수 있는 여러 이벤트를 제공합니다.
예를 들어 여러분은 Global.asax 파일을 이용하여 새로운 사용자가 웹 사이트에 접속할 때 마다 방문 수를 카운트 하는 프로그램을 구현할 수 있습니다. 이 절의 마지막 부분에서 카운트 프로그램의 예제를 구현해 볼 것입니다.
Global.asax 파일은 기존의 ASP 웹 응용 프로그램에서 사용하던 global.asa 파일과 공존할 수 있습니다. 이것은 ASP.NET 웹 응용 프로그램 안에 ASP 웹 응용 프로그램이 함께 공존할 수 있는 것과 같은 이치입니다.
그러나 Global.asax 파일은 ASP.NET 웹 폼 페이지에 대해서만 영향을 미치며, 기존의 ASP 파일에 대해서는 global.asa 파일이 영향을 미치게 됩니다.
또한 기존의 global.asa 파일은 그 내용이 변경되면 웹 서비스를 중지하고 다시 시작해야 하는 불편이 있었지만 ASP.NET의 Global.asax 파일은 내용이 변경되면 ASP.NET 워커 프로세스가 일단 웹 응용 프로그램의 실행을 중지한 후 다시 실행하는 작업을 자동적으로 수행해 줌으로써 웹 사이트 관리 측면에서 보다 나은 환경을 제공합니다.
HttpApplication 클래스
Global.asax 파일에 대해 이야기를 하다가 뜬금없이 HttpApplication 클래스는 왜 들먹이는 것일까요? 그것은 Global.asax 파일이 HttpApplication 클래스를 상속하고 있기 때문입니다.
HttpApplication 클래스는 ASP.NET 웹 응용 프로그램의 모든 객체에 사용될 공통의 속성과 메서드, 이벤트를 정의하고 있는 클래스로 웹 응용 프로그램 자체를 의미하는 클래스라고 생각하시면 이해가 빠를 것 같습니다.
이 HttpApplication 클래스는 System.Object 클래스를 상속하며 System.Web 네임 스페이스에 구현되어있습니다. Global.asax 파일은 이 클래스를 상속하므로 당연히 HttpApplication 클래스에서 제공하는 속성과 메서드, 그리고 이벤트에 대해 알아보아야겠지요?
HttpApplication 클래스의 속성
HttpApplication 클래스는 다음과 같은 속성들을 제공합니다.
Application 속성
이 속성은 제 2 장에서도 언급한 바 있는 Page 클래스의 Application 속성과 동일한 속성으로 HttpApplicationState 클래스에 대한 참조를 제공하는 속성으로 형식은 다음과 같습니다.
public HttpApplicationState Application {get;}
이 속성을 통해서 개발자는 Global.asax 파일 내에서 Application 객체에 저장된 전역 데이터에 액세스할 수 있습니다.
Context 속성
이 속성은 현재 요청된 ASP.NET 웹 폼 페이지가 실행되는 문맥 객체를 구현한 HttpContext 클래스 객체에 대한 액세스를 제공하는 속성으로 형식은 다음과 같습니다.
public HttpContext Context {get;}
Modules 속성
이 속성은 현재 웹 응용 프로그램에 사용된 모든 모듈의 컬렉션을 가져오는 속성으로 형식은 다음과 같습니다.
public HttpModuleCollection Modules {get;}
Request 속성
이 속성은 클라이언트의 요청 정보를 저장하고 있는 HttpRequest 클래스 객체에 대한 액세스를 제공하는 속성으로 형식은 다음과 같습니다.
public HttpRequest Request {get;}
Response 속성
이 속성은 현재 요청에 대한 서버의 응답을 제어하는 HttpResponse 클래스 객체에 대한 액세스를 제공하는 속성으로 형식은 다음과 같습니다.
public HttpResponse Response {get;}
Server 속성
이 속성은 현재 요청에 대한 서버 객체에 대한 액세스를 제공하는 속성으로 형식은 다음과 같습니다.
public HttpServerUtility Server {get;}
Session 속성
이 속성은 현재 사용자와 웹 서버 사이에 형성된 세션 객체에 대한 액세스를 제공하는 속성으로 형식은 다음과 같습니다.
public HttpSessionState Session {get;}
Site 속성
이 속성은 현재 웹 응용 프로그램의 구현에 사용된 ISite 인터페이스에 대한 액세스를 제공하는 속성으로 형식은 다음과 같습니다.
public virtual ISite Site {get;}
User 속성
이 속성은 현재 요청에 대한 사용자 객체에 대한 액세스를 제공하는 속성으로 형식은 다음과 같습니다.
public IPrincipal User {get;}
HttpApplication 클래스의 이벤트
HttpApplication 객체가 제공하는 메서드는 지금부터 살펴볼 HttpApplication 객체의 이벤트에 대해 각각의 이벤트를 처리할 이벤트 핸들러를 추가하는 메서드들입니다. 따라서 이들 메서드에 대한 내용은 MSDN을 참고하는 것으로 여러분께 맡기고 HttpApplication 클래스의 이벤트에 대해 살펴보도록 하겠습니다.
HttpApplication 클래스가 제공하는 이벤트는 다음과 같습니다.
AcquireRequestState 이벤트
이 이벤트는 각 요청에 대한 상태를 얻을 때 발생하는 이벤트로서 형식은 다음과 같습니다.
public event EventHandler AcquireRequestState;
AuthenticateRequest 이벤트
이 이벤트는 보안 모드에서 사용되는 인증 여부를 판단할 때 발생하는 이벤트로 형식은 다음과 같습니다.
public event EventHandler AuthenticateRequest;
AuthorizeRequest 이벤트
이 이벤트는 보안 모드에서 사용되는 특정 자원에 대한 권한을 부여받기 전에 발생하는 이벤트로 형식은 다음과 같습니다.
public event EventHandler AuthorizeRequest;
BeginRequest 이벤트
이 이벤트는 클라이언트로부터 새로운 요청이 발생할 때 마다 발생하는 이벤트로 형식은 다음과 같습니다.
public event EventHandler BeginRequest;
EndRequest 이벤트
이 이벤트는 클라이언트로부터의 요청이 종료될 때 발생하는 이벤트로 형식은 다음과 같습니다.
public event EventHandler EndRequest;
Error 이벤트
이 이벤트는 웹 응용 프로그램의 실행 도중 오류가 발생했을 때 발생하는 이벤트로 형식은 다음과 같습니다.
public event EventHandler Error;
PreRequestHandlerExecute 이벤트
이 이벤트는 ASP.NET 페이지나 웹 서비스가 실행되기 직전에 발생하는 이벤트로 형식은 다음과 같습니다.
public event EventHandler PreRequeestHandlerExecute;
PostRequestHandlerExecute 이벤트
이 이벤트는 ASP.NET 페이지나 웹 서비스가 실행된 직후에 발생하는 이벤트로 형식은 다음과 같습니다.
public event EventHandler PostRequestHandlerExecute;
PreSendRequestContent 이벤트
이 이벤트는 요청에 따른 서버의 응답 컨텐츠를 전송하기 직전에 발생하는 이벤트로 형식은 다음과 같습니다.
public event EventHandler PreSendRequestContent;
PreSendRequestHeaders 이벤트
이 이벤트는 요청에 따른 서버의 응답 컨텐츠의 헤더를 전송하기 직전에 발생하는 이벤트로 형식은 다음과 같습니다.
public event EventHandler PreSendRequestHeaders;
ReleaseRequestState 이벤트
이 이벤트는 현재 클라이언트의 요청에 대해 ASP.NET 실행 프로세스가 모두 완료된 후에 발생하는 이벤트로 형식은 다음과 같습니다.
public event EventHandler ReleaseRequestState;
ResolveRequestCache 이벤트
이 이벤트는 ASP.NET 웹 폼 페이지의 실행을 무시하고 캐싱된 데이터를 이용하여 사용자의 요청에 응답할 때 발생하는 이벤트로 형식은 다음과 같습니다.
public event EventHandler ResolveRequestCache;
UpdateRequestCache 이벤트
이 이벤트는 모든 작업을 마친 후 캐쉬 모듈에 의해 다음 요청에 사용될 캐쉬 데이터를 저장할 때 발생하는 이벤트로 형식은 다음과 같습니다.
public event EventHandler UpdateRequestCache;
이상으로 HttpApplication 클래스에 대해 알아보았습니다. Global.asax 파일은 이 HttpApplication 클래스를 상속하므로 Global.asax 파일 내에서 이들 이벤트에 대한 핸들러 메서드를 작성하여 필요한 코드를 실행시킬 수 있습니다.
Global.asax 파일에서 제공되는 이벤트
기존의 ASP 프로그래밍 경험이 있으신 독자라면 global.asa 파일이 제공하는 4가지 대표적인 이벤트에 대해 잘 알고 계실 것입니다. global.asa 파일에서는 OnStart, OnEnd, Session_OnStart, Session_OnEnd 등의 이벤트를 제어할 수 있었지요. 이들은 각각 웹 응용 프로그램이 처음 실행될 때, 웹 응용 프로그램이 종료될 때, 새로운 사용자가 접속했을 때, 기존 사용자가 접속을 끊었을 때에 발생하는 이벤트였습니다.
Global.asax 파일 역시 이 4개의 이벤트를 지원하며 앞서 언급한 HttpApplication 클래스에 정의되어 있는 이벤트 또한 사용이 가능합니다. HttpApplication 클래스 외에 Global.asax 파일에 정의된 4개의 추가 이벤트는 다음과 같습니다.
Application_Start 이벤트
이 이벤트는 웹 응용 프로그램이 처음으로 시작될 때 발생하는 이벤트입니다.
Application_End 이벤트
이 이벤트는 웹 응용 프로그램에 접속한 사용자 중 마지막 사용자가 사이트에 대한 접속을 중단한 후에 발생하는 이벤트입니다.
Session_Start 이벤트
이 이벤트는 접속한 사용자와 웹 서버 사이에 생성되는 세션과 관련된 이벤트로 새로운 사용자가 접속하여 새로운 세션이 생성될 때 발생하는 이벤트입니다.
Sessioin_End 이벤트
이 이벤트는 접속한 사용자가 웹 사이트에 대한 접속을 종료했을 때 발생하는 이벤트입니다.
여러분이 Visual Studio .NET을 이용하여 웹 프로젝트를 생성하면 다음과 같은 코드를 갖는 Global.asax.cs 파일이 생성됩니다.
using System;
using System.Collections;
using System.ComponentModel;
using System.Web;
using System.Web.SessionState;
namespace iBravo2 {
/// <summary>
/// Global에 대한 요약 설명입니다.
/// </summary>
public class Global : System.Web.HttpApplication {
/// <summary>
/// 필수 디자이너 변수입니다.
/// </summary>
private System.ComponentModel.IContainer components = null;
public Global() {
InitializeComponent();
}
protected void Application_Start(Object sender, EventArgs e) {
}
protected void Session_Start(Object sender, EventArgs e) {
}
protected void Application_BeginRequest(Object sender, EventArgs e) {
}
protected void Application_EndRequest(Object sender, EventArgs e) {
}
protected void Application_AuthenticateRequest(Object sender, EventArgs e) {
}
protected void Application_Error(Object sender, EventArgs e) {
}
protected void Session_End(Object sender, EventArgs e) {
}
protected void Application_End(Object sender, EventArgs e) {
}
#region Web Form 디자이너에서 생성한 코드
/// <summary>
/// 디자이너 지원에 필요한 메서드입니다.
/// 이 메서드의 내용을 코드 편집기로 수정하지 마십시오.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
}
#endregion
}
}
보시는 바와 같이 몇몇 이벤트 핸들러 메서드가 이미 정의되어 있음을 보실 수 있을 것입니다. 그러면 이제 Global.asax 파일과 관련된 예제를 하나 구현해 볼까요?
다음 예제는 Global.asax 파일에서 발생할 수 있는 이벤트들의 발생 순서를 알아보는 간략한 예제입니다.
1 | <%@ Application %> |
2 | <script language="C#" runat="server"> |
3 | |
4 | void Application_Start(Object sender, EventArgs e) |
5 | { |
6 | } |
7 | |
8 | void Session_Start(Object sender, EventArgs e) |
9 | { |
10 | } |
11 | |
12 | void Application_BeginRequest(Object sender, EventArgs e) |
13 | { |
14 | Response.Write("<li>Application_BeginRequest"); |
15 | } |
16 | |
17 | void Application_EndRequest(Object sender, EventArgs e) |
18 | { |
19 | Response.Write("<li>Application_EndRequest"); |
20 | } |
21 | |
22 | void Session_End(Object sender, EventArgs e) |
23 | { |
24 | } |
25 | |
26 | void Application_End(Object sender, EventArgs e) |
27 | { |
28 | } |
29 | |
30 | void Application_AuthenticateRequest(Object sender, EventArgs e) |
31 | { |
32 | Response.Write("<li>Application_AuthenticateRequest"); |
33 | } |
34 | |
35 | void Application_AuthorizeRequest(Object sender, EventArgs e) |
36 | { |
37 | Response.Write("<li>Application_AuthorizeRequest"); |
38 | } |
38 | |
39 | void Application_ResolveRequest(Object sender, EventArgs e) |
40 | { |
41 | Response.Write("<li>Application_ResolveRequest"); |
42 | } |
43 | |
44 | void Application_AccuireRequestState(Object sender, EventArgs e) |
45 | { |
46 | Response.Write("<li>Application_AccuireRequestState"); |
47 | } |
48 | |
49 | void Application_PreRequestHandlerExecute(Object sender, EventArgs e) |
50 | { |
51 | Response.Write("<li>Application_PreRequestHandlerExecute"); |
52 | } |
53 | |
54 | void Application_PostRequestHandlerExecute(Object sender, EventArgs e) |
55 | { |
56 | Response.Write("<li>Application_PostRequestHandlerExecute"); |
57 | } |
58 | |
59 | void Application_ReleaseRequestState(Object sender, EventArgs e) |
60 | { |
61 | Response.Write("<li>Application_ReleaseRequestState"); |
62 | } |
63 | |
64 | void Application_UpdateRequestCache(Object sender, EventArgs e) |
65 | { |
66 | Response.Write("<li>Application_UpdateRequestCache"); |
67 | } |
68 | </script> |
코드가 매우 길어보이지만 사실 각각의 이벤트에 대해 이벤트가 발생했음을 웹 폼 페이지에 출력하기 위한 Response.Write 메서드를 호출하는 간단한 예제입니다. 일부 이벤트에 대해 구현이 생략된 이유는 해당 이벤트에서는 Response 클래스 객체를 사용할 수 없기 때문입니다. 왜냐하면 Response 클래스 객체는 클라이언트의 요청에 의해 발생하는 이벤트에서만 사용할 수 있기 때문입니다.
이 예제 코드는 이 상태로는 실행시킬 수 없습니다. 왜냐하면 앞서도 말씀드렸다시피 Global.asax 파일에 대한 액세스는 ASP.NET 실행 엔진이 원천적으로 차단하고 있기 때문입니다. 따라서 아무 일도 하지 않는 비어 있는 ASP.NET 웹 폼 페이지를 생성하고 이 파일을 브라우저로 접근하면 Global.asax 파일의 코드들이 실행된 결과가 웹 폼 페이지에 보여집니다.
윈도 탐색기에서 C:\Inetpub\wwwroot\ 디렉터리에 새로운 텍스트 파일을 생성하고 파일의 확장자를 *.aspx로 변경한 후에 브라우저를 통해 해당 파일을 요청하면 아래 그림과 같은 결과가 나타날 것입니다.

그림에서 보는 바와 같이 Global.asax 파일에 정의한 각 이벤트들이 발생하여 그에 해당하는 이벤트 이름들이 나열되는 것을 볼 수 있습니다. 또한 이 순서는 이벤트가 발생한 순서와도 일치합니다.
Global.asax 파일을 이용한 카운터 만들기
이제 Global.asax 파일을 이용하여 웹 사이트의 방문자 수를 카운트 하는 카운터를 구현해 보도록 하겠습니다. 앞서 구현했던 Global.asax 파일을 삭제하거나 이름을 변경하고 다음 코드를 포함하는 새로운 Global.asax 파일을 작성해 보도록 하겠습니다.
1 | <%@ Application %> |
2 | <%@ Import Namespace="System.IO" %> |
3 | <script language="C#" runat="server"> |
4 | |
5 | void Application_Start(Object sender, EventArgs e) { |
6 | string path = Server.MapPath("count.txt"); |
7 | FileInfo fi = new FileInfo(path); |
8 | |
9 | int count = 0; |
10 | |
11 | if (!fi.Exists) { |
12 | StreamWriter fs = fi.CreateText(); |
13 | fs.Write(count); |
14 | fs.Close(); |
15 | } |
16 | else { |
17 | StreamReader sr = fi.OpenText(); |
18 | count = Convert.ToInt32(sr.ReadToEnd()); |
19 | } |
20 | Application.Add("count", count); |
21 | } |
22 | |
23 | void Session_Start(Object sender, EventArgs e) { |
24 | Application.Lock(); |
25 | int count = Convert.ToInt32(Application["count"]); |
26 | Application["count"] = count++; |
27 | Application.UnLock(); |
28 | if (count % 5 == 0) { |
29 | string path = Server.MapPath("count.txt"); |
30 | StreamWriter sw = new StreamWriter(path); |
31 | sw.Write(count); |
32 | sw.Close(); |
33 | } |
34 | } |
35 | |
36 | void Application_End(Object sender, EventArgs e) { |
37 | int count = Convert.ToInt32(Application["count"]); |
38 | string path = Server.MapPath("count.txt"); |
39 | StreamWriter sw = new StreamWriter(path); |
40 | sw.Write(count); |
41 | sw.Close(); |
42 | |
43 | Application.Remove("count"); |
44 | } |
45 | </script> |
이 예제는 Global.asax 파일 내에서 텍스트 파일에 방문 카운터를 기록하는 예제입니다. 먼저 웹 응용 프로그램이 최초로 실행될 때 발생하는 Application_Start 이벤트의 코드부터 살펴보도록 하겠습니다. 이 이벤트에서는 카운트 숫자를 기록하는 파일이 존재할 경우 해당 파일에 기록된 값을 읽어 1을 증가시킨 후 Application 객체에 저장하고 파일이 존재하지 않는다면 새로운 파일을 만들고 Application 객체에 새로운 카운트를 기록합니다.
6번 라인에서는 카운터 숫자를 기록할 텍스트 파일을 제어하기 위해 count.txt라는 파일에 대한 물리적 경로를 얻어오기 위해 Server.MapPath 메서드를 호출하고 그 결과를 path 변수에 저장합니다.
그리고 7번 라인과 같이 이 path 변수에 저장된 물리적 경로를 이용하여 FileInfo 클래스의 인스턴스 객체를 생성합니다. 9번 라인에서는 카운트 값을 저장할 count 변수를 선언하고 0으로 초기화하고 있습니다.
이제 11번 라인과 같이 파일의 존재 유무를 확인하여 파일이 존재하지 않는다면 FileInfo 클래스의 CreateText 메서드를 호출하여 새 파일을 생성하고 초기 count 변수 값을 텍스트 파일에 기록합니다.
파일이 존재한다면 17번 라인과 같이 FileInfo 클래스의 OpenText 메서드를 호출하여 파일의 내용을 읽어와 count 변수에 대입한 후 20번 라인과 같이 이 값을 Application 객체에 추가합니다.
다음으로 매번 새로운 사용자가 접속할 때마다 발생하는 Session_Start 메서드를 살펴보도록 하겠습니다. 사용자가 처음 방문하게 되면 방문수를 1증가 시켜야 합니다. 이 때 Application 객체 내의 값을 다른 사용자가 변경하지 못하도록 하기 위해 24번 라인과 같이 Application 객체의 Lock메서드를 호출하여 Application 객체에 대해 잠금을 시도합니다.
다음으로 현재 Application 객체에 저장된 방문 수를 알아내기 위해 24번 라인과 같이 Application 객체의 count 아이템의 값을 가져와 count 변수에 저장합니다. 그런 후 26번 라인과 같이 count 변수에 저장된 값을 1증가 시킨 값을 다시 Application 변수에 대입하고 UnLock 메서드를 호출하여 잠금을 해제합니다.
그런데 카운트 값을 계속 Application 객체에 저장해 둔다면 불의의 사고로 인해 서버의 전원이 꺼지거나 하는 경우에는 데이터가 모두 사라지겠지요. 따라서 일정 간격으로 count.txt 파일에 카운트를 기록해 두어야 합니다. 예제에서는 카운트 값이 5의 배수가 될 때마다 count.txt 파일에 현재 카운트를 기록하도록 구현하였습니다.
29번 라인의 코드를 이용하여 현재 카운트가 5의 배수인지 여부를 검사한 후 5의 배수라면 31번 라인의 코드와 같이 StreamWriter 클래스를 이용하여 count.txt 파일을 열고 count 변수의 값을 기록합니다.
마지막으로 모든 사용자가 웹 사이트에 대한 접속을 종료하는 경우에도 현재 카운트를 count.txt 파일에 기록합니다. 이 코드는 방금 살펴본 Session_Start 이벤트에서 사용했던 코드와 동일하므로 설명은 생략하도록 하겠습니다.
다음으로 현재 카운트 숫자를 출력하는 웹 폼 페이지를 다음 코드를 이용하여 구현합니다.
1 | <%@ Page Language="C#" %> |
2 | <html> |
3 | <head> |
4 | <title>Global.asax</title> |
5 | <script language="C#" runat="server"> |
6 | void Page_Load(object sender, EventArgs e) { |
7 | string count = Application["count"].ToString(); |
8 | Response.Write("현재까지방문자는"); |
9 | Response.Write(count.ToString()); |
10 | Response.Write("명입니다."); |
11 | } |
12 | </script> |
13 | <body> |
14 | </body> |
15 | </html> |
이 예제 파일은 단순히 Application 객체에 저장되어 있는 count 변수 값을 출력하는 예제입니다. 이 예제의 실행 결과는 아래 그림과 같습니다.

현재로서는 처음 실행하였기 때문에 카운트가 1이 될 것입니다. 그런데 Session_Start 이벤트는 새로운 세션이 생성될 때 발생하는 이벤트 입니다. 따라서 새로운 세션을 생성하기 위해서는 매번 IE를 종료하고 다시 실행하여 해당 페이지에 접속해야 합니다.
출처: https://aladdin76.tistory.com/468 [Aladdin's Land]
ASP.NET 상태 관리
ASP.NET의 상태 관리는 응용 프로그램을 제작할 때 필요한 데이터를 임시 또는 반영구적으로 서버 또는 클라이언트에 보관하고 사용하는 방법을 말한다.
Copy of 데이터베이스를 사용하지 않고 간단하게 데이터를 저장하는 기능
개체명 | 설명 |
HttpCookie (Cookies) | 클라이언트 측 웹 브라우저에 간단한 데이터를 보관해 서버 성능을 향상시킬 수 있는 쿠키 개체를 생성한다. |
Cache | 클라이언트 측 메모리에 데이터를 보관해 응답 속도를 향상시킬 수 있는 캐시 개체를 생성한다. |
ViewState | 해당 웹 페이지 내에서만 어떤 정보를 임시로 보관하고자 할 때 가장 최적화된 방법을 제공한다. |
Application | 전체 웹 사이트 내에서 공유되어야 할 항목을 저장하는 데 사용된다. |
Session | 전체 웹 사이트 내에서 현재 사용자에게만 제공되는 항목을 저장하는 데 사용된다. |
QueryString | 현재 페이지에서 다음 페이지로 간단한 정보를 전달할 때 사용한다. |
실습 ( 현재 접속자 수 표시 카운터 만들기 )
실습을 위해 전역 응용 프로그램 클래스인 'Global.asax', 웹 폼 'FrmCounter.aspx'를 만들어 준다.
Global.asax
'Global.asax' 파일은 Application과 Session 레벨 이벤트를 제공하며 주요 이벤트 설명은 다음과 같다.
- Application_Start : 웹 프로젝트 가동 후 처음으로 사용자가 방문했을 때 발생한다.
- Application_End : 웹 프로젝트 가동 후 마지막 사용자가 나간 후 발생한다. 일반적으로 마지막 사용자의 최종 요청이 끝나고 20분 후에 발생한다.
- Session_Start : 각각의 사용자가 방문할 때 발생한다.
- Session_End : 각각의 사용자가 나가고 20분 후에 발생한다.
protected void Application_Start(object sender, EventArgs e)
{
// [1] 사이트 통계 1 / 3
Application["CurrentVisit"] = 0; // 현재 사용자
}
protected void Session_Start(object sender, EventArgs e)
{
// [2] 사이트 통계 2 / 3
Application.Lock();
Application["CurrentVisit"] = Convert.ToInt32(Application["CurrentVisit"]) + 1; // 현재 사용자
Application.UnLock();
}
protected void Session_End(object sender, EventArgs e)
{
// [3] 사이트 통계 3 / 3
Application.Lock();
Application["CurrentVisit"] = (int)Application["CurrentVisit"] - 1; // 현재 사용자
Application.UnLock();
}
FrmCounter.aspx
... 생략 ...
<div>
현재 : <asp:Label ID="lblNow" runat="server"></asp:Label> <br />
</div>
... 생략 ...
FrmCounter.aspx.cs
... 생략 ...
protected void Page_Load(object sender, EventArgs e)
{
// 현재 접속자 수 표시
lblNow.Text = Application["CurrentVisit"].ToString();
}
... 생략 ...

다음과 같이 Global.asax 파일은 루트경로에 만들어줘야 한다. 따로 디렉토리를 만들어서 실행한다해서 같은 디렉토리 내에 위치시키는 것이 아니다. 만약 같은 디렉토리 내에 위치시키면 Global.asax 파일은 실행되지 않는다.
FrmCounter.aspx 페이지를 실행한 후 웹 브라우저 창을 하나 더 띄운 다음 같은 경로로 접속하게 되면 카운터가 작동을 한다.

만약 웹 브라우저를 새로 띄우지 않고 새로 고침 버튼을 누르거나, 새 탭을 띄우면 같은 세션의 웹 브라우저로 인식하기때문에 카운터가 올라가지 않는다.
캐싱을 사용한 웹 페이지 성능 향상 기법
ASP.NET에서는 자주 바뀌지 않는 페이지에 대한 내용을 서버 측 캐시에 저장하고 있다가 클라이언트의 요청이 들어오면 바로 출력시킨다. 응답 속도를 개선할 수 있는 기법으로 이를 캐싱(Caching)이라고 한다.
실습 ( 캐싱을 이용한 웹 페이지 성능 향상 )
실습을 위해 웹 폼 사용자 정의 컨트롤인 'FrmCachingWebUserControl.ascx'와 웹 폼인 'FrmCaching.aspx'를 생성한다.
FrmCachingWebUserControl.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="FrmCachingWebUserControl.ascx.cs" Inherits="ASP_Practice.Day0128.Caching.FrmCachingWebUserControl" %>
<<%@ OutputCache Duration="5" VaryByParam="None" %>
현재 시간(웹 폼 사용자 정의 컨트롤) :
<asp:Label ID="lblTimeWebUserControl" runat="server" Text="Label"></asp:Label>
FrmCachingWebUserControl.ascx.cs
... 생략 ...
protected void Page_Load(object sender, EventArgs e)
{
// 현재 시간 출력 : 5초에 한 번씩만 출력
lblTimeWebUserControl.Text = DateTime.Now.ToString();
}
... 생략 ...
FrmCaching.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="FrmCaching.aspx.cs" Inherits="ASP_Practice.Day0128.Caching.FrmCaching" %>
<%@ Register Src="~/Day0128/Caching/FrmCachingWebUserControl.ascx" TagPrefix="uc1" TagName="FrmCachingWebUserControl" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
현재 시간(웹 폼) :
<asp:Label ID="lblTimeWebForms" runat="server" Text="Label"></asp:Label>
<hr />
<uc1:FrmCachingWebUserControl runat="server" id="FrmCachingWebUserControl" />
</div>
</form>
</body>
</html>
FrmCaching.aspx 페이지를 열고 코드 화면에 FrmCachingWebUserControl.ascx 파일을 드래그 해주면 저절로 Register 지시문이 생성된다. 물론 직접 코드를 입력해도 상관은 없다.
FrmCaching.aspx.cs
... 생략 ...
protected void Page_Load(object sender, EventArgs e)
{
// 현재 시간 출력 : 매번 바로 출력
lblTimeWebForms.Text = DateTime.Now.ToString();
}
... 생략 ...

다음 화면처럼 웹 브라우저를 새로고침을 해도 '현재 시간 (웹 폼 사용자 정의 컨트롤)'에 해당되는 시간은 5초에 한 번씩만 값에 변화가 있다. '현재 시간(웹 폼)' 같은 경우에는 새로고침 할 때마다 값의 변화가 있다. 위와 같은 방법으로 자주 바뀌지 않는 페이지를 매번 실행하지 않고 서버 측 메모리에 저장하고 있다가 바로 출력시켜 주는 방식을 사용해 웹 페이지의 성능을 향상시킬 수 있다.