on
지식관리_ASP.NET_웹폼
지식관리_ASP.NET_웹폼
20210407
ASP.NET 웹폼이란 무엇인가?
ASP.NET에 들어서면서 페이지 작성시 가장 먼저 개발자들이 만나게 되는 것이 바로 웹 폼(WebForm)이라는 것입니다. 웹에서 사용하는 폼이라는 의미인데, 이것은 마치 웹 페이지를 일반 어플리케이션 폼을 작성하듯이 만들 수 있게 해 주는 웹 페이지 구조를 말합니다.
여러분이 VC++ 이나 VB 등을 다루어 보았다면, 여러분이 윈도우를 꾸미기 위해서 제공되는 폼 위에다가 필요한 컨트롤들을 그냥 Drag and Drop 으로 올려다 놓으면 그것으로 폼이 후딱 만들어지던 것을 보셨을 겁니다. VB나 VC++ 에서는 간단한 구성의 폼을 하나 꾸미는 데는 10초도 걸리지 않습니다. 그렇게 쉽고 간단하지요. 그러한 기능이 이제 Visual Studio.NET을 통해서 제공이 된다는 것입니다. 물론, 직접 손으로 예전처럼(ASP 때처럼) 코딩해도 상관은 없습니다.
하지만, 그렇게 만들어지는 페이지의 HTML 소스나 소스코드를 보면 그리 쉽게 이해가 가지 않는 모습을 띄고 있지요. 이는 ASP.NET 의 웹 페이지 자체가 하나의 객체로써 구성되어지고, 상속되어진 클래스의 구성을 하고 있기에, 언어기반의 프로그래밍 경력이 없는 이들에게는 대단히 어렵고 복잡하게 받아들여질 수 있기 때문입니다. 잠시 후 이러한 예제들을 만나보게 될 것입니다.
ASP.NET 은 이벤트 중심의 프로그래밍을 지향합니다. ASP 때의 코딩방식에서 완전히 탈피한 스타일이라 이 부분은 ASP 식의 프로그래밍에 익숙하신 분들은 오히려 혼란스러울 수 있기까지 한 부분일 수 있습니다.
자바스크립트에 익숙한 사람이라면 흡사 코드가 클라이언트측에서 어떤 이벤트를 처리하는 부분처럼 느껴질 수도 있습니다. 그리고, 이 예제는 솔직히 굳이 서버에서 처리하지 않아도 되는 예제이기는 합니다. 하지만, 우리에게 중요한 것은 이 페이지의 소스가 서버에서 처리된다는 것입니다.
현재 웹개발 방식은 더이상 서버 상에서, HTML을 처리할 필요가 없습니다. 클라이언트의 성능이 좋아졌기 때문에, 서버의 역할은 많이 축소되고, 클라이언트 단에서 Javascript 또는 Typescript를 통해 데이터를 가공하기도 하고, 여러가지 비즈니스 로직을 수행합니다.
그러나 웹폼은 서버 상에서 HTML 을 가공하여, 다시 클라이언트로 보내주는 방식으로 동작합니다. 상대적으로 클라이언트의 역할은 적고, 서버의 역할은 많은 편입니다. 2008년도 이전의 개발접근 방식이라서, 현재의 개발 프레임워크와는 개발 접근 방식이 다릅니다.
그래서, 현재는 대부분이 싱글 페이지 프레임워크 형식에 컴포넌트 기반 개발 방식을 따르기 때문에 아래의 순서대로 접근하게 됩니다.
0. 프레임워크의 이상적인 전체구조 파악
- Main에서 시작해, Routor를 통해 페이지를 이동하는 방식
1. 라우터 정의
2. 각 페이지별 템플릿 / 스타일 / 로직으로 이루어진 Page Component 구현
- 상황에 따라 Popup으로 쓰일 Page Component 구현
3. 템플릿 / 스타일 / 로직으로 이루어진 Common Component 구현
- 데이터 전달 흐름
[Parent -> Child, INPUT 변수], [Child -> Parent, OUTPUT 이벤트]
4. 공용 서비스(Service) / 유틸(디렉티브, 파이프, 가드) 구현
5. DB 모델(Model)
그러나, 웹폼은 일단 페이지별로 개발을 수행합니다. ex) articleList.aspx, writeArticle.aspx 형식으로, 페이지를 구현한 후에 http request를 통해 html 페이지를 post/get하는 방식으로 동작한다고 보면 된다. 웹폼은 기존 Form처럼 만들면, HTML 형식으로 변환해주는 기술이 아닐까?
마치 vb 6.0의 Web Version이라고 할 수 있다.
Sub Button1_Click(Source As Object, E As EventArgs) lblResult.Text = "안녕하시렵니까? " & txtName.text & " 님" End Sub 이름 :
소스에서 등과 같은 태그가 여러분을 당황스럽게 할런지도 모르겠습니다. 이것은 웹 폼 서버 컨트롤이라 불리는 것으로 기존의 HTML 컨트롤을 대신하게 될 서버와 연동이 가능한 컨트롤들입니다. 이름에서 느껴지듯이 이들은 각각 입력을 위한 텍스트 박스, 버튼, 레이블 이지요. 각 컨트롤의 속성으로는 runat="server" 라는 것이 들어있음에 주목하세요. 이 컨트롤들은 서버에서 연동되는 컨트롤이기에 이러한 속성이 지정되어져 있습니다. 컨트롤의 이름(Label, Textbox, Button)과 속성값(ReadOnly, Enabled, TabIndex 등)이 어디서 많이 봤나 했더니, vb 6.0에서 윈폼을 만들 때 보던 값들이었다.
각각의 컨트롤은 id 속성으로 구분을 하며, 서버에서는 그 ID로 각각의 컨트롤을 제어할 수 있습니다. 소스에서는 우리가
ASP.NET의 처리방식
클라이언트 브라우저로부터 페이지가 처음 요청되는 순간, IIS는 웹 페이지를 파싱하는 ASP.NET 엔진으로 일단 페이지를 읽어들입니다. 그리고, 이를 JIT(just-in-time)로 컴파일을 합니다. 그리고, 페이지의 컨트롤들을 HTML로서 생성하면서, 컴파일된 코드가 실행되고, 호출된 이벤트가 있다면 그 이벤트 코드가 실행이 되어져서, 컨트롤과 상호작용을 하고, 출력 HTML은 생성됩니다. 그리고, 이 결과 HTML 페이지는 클라이언트의 브라우저로 넘겨지는 것입니다.
브라우저 : 페이지요청 -> IIS(ASP.NET 엔진) : 페이지 파싱 - JIT 컴파일 - HTML 파일 출력 전달 -> 브라우저
JIT Compile의 3가지 동작
1. 페이지의 컨트롤들을 HTML로서 생성
2. 컴파일된 코드가 실행
3. 호출된 이벤트가 있다면 그 이벤트 코드가 실행이 되어져서, 컨트롤과 상호작용
페이지가 처음 요청되는 경우는 위와 같은 동작을 하지만, 두번 이상 호출되어지면 컴파일을 하는 작업은 사라지고, 이미 컴파일이 되어져 있던 것을 사용하게 되기에, 이후 요청시는 페이지의 수행시간이 단축되어 집니다. 이를 그림으로 표시하면 다음과 같습니다.
Visual Studio 에서 webform(.aspx)를 생성, 즉 ASP.NET 페이지를 만들게 되면 기본적으로 Code Behind 로써 페이지가 구성이 됩니다. 즉, 페이지의 컨텐츠 페이지와 실제 로직 부분이 각각의 페이지로 구성되어지고 연결되어진다는 것이지요. 사실 .aspx 는 윈폼처럼 Web 페이지를 만들려고 고안된 것이기 때문에, 좌표로 위치를 지정할 수 있는 방식(DHTML?) 또는 기본 HTML 방식으로 만들수 있다고 한다. 그러나, 기본 HTML 방식을 쓰는 것이 표준에 맞지 않을까 싶다.
Angular의 경우, 하나의 Page Component가 클라이언트 내에서 해당 페이지에 대한 요청을 처리하고 Rendering 하는데까지 모두 총괄한다. 그러나 Asp.net의 Webform Page는 클라이언트에서 처리할 부분과 서버에서 처리해주어야할 부분을 명확하게 나누어 구현한다. 이는 모던 프레임워크 내에서는 브라우저가 HTML을 모두 처리할 수 있는 성능이 되는 반면, Webform이 나오던 시기에는 성능상 ASP.NET 서버 상에서 HTML을 처리 후, 브라우저로 보내야했기 때문이다. 실제로 .aspx 파일 내부에 runat="server"라고 명시되지 않은 태그나 스크립트 등은 클라이언트 브라우저 상에서 처리하게 될 것이다.
이런 특성 때문에, 클라이언트에서 모두 데이터를 처리하고, HTML을 처리하는 경우, 한 페이지에서 새로고침이나 별도 요청 없이 여러가지 작업을 할 수 있는 반면, Webform은 하나의 작업을 처리하려면 서버를 다녀와야되기 때문에, 동일한 페이지 내부에서도 Submit이 필요한 것이다. 그리고 Submit 이후, 여러번 페이지 요청 때문에 초기화를 막고 기존 폼 상태를 유지하기 위하여 내부적으로 ViewState라는 개념을 가지고, Submit 이후에도 상태를 유지한다.
하나의 ASP.NET 페이지에는 오직 하나의 웹 폼만이 존재할 수 있다는 사실도 기억하자. 그리고, 모든 서버 컨트롤들은 반드시 웹 폼 구역안( ) 안에 존재해야만 한다. 그래야만 프로그래밍적으로 제어할 수 있다.
서버 컨트롤은 서버에서만 인식되는 컨트롤이다.
서버 컨트롤은 서버에서만 인식되는 컨트롤이다. 클라이언트는 서버에 그러한 컨트롤이 있는지에 대해서는 전혀 알지 못한다. 또한, 클라이언트에서는 서버측의 컨트롤에 접근할 수도 없다. 우리가 작성한 모든 코드는 서버에서 실행시에 사용되는 컨트롤들이다. 클라이언트는 단지 자신이 받아 볼 결과에만 관심이 있다. 다시 말해서, 클라이언트에게는 원래의 aspx 소스를 훔쳐볼 방법이 없다.
버튼을 클릭하는 것은 클라이언트 측의 행동이고, btnSubmit_OnClick 함수는 서버측에 있다. 클라이언트측에서 서버측의 함수를 호출할 방법은 사실상 없다. HTTP 라는 프로토콜은 연결이 유지되는 환경이 아니기 때문이다. 그럼에도, 이와 같은 방법이 가능한 것은 클라이언트가 버튼을 클릭할 경우에 무조건 폼이 서버로 서브밋되기 때문이다. 폼의 모든 데이터들이 서브밋이 되어지며, 동시에 현재 서버측의 btnSubmit_OnClick 라는 이벤트 함수를 호출하였다라는 정보도 같이 서버로 전송되어진다. 서버에서는 현재의 aspx 페이지를 다시금 생성하면서 추가적으로 btnSubmit_OnClick 라는 함수도 실행한다. 대략 이러한 식으로 페이지가 동작한다는 사실을 잠시 알아두기 바란다.
자기 자신에서 서브밋 된다는 것은 Postback이라고 지칭하며, 이는 컴파일 될 때 form action="자기자신의 url.aspx" 형식으로 변환됨으로써 구현한다.
만약 버튼이 클릭될 경우, 폼은 자기 자신 페이지로 전송이 되고, 버튼이 클릭하여 발생한 이벤트인 btnSubmit_OnClick 이라는 함수가 실행되어진다는 것은 알았는데 그런데, 만일 폼을 자기 자신 페이지가 아닌 다른 페이지로 전송한다면? 즉, 폼 태그 부분을 다음처럼 수정하여 action 을 다른 페이지로 지정한다면? 다른 페이지 내에 해당하는 클릭 콜백함수가 존재하지 않으면 문제가 발생하지 않겠는가? 그렇기 때문에, 웹 폼의 action을 개발자가 바꾸어도 ASP.NET은 그 경로를 자기자신 페이지로 강제한다.
KEY : 버튼을 클릭했을 때 일어나는 일련의 과정. POSTBACK.
포스트백!! 무척이나 앞으로 자주 만나게 될 단어이다. 굳이 번역하자면 "자기 자신으로의 전송" 이 되겠다. 너무 길다? 그렇다면 그냥 "되전송" 이란 말도 나쁘지 않아보인다
클래스의 이름은 일반적으로 aspx 페이지의 파일명을 기준으로 한다. 클래스 이름은 현재의 웹 어플리케이션 내에서 절대적으로 고유한 이름을 사용해야만 하는데, 파일명 또한 그러하기 때문에, 주로 파일명을 클래스 명으로 사용하는 것이다.
Page 태그의 Src 속성에 동일한 값을 줌으로써, 여러개의 .aspx 파일을 하나의 .cs 파일에서 처리하게 할수는 있으나, 일반적이지 않다. Inherit 속성이란 만약, .cs 파일 내에 아래와 같이 두개의 클래스를 선언 했을 경우, 선택하기 위함이지만, 일반적으로 사용되지는 않는다.
<%@ Page language="c#" Src="Start.cs" Inherits="AnotherStart"%> // .cs 파일 내에 두개 이상의 class가 있을 경우, Inherits 속성으로 클래스명을 주어 선택할 수 있다. // 그러나 대부분 클래스가 하나인 경우가 많다. // .cs 파일도 여러개의 .aspx가 공유할 수 있으나, .aspx당 하나의 .cs를 만드는 것이 일반적이다. <%@ Page language="c#" Src="Start.cs" Inherits="Start"%> //이전 우리가 수작업을 통해서 코드 비하인드를 구성했을 경우에는 Src 라는 속성을 사용했었지만, //.net은 Src가 표준이지만, VS.NET에서만 Codebehind 라는 속성을 사용한다. <%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="TaeyoBook.WebForm1" %> // AutoEventWireup의 경우 기본값(true)로 나두어도 상관 없지만, VS.NET은 false를 기본적으로 적용한다. // 각각의 Event 마다 CodeBehind에 수동으로 입력해야하는 경우가 대부분이므로, false로 지정해도 상관없다.
using System; using System.Web.UI; using System.Web.UI.WebControls; public class Start : Page { protected Label lblMsg; public void btnSubmit_OnClick(Object sender, EventArgs e) { lblMsg.Text = "클릭!!!"; } } // 새롭게 추가된 클래스. public class AnotherStart : Page { protected Label lblMsg; public void btnSubmit_OnClick(Object sender, EventArgs e) { lblMsg.Text = "Good Morning~~ ASP.NET!!"; } }
VS.NET은 페이지 생성시 기본적으로 페이지 명 뒤로 cs라는 확장자를 붙인 WebForm.aspx.cs 와 같은 C# 페이지(코드 비하인드 클래스 페이지)를 생성해 주고, 연결해 준다. 이러한 코드 비하인드 페이지는 System.Web.UI.Page 라는 클래스로부터 상속 받은 하나의 C# 클래스로 구성된다. 그 클래스의 이름은 기본적으로 aspx 파일의 파일명을 사용하게 되는데, 우리의 경우 그 클래스 이름은 WebForm1이 된다.
AutoEventWireup 이라는 속성은 페이지의 이벤트가 자동으로 연결되는지 여부를 나타내는 것으로, 이벤트의 자동 연결이 설정할 것이면 true 를 그렇지 않으면 false 를 지정한다. 이 값을 지정하지 않을 경우는 자동으로 true 가 지정되는 데, 그럴 경우 페이지 내에서 발생하는 이벤트들은 모두 UI 페이지에서 OnClick=”btnSubmit_OnClick” 와 같이 이벤트 핸들러에 지정한 것만으로 처리가 이루어진다. 하지만, 코드 비하인드 페이지가 UI 페이지와 어떠한 이벤트를 주고 받을 경우(거의 모든 경우를 의미한다)에는 사실상 코드 비하인드 페이지 내에서 그 이벤트를 코드로써 등록 해 주는 추가적인 작업이 필요하다. 마치, 비하인드 페이지에서 UI 페이지의 개체를 접근하기 위해서 개체의 변수를 선언해 주었던 것처럼 말이다.
정리하자면, AutoEventWireup을 fasle 로 지정할 경우는 여러분이 코드 비하인드 페이지에 추가적인 이벤트 연결 코드를 작성해 주어야 하는 것이고, true로 지정할 경우는 어떠한 추가적인 코드도 필요하지 않음을 의미한다. 대부분 수작업으로 코드 비하인드를 구성할 경우는 일반적으로 true 인 기본값을 그대로 사용하지만(즉, 아예 이 속성을 코딩하지 않지만), VS.NET은 명시적으로 이것을 false 로 지정한 다음, 그러한 이벤트 연결 코드를 자체적으로 제공해 준다.
AutoEventWireup을 True로 주면, 페이지 내에서 발생하는 이벤트들은 모두 UI 페이지에서 OnClick=”btnSubmit_OnClick” 와 같이 이벤트 핸들러에 지정한 것만으로 처리가 이루어진다.
from http://sddev.tistory.com/167 by ccl(A) rewrite - 2021-04-07 16:00:49