Migrating from ASP to ASP+
ASP에서 ASP+로 마이그레이션 하기
written by Doug Seven
translated by Garzette(garzette@hanmir.com)
Microsoft가 2000년 7월 PDC에서 ASP+를 발표한이래,(많은 질문들 가운데) 한가지 질문이 뉴스그룹과
토론 포럼에 많이 나오게 되었다. 현재 본인의 웹 응용프로그램에서 ASP에서 ASP+로 바꾸는데 해야할
것은 무엇인가? PDC에서 발표자들은 코딩에서 바뀌는것은 최소일것이라고 했고, 바뀌게 되는 것은 운영
하기 어려울 정도는 아니라고 했다. 우리는 이 기사에서 그 주장이 맞는지 살펴볼 것이다.
ASP+를 알파칩에서 작동시키기 위해 필요한 것은:
# Windows2000 프로페셔널, 서버, Advanced Server
# IIS 5.0
# Internet Explorer 5.0 .NET 프레임워크 런타임
(앞으로 ASP+릴리즈는 Windows NT와 9x 에서 작동될 수 있을 것이다.)
여러분이 ASP 개발자라면, VBScript와 같은 현재 사용하는 기술들은 쉽게 Visual Basic.NET에서 여러분의
ASP+ 페이지의 코드로 바뀔 수 있다. 여러분은 또한 C#이나 Managed C++이나 코볼 등과 같은 다른 언어
에서도 또한 사용할 수 있다. 이 기사에서 필자는 조그만 웹 응용프로그램을 ASP에서 ASP+로 마이그레이션
하는 단계를 세부적으로 보일 것이다. 사용하는 샘플은 Visual Basic.NET 이다.
ASP와 ASP+는 서로 같이 있을 수 있고, 서로 상호 작동을 할도 수 있지만, 우리는 전체 사이트를 ASP+로 마이
그레이션 하는 방법을 선택했다. 마이그레이션 되는 사이트는 우리가 웹 개발을 시작할때 가르치는데 사용되는
샘플사이트이다. 우리는 이 사이트가 오늘날 인터넷에 있는 사이트 중에서 중간 이하의 크기를 가진 중요한
부분을 나타낸다고 느낀다. 이 사이트는 http://www.codejunkies.net/eVille/이고, 클래스나 주제에 대한
가상의 학생등록 사이트이다. Windows 2000에서 작동하고, VBscript 클라이언트 사이드 Javascript, ASP
3.0을 사용하고, COM을 사용하지 않고 Access 2000에 의해 구동된다.
ASP와 ASP+는 IIS 5.0에서 구동되는 같은 웹 서버에서, 나란히 작동되도록 설계되었다.(최종 릴리즈는
다른 버전을 또한 지원할 것이다). 이것은 한번에 한 페이지의 사이트를 마이그레이션 할 수 있게 하도록
한다. 원래 페이지는 ASP3.0에서 계속 작동될 것이고, 새로운 페이지는 ASP+ 서버 컨트롤과 기능을 사용하도록
전환될 것이다.
최초 고려사항
제일 처음 필요한 단계는 IIS가 유효한 디폴트 문서로서 default.aspx를 인식하게 하게 것이다. 이것은
Internet Service Manager에서 간단하게 수행할 수 있다.
# IIS 가상 디렉토리에서 Properties 다이얼로그 창을 연다.
# Document 탭에서 Add 버튼을 클릭한다.
# Default.aspx를 입력한다.
# OK 버튼을 두번 클릭한다.
eVille 사이트는 COM을 사용하지 않는다. 그래서 ASP 페이지나 include 파일에서 모든 데이터 Access는
ADO를 사용한다. 우리의 최초 목표중의 하나는 ADO+ Managed Provider의 성능 이점을 얻기 위해서 ADO에서
ADO+로 컨버젼 하는 것이다. ASP+는 전통적인 ADO의 사용을 허락한다. 하지만, ADO+로 마이그레이션 하는
실질적인 이점이 있다. 예를 들어 한개의 Dataset에서 여러 테이블을 추출하고, 더 빠른 성능향상을 가져오고
Server Control에 데이터를 바이딩하게 한다. ASP+ 페이지에서 데이터 접속은 ADO, ADO+, SQL Managed
Provider 에서 사용될 수 있다. 이 사이트는 SQL server를 이용해서 성능향상을 하는 것이 아니기 때문에,
우리는 ADO+의 가능한 관리에 남겨져 있다.
이 사이트의 모든 페이지는 몇 가지의 데이터 접속을 가지고 있다. 그래서 이것은 사이트를 마이그레이션
하는데 가장 큰 작업의 일부분이 될 것이다. 근본적으로, 모든 페이지는 페이지에서 필요로 하는 데이터를
추출하고 보이기 위한 몇 가지의 코드 수정을 가져야 한다. eVille의 아키텍쳐는 ADO 접속 코드를 포함하는
connect.inc 파일을 가지고, 이 파일은 모든 페이지에 쓰여진다. 커넥션이 생성되고, 사용할 준비가 되어있다.
데이터 베이스로 접속하는 프로세스와 ASP Data Control로 바인딩하는 컨트롤이 ASP+ 페이지의 새로운 Page_
Load 이벤트에서 사용되므로, 지금까지와는 약간 다른 접근 방법이 사용된다.
우리는 Pagelet을 생성시킴으로써 분리된 모듈에서 보편적으로 생성된 커넥션을 가지는 같은 개념을 사용
하였다. ASP+ Pagelet은 개발자에게 가상의 컨트롤을 생성시키게 하며, 이 컨트롤은 다른 오브젝트와 같이
프로퍼티와 메서드, 이벤트를 나타나게 할 수 있다. 우리의 솔루션은 ConnectToDB 메서드를 나타내는 Pagelet
을 생성하는 것인데, 이 connectToDB 메서드는 ADOConnection 오브젝트를 리턴한다(ADO에서 약간 문법이
바뀌었다). 우리는 다음과 같은 코드를 가지는 Pagelet을 생성하고, connect.aspc로 저장했다(Pagelet을
나타내는 확장명이다).
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.ADO" %>
<script language="VB" runat="server">
Public Function ConnectToDB() As ADOConnection
ConnectToDB = New ADOConnection("DSN=evilleDSN")
End Function
</script>
여러분은 system.Data와 System.Data.ADO 2개의 네임스페이스를 import 했다는 것을 알았을 것이다. 이런
네임스페이스는 ADO+ Managed Provider를 사용하는데 필요로 한다. 필자는 현재 MSSQL Server 2000 데이터베이스
에서 SQL Managed Provider를 사용하는 대부분의 샘플이 그렇듯 이것에 대한 많은 질문을 받았다. SQL server
를 사용하지 않는 데이터베이스에서도 ASP+는 ADO+ Managed Provider를 사용할 수 있다; 현재 응용프로그램
에서 여러분이 사용했던 ADO의 방식과 많은 부분이 같다. 여러분의 VB 응용프로그램에서 참조를 만드는 것과
유사한 네임스페이스를 import한다.
Pagelet의 사용은 우리에게 모듈에서 한번 생성된 커넥션과, 필요로 할때 모듈을 재사용하게 함으로써 현재
사이트 플랜을 유지하게 한다. 이것은 우리가 Include 파일이 가리키는것을 본인의 Pagelet의 인스턴스로
바꿀 필요가 있다는 것을 의미하고, 우리가 데이터베이스로 커넥션하는데 필요할때 ConnectToDB 메서드로
호출한다. 이 Pagelet을 사용하는 페이지에서, 우리는 ASP+ 를 사용하면서 페이지에서 등록할 필요가 있다.
우리가 TagPrefix, TagName, 소스(src) 를 지정하는 지향에서, Tagprefix와 TagName은 ASP에서 include 파일과
유사하게 Pagelet이 위치한 곳에서 사용될 것이다.
<%@ Register TagPrefix="seven" TagName="Connect"
src="_includes/connect.aspc" %>
우리가 막 등록했던 Pagelet을 위치시키기 위해서, 우리는 ASP+ 서버 컨트롤과 유사하게 다룬다:
<[TagPrefix]:[TagName] id=myPagelet runat=server />
실제코드는 아래와 같다.
<seven:Connect id=Connect runat=server />
ADO+에서 Recordset의 개념은 Dataset과 Dataviews의 조합으로 바뀌었다. 우리는 잠시 이것들에 대해서
알아보도록 하자. 먼저 default.asp에서 default.aspx로 마이그레이션했을때 코드가 어떻게 바뀌었는지
알아보자. 먼저 default.asp이다.
<!-- #include file="_includes/connect.inc" -->
<%
Dim cnEville_DB, rsUpcoming, strSqlUpcoming
Set rsUpcoming = Server.CreateObject("ADODB.Recordset")
strSqlUpcoming = " SELECT TOP 2 " & _
"Classes.Title, Sessions.Session_ID, " & _
"Sessions.Special, Classes.Description " & _
"FROM Classes INNER JOIN Sessions ON " & _
"Classes.Class_ID = Sessions.ClassID " & _
"WHERE (((Sessions.Date)>Date())) " & _
"ORDER BY Sessions.Date"
rsUpcoming.Open strSqlUpcoming,cnEville_DB
%>
ASP+에서 이것은 다음과 같이 바뀌었다:
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.ADO" %>
<%@ Register TagPrefix="seven" TagName="Connect" &_
src="_includes/connect.aspc" %>
<script language="vb" runat=server>
Sub Page_Load(Source As Object, E As EventArgs)
Dim dscUpcoming As ADODataSetCommand
Dim dsUpcoming As New DataSet
Dim strSQL As String
strSQL = "SELECT TOP 2 Classes.Title," & _
"Sessions.Session_ID, Classes.Description " & _
"FROM Classes INNER JOIN Sessions ON " & _
"Classes.Class_ID = Sessions.ClassID " & _
"WHERE (((Sessions.Date)>Date())) " & _
"ORDER BY Sessions.Date"
dscUpcoming = New ADODataSetCommand(strSQL, Connect.ConnectToDB())
dscUpcoming.FillDataSet(dsUpcoming, "Upcoming")
End Sub
</script>
데이터 접속의 핵심은 표준 SQL 문장에서 아무 변화도 없이 전송되는 것이다. 그러나 여러분이 볼 수
있듯이, 레코드셋을 만드는 구조는 ADODataSetCommand와 DataSet을 사용하여 바뀌었다.
Dataset으로 들어가기
ADO+는 Dataset과 Dataview라는 개념을 소개한다. Dataset은 데이터와 그 관계들이 한개 이상의 테이블
을 가지고 있다는 관점에서, 레코드셋의 집합과 같다. Dataview는 ADO 레코드셋과 유사한 이런 테이블들
중의 하나를 이용한다. 위에있는 예제에서, Dataset은 단지 한개의 테이블 Upcoming만을 가지고 있는데
그 테이블은 ASP+ 서버 컨트롤을 사용하는데 이용된다. 우리는 Dataset에 더 테이블들을 추가할 수 있다:
# 우리의 SQL 문장을 재정의 함
# ADODataCommand의 SelectCommand 속성을 새로운 ADODataCommand로 세팅함
# ADODataCommand의 FillDataSet 메서드를 호출함
FilldataSet 메서드는 단지 결과테이블을 SQL문장에서 메서드 호출로 통과되는 Dataset으로 만든다.
다른 테이블로 합치는 것은 다음과 같이 보일 것이다:
dscUpcoming = New ADODataSetCommand(strSQL, Connect.ConnectToDB())
dscUpcoming.FillDataSet(dsUpcoming, "Upcoming")
'Redefine the SQL statement
strSQL = "SELECT * FROM Students"
'Set the ADODataSetCommand's SelectCommand property
dscUpcoming.SelectCommand = New ADOCommand(strSQL, Connect.ConnectToDB())
'Add the results to the DataSet as a new table with the FillDataSet method
dscUpcoming.FillDataSet(dsUpcoming, "Students")
여기서 우리는 데이터베이스에 대한 커넥션을 만들고, 데이터를 Dataset으로 되돌려줄 것이다. 그러나;
우리는 이 데이터를 아직 사용할 수 없다.
HTML 테이블을 ASP+ Datalist로 컨버팅하기
우리가 데이터 저장창고로부터 얻은 데이터는 eVille을 통해서 제공된 다음에 나올 두개의 클래스들을
나타내는데 사용될 것이다. 설계상의 이유로, 표준 그리드는 적합하지 않다. 데이터는 클래스에 등록된
링크를 이용해서, Class, Title, 설명 등을 보여주면서, 전통적인 포맷으로 나타내져야 할 필요가 있다.
(링크는 Querystring에서 Session_ID를 통과시킨다). 아래에 원래의 ASP는 ADO 레코드셋을 통해서 각
레코드에서 새로운 줄을 만들어내는 반복된 페이지를 나타낸다 :
<table width="100%" border="0">
<tr>
<td class="headerRow">Upcoming Events</td>
</tr>
<%Do While Not rsUpcoming.EOF%>
<tr>
<td><p><b><%=rsUpcoming("Title")%></b><br>
<%=rsUpcoming("Description")%></p>
<p><a href="enroll.asp?SessionID=<%=rsUpcoming("Session_ID")%>">
Enroll Now!</a></p><br>
</td>
</tr>
<%
rsUpcoming.MoveNext
Loop
%>
</table>
ASP+에서 우리는 Datalist라는 새로운 서버 컨트롤을 사용한다. ASP+ Datalist는 테이블 기반의 포맷
에서 전통적인 레이아웃을 만들어내는 새로운 컨트롤 중의 하나이다. Datalist는 여러분이 할당한 등록정보에
기초를 둔 테이블의 row와 컬럼을 만들어내고, 레이아웃을 컨트롤하기 위해서 Template를 이용한다.
다음 예제에서, 우리는 각 row의 레이아웃을 형성하는데 ItemTemplate를 사용한다. 이 template은 추출된
각 cell의 레이아웃을 제어한다(한 레코드당 한개의 cell) :
<tr>
<td class="headerRow">Upcoming Events</td>
</tr>
</table>
<asp:DataList id="dlUpcoming" width="100%" runat="server">
<template name = "ItemTemplate">
<p><b><%# Container.DataItem("Title") %></b><br/>
<%# Container.DataItem("Description") %></p>
<p><a href="enroll.asp?SessionID=<%# Container.DataItem("Session_ID") %>">
Enroll Now!</a></p><br/>
</template>
</asp:DataList>
디폴트로 Datalist는 한개의 컬럼 테이블을 생성시킨다. 이것은 몇개의 프로퍼티를 바꾸어서 여러개의
컬럼을 생성하는데 세팅될 수 있다:
<asp:DataList id="dlUpcoming" width="100%"
RepeatDirection="Horizontal"
RepeatColumns="2"
runat="server">
다른 컨트롤을 표시하는 데이터들은 Datagrid(표준 테이블/그리드 레이아웃)와 Repeater(완전한 커스텀
레이아웃)을 포함한다.
만일 우리가 이페이지를 지금 보려고 한다면, 테이블에서 아무것도 보이지 않을 것이다. 왜냐하면, 우리가
레이아웃을 디자인하는 동안, 어떤 데이터도 제공하지 않았기 때문이다. 우리는 명시적으로 우리의 데이터를
ASP+ Datalist 컨트롤에 바인딩해야 한다(Dataset으로부터 온 Dataview). 우리는 이것을 우리가 보여주려고
하는 데이터의 컨트롤의 Datasource 프로퍼티와 DataBind() 메서드를 세팅함으로써 가능하다.
ASP+ 웹 응용프로그램이 추출되기전에 컴파일되기 때문에, 우리는 더이상 페이지에서 선형적인 처리 흐름에
바인딩할 수 없다. Datalist의 ID가 페이지를 다운로드 하는 중간까지 결정할 수 없다 하더라도(우리가
실제로 페이지에서 컨트롤을 사용할때), 우리는 페이지의 시작에서 Page_load 이벤트에서 컨트롤을 참조할
수 있다. 그렇게 함으로써, 우리는 페이지가 로드될 때 컨트롤에 데이터를 바인딩한다:
<script language="vb" runat=server>
Sub Page_Load(Source As Object, E As EventArgs)
. . .
cmdUpcoming.FillDataSet(dsUpcoming, "Upcoming")
dlUpcoming.DataSource = dsUpcoming.Tables("Upcoming").DefaultView
dlUpcoming.DataBind()
End Sub
</script>
Datalist와 같은 ASP+ 서버 컨트롤을 사용함으로써, 우리에게 컨트롤에 대한 프로그램적인 접근을 제공한다.
결과적으로 우리는 그 프로퍼티와 메서드에 대해서 코드를 쓸 수 있도록 하게 해준다. 첮번째 라인에서
우리는 Datalist의 Datasource 프로퍼티를 DataSet에서 Dataview(데이터의 한개 테이블)로 세팅한다.
특별히, 우리는 Dataset의 테이블 컬렉션에서 Upcoming 테이블의 디폴트 뷰로 그것을 세팅한다.
DataSource를 세팅했으므로, 우리는 그다음에 Datalist 컨트롤에 대한 SQL 쿼리로부터 온 결과를 바인딩
하면서 Datalist 컨트롤의 Databind() 메서드를 호출한다.
다른 페이지들을 컨버팅하기
페이지의 나머지 부분에서, 우리는 ASP+ Datalist 혹은 Repeater 컨트롤을 사용함으로써 유사한 단계
들이 이어진다. 이것은 표준 그리드 디스플레이라기 보다는 전통적인 데이터의 레이아웃을 위해 호출된
디자인으로 이것이 필요하다. 그 값이 체크되어있는지를 알기위한 한개의 필드가 필요하고, 그 필드의
값을 의지하는 classcatalog.aspx 페이지는 두개중의 하나의 가능한 추출된 결과물을 가진다. 이 페이지는
Repeater 컨트롤을 사용했고, 그래서, 우리는 컨트롤에게 하게 하지 않고, 명시적으로 테이블의 로우와
컬럼을 생성한다. 이것은 템플레이트안에서 작동된다. ASP에서 그것은 이렇게 보일것이다:
'Check to see if this is a special offer
If rsSessions("Special") = True Then
'If this class is a special, then write "Special Offer!"
Response.Write "<td valign=top align=center>" & vbCrLf
Response.Write "<a href=""classdetail.asp?SessionID="
Response.Write rsSessions("SessionID")
Response.Write """name=""Click for more detail"">"
Response.Write "Special Offer!"
Response.Write "</td>"
Else
'If it is not a special, write "--" to the column
Response.Write "<td valign=top align=center>--</td>"
End If
ASP+에서 같은 결과를 얻기 위해서 우리는 함수를 이용한다. 스크립트 블록에서, 아래에 보이는 것과
같은 Page_Load 이벤트와 같이, 다음과 같은 코드를 만든다:
Function CheckSpecial(ByRef blnSpecial As Boolean, _
ByRef intNumber As Integer) As String
If blnSpecial = True Then
CheckSpecial = "<a href=" & Chr(34) & _
"classdetail.aspx?SessionID=" & _
intNumber & Chr(34) & ">Special!!</a>"
Else
CheckSpecial = "--"
End If
End Function
우리는 그리고 나서 간단히 ASP+ Repeater로부터 함수를 호출한다:
<template name = "ItemTemplate">
<tr>
[ other data being displayed ]
<td valign=top align=center>
<%=CheckSpecial(Container.DataItem("Special"),
Container.DataItem("Session_ID"))%>
</td>
</tr>
</template>
컨테이너는 우리의 ASP+ Repeater 컨트롤로 참조된 데이터의 페어런트 오브젝트로 참조한다.
Container.DataItem("Special")과 Container.DataItem("Session_ID")을 호출하는 것은 페어런트
오브젝트에서(ASP+ Repaeter 컨트롤) 그런 컬럼의 값을 가지는 함수로 통과시킨다.
Session 변수로 작업하기
현재 있는 eVille의 ASP 버전은 만일 사용자가 로그인을 하지 않았다면, 사이트의 일부분에 접속하는
것을 제한한다. 머지않아 발표할 특별한 제안에서 보는 것과 같은 클래스에 등록하고, 현재 등록현황을
보는 것과 같은 기능은 제한된 영역이다. 로그인하기 언에 이런 영역을 접속하려고 한다면 로그인
페이지로 다시 redirect하게 될 것이다. 사용자는 자신의 사용자 이름과 암호를 폼에 채워 넣도록
한다. 이런것들은 데이터베이스에서 Student 테이블과 비교하게 될 것이고, 로그인이 성공적으로 된다면
Session 값인 blnLoggedIn은 true로 세팅될 것이다. 이 메서드는 한대의 서버에서 호스팅 되기때문에 이
사이트에서 유효하다. 다른 메서드들은 ASP+ Session혹은 SQL Session Store의 사용과 같이 Web Farm
에서 호스팅되는 웹 응용프로그램으로 사용될 것이다.
사용자 Input 유효화 체크하기
가장 소스가 많이 바뀌어지는 것 중의 하나는 사용자가 eVille 회원에 등록할때 사용자가 입력하는 내용을
캡춰하는 페이지에서 발생된다. signup.asp인 한 페이지는 새로운 회원이 가장 중요한 정보를 입력하는
데 사용될 것이고, 현재있는 회원이 그들의 정보를 업데이트 할때 사용될 것이다. 원래의 상태에서,
폼의 데이터는 cookie.asp 페이지로 전달된다(HTTP Post방식으로). 이 페이지는 폼의 데이터를 조사할
것이고, 에러가 있다면, 다시 signup.asp 페이지로 쿼리 스트링에서 에러 숫자와 함께 되돌려진다.
select case 문장에서 에러 숫자를 변환한다. 우리가 체크하는 에러는 다음과 같다:
# 사용자 이름이 입력되지 않았을 경우
# 암호를 입력하지 않았을 경우
# 암호와 확인하는 암호가 일치하지 않았을 경우
# 사용자 이름이 이미 데이터베이스에 있을 경우
첫번째 가능한 두가지 에러는 모든 input 필드에서 ASP+ 서버 컨트롤로 변환시키고 RequiredFieldValidators
를 추가함으로쏘 쉽게 다룰 수 있다. RequiredFieldValidators는 값이 ControlToValidate 필드에서 확인되는
서버컨트롤에서 입력되었는지를 단지 확인을 시켜줄 뿐이다:
<tr>
<td valign="top">
<asp:RequiredFieldValidator runat=server
ControlToValidate = "txtUserName"
Display = "static"
errorMessage="<b>*</b>"
ForeColor = "#CC3300" />
</td>
<td valign=top>User Name:</td>
<td valign=top>
<asp:TextBox id="txtUserName" size=25 runat=server /></td>
</tr>
이것은 매우 쉬운 솔루션이다. 그리고 우리는 폼에서 모든 input 필드에 RequiredFieldValidator를 추가
하기로 결정했다. 우리가 ASP에서 하듯이 입력된 값에 대해서 값에대한 체크를 추가하는 VBscript 함수를
사용하는 것보다, 간단히 우리가 유효화를 체크하기 원하는 각 컨트롤에서 RequiredFieldValidator를
추가한다.
암호와 암호확인에 대한 비교에는 ASP+ CompareValidator를 사용했다. 이 컨트롤은 우리에게 ControlToValidate
와 ControlToCompare 프로퍼티와 Operator 프로퍼티(이 예제에서 'Equal')를 세팅하게 함으로 가능하다.
두개의 정의된 컨트롤은 Operator 프로퍼티를 사용하여 비교된다. 이것은 확실히 if ~ then 문장으로 같은
내용을 구현하는 것보다 훨씬더 쉽고 빠른 솔루션이다.
<asp:CompareValidator runat=server
ControlToValidate = "txtConfirm"
ControlToCompare = "txtPassword"
Type = "String"
Operator = "Equal"
Display = "dynamic"
errorMessage="<b>*</b>"
ForeColor = "#CC3300" />
브라우져에 기초하여, ASP+ Validator 컨트롤은 클라이언트 자바스크립트 유효화 체크(IE4.0 이상버전)나
서버사이드 유효화 체크(모든 브라우져 가능)를 사용할 것이다. 유효화 체크가 어떻게 되는지 관계없이
서버사이드 유효화 체크는 항상 가능하다(클라이언트 사이드의 유효화 체크가 페이지를 해킹하는 것을
방지 하게 한다).
우리가 체크할 마지막 에러는 사용자가 이미 사용되고 있는 사용자 이름을 입력하는지 여부를 체크하는
것이다. 지금까지 우리는 클라이언트 사이드나 서버사이드를 사용한 서버 컨트롤로 ASP+ 유효화 체크를
수행했다. 마지막 에러에서, 우리는 몇가지의 전통적인 서버사이드 유효화 체크를 제공할 필요가 있다.
왜냐하면 요청된 사용자 이름이 유용한지 여부를 알아보기 위해서 데이터베이스에 접속하는 것이 필요하기
때문이다. 여기에서 우리는 ASP+ CustonValidator 컨트롤을 사용했다.
CustonValidator에서 우리는 클라이언트 혹은 서버사이드에서 우리 자신의 유효화 코드를 사용할 수 있다고,
그것에 대한 유효화 체크를 할 수 있다. 이 사이트의 원래 버전에서, 우리는 Form의 데이터를 cookies.asp
페이지로 통과시키는데, 이 페이지에서 유효화체크가 수행되고, 그리고 나서 에러가 발생된다면 에러 메세지
를 통과시킨다. 간단하게 사용하기 위해서, 우리는 signup.aspx 페이지로 되돌려 지고, 사용자의 input체크
를 하고 모든것이 OK일때 redirect 하게 될 것이다. 이것은 우리에게 ASP+페이지에서 중앙집중적이된 모든
유효화 체크를 하게 할 수 있다(ASP에서도 중앙집중적이었지만, cookies.asp에서였다).
아래에 사용자 이름에 대한 CustonValidator로 체크하는 방법을 나타낸다:
Function ValidateUserName(ByVal objSource As Object, ByVal strUserName As String) As Boolean
Dim dscUser As ADODataSetCommand
Dim dsUser As New DataSet
Dim dvUser As DataView
Dim strSQL As String
strSQL = "SELECT UserName FROM Students " & _
"WHERE UserName = '" & strUserName & "'"
dscUser = New ADODataSetCommand(strSQL, Connect.ConnectToDB())
dscUser.FillDataSet(dsUser, "User")
UserGrid.DataSource = dsUser.Tables("User").DefaultView
UserGrid.DataBind()
If UserGrid.Items.Count > 0 Then
ValidateUserName = False
Else
ValidateUserName = True
End If
dvUser = New DataView(dsUser.Tables("User"))
End Function
</script>
[page stuff?
이 컨트롤은 Form Post에서 ValidateUserName 함수를 연속해서 부른다. Dataset을 사용하여 우리는
요청된 User Name과 데이터베이스에 있는 User Name을 매치시키는 쿼리문장을 호출한다. 만일 이름이
사용되고 있다면, 한개의 레코드가 리턴될 것이고 그렇지 않다면 레코드가 리턴되지 않는다. 이것을
체크하기 위해서, 우리는 결과를 숨겨진 Datagrid(Visible 속성을 false로 둔다)를 바인딩하고, 그리고
나서 Item Collection과 Count 프로퍼티를 체크한다. 만일 Count가 0보다 크다면, 요청된 User Name이
이미 존재한다는 것이다. 많일 User Name이 존재한다면 메시지를 보일것이고, 그렇지 않다면, 우리는
폼에서 계속 작업을 할 수 있다.
이런 형태의 유효화 체크가 실현가능하다는 것을 염두에 두자. 이런 형태의 함수로 설계된 Datareader
컨트롤이 있다. Datareader는 Datagrid에 바인딩 해야하지 않고도 이런 형태의 조사를 수행하게 할 수
있다. 그러나 ASP+ Alpha에서 Datareader에 버그가 있고, 작동되지 않는다. 이것은 Beta 1 릴리즈에서는
수정이 될 것이다. 이런 실현가능한 코드는 현재 .NET 프레임워크에서 ASP+에 작동되는 사이트에서
얻을수 있도록 제공된다.
사용자로부터 데이터를 모으기
일단 모든 input이 유효화가 된다면, 우리는 cookies.aspx페이지로 가서 데이터베이스로 데이터를 입력
한다. 그리고 사용자를 로그인한다. signup.aspx에서 일단 데이터가 유효화체크가 되면, 우리는 폼의
모든 값을 redirecting하기 전에 세션값에 입력한다.
<asp:DataGrid id="UserGrid" visible=false runat=server />
<asp:CustomValidator runat=server
ControlToValidate = "txtUserName"
onServerValidationFunction = "ValidateUserName"
errorMessage = "The User Name you chose is taken. Please chose another."
ForeColor = "#CC3300"
display = "dynamic"
/>
<script language="VB" runat="server">
Sub Page_Load(Source As Object, E As EventArgs)
If Page.IsPostBack And Page.IsValid Then
'Create the Session Variables froim the Form Fields
Session("strFName") = Request.Form("txtFirstName")
Session("strLName") = Request.Form("txtLastName")
Session("strAddress") = Request.Form("txtAddress")
Session("strCity") = Request.Form("txtCity")
Session("strState") = Request.Form("txtState")
Session("strZipcode") = Request.Form("txtZipcode")
Session("strEmail") = Request.Form("txtEmail")
Session("strPhone") = Request.Form("txtPhone")
Session("strUserName") = Request.Form("txtUserName")
Session("strPassword") = Request.Form("txtPassword")
Response.Redirect("cookie.aspx")
End If
. . .
End Sub
</script>
cookies.aspx에서 우리는 입력될 값들로 세션값을 사용하여 표준 SQL 문장을 생성한다. 우리는 같은
결과를 얻는 Querystring안에 있는 name/value의 짝을 사용하여 쉽게 사용될 수 있다. 데이터베이스에
값을 입력하기 위해서, 우리는 ADOCommand 오브젝트를 사용한다. 우리는 SQL문장과 ADOConnection
오브젝트를 ADOCommand로 통과시킨다. 일단 ADOCommand가 셋업되면, 우리는 커넥션을 열고,
ADOCommand.execute를 호출한다:
<script language="VB" runat="server">
Sub Page_Load(Source As Object, E As EventArgs)
Dim cnCon As New ADOConnection
Dim dcAdd As ADOCommand
Dim strSQL As String
strSQL = "INSERT INTO Students " & _
"(FirstName, LastName, Address, City, State, " & _
"Zipcode, Phone, Email, UserName, [Password] ) " & _
"VALUES (" & _
"'" & Session("strFName") & "', " & _
"'" & Session("strLName") & "', " & _
"'" & Session("strAddress") & "', " & _
"'" & Session("strCity") & "', " & _
"'" & Session("strState") & "', " & _
"'" & Session("strZipcode") & "', " & _
"'" & Session("strPhone") & "', " & _
"'" & Session("strEmail") & "', " & _
"'" & Session("strUserName") & "', " & _
"'" & Session("strPassword") & "'" & _
")"
cnCon = Connect.ConnectToDB()
dcAdd = New ADOCommand(strSQL, cnCon)
cnCon.Open()
dcAdd.Execute()
End Sub
</script>
이 새로운 데이터는 데이터베이스에 더해지고, 새로운 학생이 로그된다. 유사한 기능이 학생이
학급에 등록할때 학생id, 세션id등을 등록 테이블에 입력할때 사용된다.
요 약
작은 ASP사이트를 ASP+로 마이그레이션하는데 맞이하는 몇가지 도전들을 전체적으로 살펴보는동안,
우리는 주된 영역을 커버할 수 있었다. 우리가 해야할 변화는 있다고 해도 거의 적다. 우리는 확실히
웹 서비스, 아웃오브 세션 스테이트나 새로운 보안 스키마와 같은 ASP+의 새로운 특징의 대부분을
이용하지는 않았다. 그러나 우리는 그 작업을 시작하려는 위치에 있다. 이 사이트는 .NET 프레임워크
에서 작동된다. 그리고 request를 이용하는 브라우져, 다른 유효화 기술을 제공하는 새로운 서버 컨트롤,
그리고 ADO+ Datasets 등을 기초로 rendered HTML, DHTML와같은 몇가지 ASP+의 특징을 이용한다. 그리고
이것들은 우리에게 다른 오브젝트들을 생성시키지 않고 한번에 여러개의 테이블을 얻을 수 있게 한다.
'ASP.NET' 카테고리의 다른 글
responseText 속성을 이용한 단순 문자열 다루기 (0) | 2007.12.27 |
---|---|
ASP.NET의 캐시 구성 개체 만들기 (1) | 2007.10.17 |
Releasing the Source Code for the .NET Framework Libraries (0) | 2007.10.15 |
Smart Client (0) | 2007.10.15 |
ClientScriptManager.RegisterStartupScript 메서드 (Type, String, String, Boolean (0) | 2007.09.13 |