By 셸리 파워스(Shelly Powers), Developing ASP Components, 2nd Editon의 저자
마이크로소프트의 새로운 .NET 환경에 관해 보았다면, 기존의 ASP 서버 환경과 ASP.Net이 얼마나 다른지 알고 있을 것이다.
비주얼 베이직 프로그래머는 ASP 스크립팅 블록에 쓰이는 기본 언어인 C#에 더 이상 가변형(Variant Data Type)이 없다는 사실에 여전히 당황해하고 있다.
이러한 차이점이 있긴 하지만, 지금까지 작성했던 코드를 재작성하거나 다시 만들지 않고 .Net, 특히 ASP.Net으로 마이그레이션(migration) 할 수 있다.
사실 기존의 ASP COM/COM+ 컴포넌트를 수정하거나 재컴파일하지 않고, 새로운 ASP.Net 페이지나 새로 수정한 ASP.Net 페이지에서 이용할 수 있다.
필자는 얼마 전에 윈도우 2000/COM+ 환경에서의 ASP 컴포넌트에 대한 책(
Developing ASP Components, 2nd Edition)을 쓴 적 있다. 그래서 .NET이 프로덕션 환경에 최종적으로 릴리스될 때 기존에 있던 ASP COM/COM+ 컴포넌트를 새로운 .Net 환경에서 사용할 수 있는지를 보여주기로 했다.
먼저 기존에 있는 ASP 페이지를 가지고 ASP에서 ASP.Net으로 옮기자.
ASP에서 ASP.NET으로 전환하기
ASP.Net에서 가장 중요한 사실은 같은 IIS 서버에 ASP와 함께 존재한다는 것이다. 사실 같은 디렉토리 안에 위치시킬 수도 있다. 이는 여전히 ASP 애플리케이션을 위한 지원을 제공하면서 ASP.Net으로 옮길 수 있다는 의미이다. .Net 으로 옮기기 위한 충분한 시간이 있으니, 안심해도 된다.
새로운 ASP.Net 환경에서는 사용자의 페이지가 어떻게 변하는지, 필자의 책에 있는 예제로 알아보자. 물론 필자는 윈도우 2000 프로페셔널 머신에 .Net 지원을 설치했다.(.Net 지원이 없으면,
Visual Studio .Net에서 첫째 베타를 다운로드 하자)
책에서는 웹 서비스, 폼과 같은 .Net의 기능에 관해서는 설명하지 않으므로, 각각의 ASP 페이지를 기본 ASP 페이지로 변환하기 위해 파일이름을 .asp에서 .aspx로 바꾸자. 필자는 7장("Creating a Simple Visual Basic ASP Components")의 asp0701.asp 예제 파일로 마이그레이션 했다. Asp0701.asp의 소스는 다음과 같다.
<%
Dim obj
Set obj = Server.CreateObject("asp0701.First")
Dim msg
msg = obj.sayHello("World!")
Response.Write "" & msg & ""
Set obj = Nothing
%>
|
역주 : 비주얼 베이직에서 프로젝트 이름은 asp0701로 하고, 클래스 명은 first로 하여 컴파일한다. 프로젝트 등록정보, 일반 탭에서 "무인실행"을 선택한다.
Option Explicit
Public Function SayHello(ByVal strName As String) As String
"create message
Dim strMessage As String
strMessage = "Hello " & strName
"return from method
SayHello = strMessage
End Function
|
스크립트에서 액세스하는 컴포넌트는 비주얼 베이직 6.0 컴포넌트로 "Hello"라는 단어를 출력한다. 이름을 바꾼 후에 브라우저에서 액세스를 시도했고, 그림 1과 같은 .Net 컴파일 에러를 받았으니, .Net 환경 설정은 옳았다.(항상 긍정적인 면을 찾자.)
그림 1
에러는 VB 컴포넌트를 액세스하는 Set 키워드를 이용하기 때문에 발생했다. .Net 환경에서는 객체 인스턴스화를 위해서 Set과 Get을 지원하지 않는다.
이러한 차이점이 있긴 하지만, 지금까지 작성했던 코드를 재작성하거나 다시 만들지 않고 .Net, 특히 ASP.Net으로 마이그레이션(migration) 할 수 있다.
정말 간단히 수정된다. 필자는 이처럼 간단히 수정되는 것이 좋다.
예제에서 Set을 제외하고 다시 시도했다. 그러나 두번째 시도도 여전히 실패다. Response.Write 메소드의 인자 목록에 괄호가 빠졌기 때문이다. NET에서 모든 메소드는 괄호로 둘러싸야 하는 것이다.
이 방법도 간단하다. 이 방법도 좋아질 것 같다. 변환을 하고 나니까, 예제가 잘 동작했으며 브라우저에 "Hello World!"가 나타났다.
기본적인 연습이긴 하지만, 프로세스가 일어나는 동안은 주목해서 봐야 한다. 필자는 ASP 페이지를 ASP.Net으로 마이그레이션 할 뿐만 아니라, 명확히 COM+ 컴포넌트를 새로운 .Net 환경으로 마이그레이션 했다. ASP.Net은 여전히 CreateObject와 같은 후기 바인딩을 지원한다.
컴포넌트와 ASP 페이지를 ASP.Net으로 옮기는 것은 매우 쉽지만, ASP/ASP.Net 애플리케이션에 대한 최적의 퍼포먼스가 제공된 것은 아니다. 컴포넌트를 보다 ASP.Net 환경에 적합하게 통합하고 초기 바인딩과 같은 퍼포먼스 향상을 이용하는 더 나은 방법이 있을 것이다. 이제부터는 ASP.Net 애플리케이션에서 COM/COM+ 컴포넌트를 접근하는 것에 대해 자세히 알아보자.
세부사항 살펴보기
Visual Studio 6.0/COM+은 관리형 코드(managed code)인데 반해, Visual Studio .Net은 비관리형 코드(unmanaged code)라는 데 가장 큰 차이점이 있다. 간단히 말해 관리형 코드는 .Net Common Language Runtime(이하 CLR) 서비스 지원 하에 실행되는 코드이다. 이러한 서비스는 메모리 관리, 크로스 랭귀지 예외 처리 등의 지원을 제공한다.
역주 : .Net 환경에서는 관리형 코드와 비관리형 코드로 나뉜다. 관리형 코드는 CLR 환경 하에서 실행되는 코드를 뜻하며, 플랫폼에 상관없이 CLR 환경 하에서 실행된다. 비관리형 코드는 기존의 Visual C++과 같은 언어로 작성된 코드를 뜻하며, CLR과 상관없이 실행된다.
COM+ 컴포넌트는 관리형 코드에 기반하지 않는다. 그러나 위에서 언급했듯이, ASP.Net 응용프로그램 안에서 컴포넌트에 접근할 수 있다. 즉 CreateObject를 이용해서 컴포넌트에 접근하거나, 유용한 유틸리티인 TlbImp(
.Net Framework SDK에 있는)를 이용해서 사용자의 컴포넌트를 위한 .Net 호환 래퍼(wrapper)를 만들 수 있다. 이때는 asp0701.dll이 하는 처럼, 사용자의 컴포넌트에 타입 라이브러리가 있어야 한다.
ASP.Net 응용프로그램이든 아니든 간에, TlbImp 유틸리티는 COM 객체를 노출시켜 .Net 관리형 코드를 사용할 수 있도록 .Net 호환 어셈블리를 생성한다. 타입 라이브러리 파일(확장자가 .tlb인)로 분리하면, 다음과 같이 tblimp를 실행해서 타입 라이브러리와 같은 이름의 DLL이 생성된다.
타입 라이브러리가 DLL 컴포넌트 그 자체의 일부로서 컴파일 되었다면(Visual Basic COM+ asp0701 컴포넌트와 같이), out 인자를 사용해서 어셈블리를 위한 새로운 이름을 주어야 한다.
tlbimp asp0701 /out:asp0701lib
|
역주 : 역자가 테스트한 바로는
tlbimp asp0701.dll /out:asp0701lib.dll
|
과 같이 확장자까지 직접 지정해야만 정상적으로 수행되었다.
Tlbimp는 기존에 있는 DLL 객체에 덮어쓰기를 허용하지 않으므로 반드시 out 인자를 지정해야한다.
Tblimp로 asp0701.dll을 이용해서 새로운 파일, asp0701lib.dll을 생성한다. 이제는 ASP.Net 페이지 안에서 이용할 수 있는 레퍼를 사용하자.
새로운 어셈블리 래퍼 사용하기
ASP.Net에서 가장 중요한 사실은 같은 IIS 서버에 ASP와 함께 존재한다는 것이다. 사실 같은 디렉토리 안에 위치시킬 수도 있다.
ASP.Net 어셈블리는 메인 애플리케이션 디렉토리인 /bin 디렉토리로 옮겨야한다.
이제는 .Net 컴파일러는 위치로 어셈블리를 찾는다. 종래의 COM/COM+ 컴포넌트는 반드시 시스템에 등록시켜야만 했지만, .Net에서는 필요 없다. 컴포넌트를 등록하거나 COM 서비스 관리자(윈도우 2000의 관리도구중의 하나)를 사용하여 등록하려면, regsvr32와 같은 시스템 유틸리티를 사용한다.
어셈블리 파일을 옮기고 컴포넌트를 등록하면, ASP.Net 페이지 안에서 컴포넌트를 이용할 수 있다. 다음과 같은 예제코드에서(원래의 asp0701.asp 페이지를 수정한) 첫째 라인은 응용 프로그램 안에 새로운 어셈블리를 포함할 것을 지시한다. 이러한 임포트는 컴포넌트에 대한 네임 스페이스를 나열하는데, 이 경우에는 "asp0701"이다. 이제 CreateObject와 같은 후기 바인딩 대신에, New 키워드를 사용하여 객체를 생성하고, ASP.Net 애플리케이션 안에서 초기 바인딩을 사용할 수 있다.
<%@ Page Language="VB" %>
<%@ Import Namespace="asp0701" %>
Developing ASP Components
<%
Dim obj As First
obj = new First()
Dim msg As String
msg = obj.sayHello("World!")
Response.Write("" & msg & "")
%>
|
(네임스페이스와 어셈블리 이름은 다를 수 있다. .Net과 COM/COM+ 객체에서, 네임스페이스는 컴포넌트의 ProgID의 첫째 부분이다. 그래서 asp0701.First에서는 asp0701이 된다.)
ASP.Net 페이지를 실행한 결과 브라우저에 "Hello World!" 라는 메시지가 똑같이 출력된다. 이제는 컴포넌트에 포함된 비관리 코드는 .Net 컨텍스트 안에 래핑(wrapping)될 수 있다.
마지막으로 이 전체 프로세스에서 COM/COM+ 컴포넌트가 어떻게 변했는지 살펴보자.
COM/COM+ 컴포넌트를 .Net에 맞추기
COM/COM+ 컴포넌트에 TlbImp를 실행할 때, 유틸리티는 IUnknown과 IDispatch 메소드를 떼어내고, 이전 인터페이스를 새로운 관리형 인터페이스로 변환한다.(관리형 코드와 비관리형 코드에 대해 보다 자세한 것은
the documentation on Net를 보기 바란다. 이는 주제를 벗어나므로, 여기에서는 다루지 않는다.)
또한 타입 정의는 기본형으로 임포트된다.
임포트된 어셈블리 파일의 내용을 보려면, .Net 유틸리티인 ildasm를 사용해서 생성된 어셈블리 변환을 보면 된다.
그림 2는 asp0701.dll 어셈블리에 대한 ildasm 결과이다.
그림 2
여기에서 주목할 것은 COM/COM+ String 데이터형이 .Net System.String 데이터 형으로 변환되었다는 것이다.
ASP에서 ASP.Net으로 옮기기 위한 몇 가지 단계를 알아보았다. 두 환경사이에 그렇게 복잡한 변화가 있는 것은 아니다.
요약
ASP.Net으로 변환하기 위해 모든 것을 새로 만들 필요는 없다. 기존에 있는 ASP 응용 프로그램을 새로운 환경으로 점진적으로 옮기면 된다. 이 글에서 언급한 대로, 이러한 컴포넌트들을 수정하거나 재컴파일하지 않고 새로운 환경에서도 마찬가지로 계속해서 사용자의 COM/COM+ 컴포넌트를 이용하면 된다.
무엇보다도 기존의 컴포넌트를 계속 개발할 수 있고, .Net 으로 옮기고 싶으면 언제라도 사용자의 컴포넌트를 .Net으로 옮길 수 있다.
셸리 파워스(Shelley Powers)는 자신이 설립한 Burning Bird Enterprises(Boston, Massachusetts)에서 컨설턴트로 일한다. 지난 몇 년 동안 여러 플랫폼과 툴을 이용하여 다양한 분산/웹 애플리케이션을 개발했다. Dynamic HTML, Java Script, CGI, Perl, 일반 웹 기술에 대한 서적을 저술 또는 공동저술하기도 했다.
역주 : NT 환경과 달리, 윈도우 2000에서는 많은 부분이 바뀌었다.
COM/COM+ 컴포넌트와 관련하여 보안 부분이 이전과 달리 많이 바뀌었다.
만약 여러분이 새로 작성한 DLL 파일과 ASP 파일을 테스트하거나 위와 같은 ASP.Net 환경에서 ASP 페이지를 테스트할 때, 다음과 같은 에러메시지를 만날 수 있다.
(한글 OS에서는 메시지는 다르지만, 에러코드는 동일할 것이다)
Server object, ASP 0178 (0x80070005)
The call to Server.CreateObject failed while checking permissions. Access is denied to this object.
이와 같은 경우에는 다음과 같은 방법으로 해결하기 바란다.
- 해당 가상 디렉토리에 대한 인증 방법을 기본 인증만 선택한다.
- iisreset을 실행하여 IIS 서버를 재시작한다.
- 비주얼 베이직에서 DLL을 재컴파일 한다.
(프로젝트 등록정보에는 "이진 호환성"을 선택한다)
- 구성 요소 서비스에 해당 DLL을 패키지로 등록한다.
NT 환경에서는 regsvr32나 패키지 배포 마법사로 DLL을 시스템에 등록시키면 되었으나, 윈도우 2000 환경에서는 대부분의 경우 COM/COM+ 컴포넌트 인증 문제로 인해, 이러한 문제가 발생한다.(윈도우 2000 프로페셔널에서는 위와 같은 문제가 거의 생기지 않으나, 서버 이상의 환경의 이상에서는 자주 발생한다. 정확한 원인까지는 모른다. 이에 대해 아시는 분은 다음 주소
traxacun@unitel.co.kr로 연락 주시면 감사하겠습니다.)