참으로 어렵게 알아낸 해결 방법 하나를 소개하고자 합니다. 지금 이야기하려는 내용은 ASP.NET 2.0 버전부터 새롭게 추가된 포스트백 이벤트 유효성 검사 기능에 관한 내용입니다. 이 기능은 기본적으로 의도하지 않은 잘못된 입력 값을 원천적으로 차단하기 위한 보안 정책입니다만, 이벤트 버블링이 필요한 경우 호환성 문제를 유발하기도 합니다. 아래에 나열된 컨트롤에 해당되지 않을 경우 이러한 호환성 문제를 겪을 수 있습니다. (http://odetocode.com/Blogs/scott/archive/2006/03/20/3145.aspx 자료 인용)

HtmlAnchor HtmlButton HtmlInputButton
HtmlInputCheckBox HtmlInputHidden HtmlInputImage
HtmlInputText HtmlInputPassword HtmlInputRadioButton
HtmlInputReset HtmlInputSubmit HtmlSelect
HtmlTextArea BulletedList Button
Calendar CheckBox Table
ChildTable WizardChildTable DataControlButton
ImageButton DataControlImageButton LinkButton
DataControlLinkButton DataControlPagerLinkButton DataGridLinkButton
DetailsView DropDownList FormView
GridView HiddenField ImageMap
LayoutTable ListBox Menu
PagerTable RadioButton RadioButtonList
TextBox TreeView WizardDefaultInnerTable
CatalogZone ConnectionsZone EditorZone
WebPartZone ZoneButton ZoneLinkButton

안타깝게도 DataList나 Repeater 같은 컨트롤은 이러한 호환성 문제가 있는듯 합니다. 단순히 Event Validation 설정을 끄는것으로 문제를 해결할 수도 있겠지만 좀 더 완전한 방법을 찾아야 했기 때문에 다양한 도구와 기법을 이용해서 문제를 추적해본 결과 원인을 알아낼 수 있었습니다.

포스트백 이벤트 검증 기능을 지원하지 않는 컨트롤 자체 및 해당 컨트롤 아래에 배치된 자식 컨트롤의 경우 UniqueID, ClientID 값 자체가 ID 프로퍼티의 값과 동일하게 바뀌면서 고유한 식별자가 누락되는 문제점이 있습니다. Render 이벤트를 Overriding해서 ClientScriptManager의 RegisterForEventValidation 메서드를 호출해서 직접 등록을 했다고 할지라도 검사가 실패하게 되는 가장 큰 원인입니다.

문제를 알아내기 위하여 조사하는 과정 중에 혹시 __EVENTVALIDATION 항목의 직렬화 처리에 버그가 있는 것은 아닌지 조사도 해보았지만 잘 작동하고 있었습니다. 이 부분에 대해서는 __VIEWSTATE 항목과 마찬가지로 안심하셔도 될 듯 하네요.

이 문제를 해결하기 위한 방법은 좀 더 시간을 내서 고민해 봐야 할 듯 합니다. 지금 택할 수 있는 방법은 이벤트 핸들러를 통하여 제공되는 sender 파라미터를 리플렉션으로 추적하는 방법이었으며 다행히 의도대로 잘 동작하고 있습니다.

1. 정상적으로 이벤트 핸들러를 호출하였다면 sender는 null 참조가 아닌 Control 객체입니다. 변환에 실패하면 데이터 바인딩을 추적할 수 없으므로 함수 실행을 종료해야 합니다.

2. 변환된 컨트롤을 통하여 Parent 프로퍼티로 가져올 수 있는 객체가 IDataItemContainer 인터페이스를 구현하고 있는지 확인합니다. 변환에 실패하면 데이터 바인딩을 추적할 수 없으므로 함수 실행을 종료해야 합니다.

3. 변환된 컨트롤 자체가 버튼 계열 컨트롤이고 이벤트 버블링을 위하여 CommandName이나 CommandArgument를 지정하였다면 IButtonControl 인터페이스를 구현하고 있을 가능성이 크므로 IButtonControl 인터페이스로 형 변환을 하거나 실제 컨트롤 형식으로 형 변환을 해둡니다.

4. IButtonControl 인터페이스로부터 얻을 수 있는 CommandName, CommandArgument와 함께 IDataItemContainer로 항목의 index를 조사할 수 있으므로, 원래 데이터 바인딩 항목이 속해있던 템플릿 컨트롤을 찾아서 프로그래밍하면 원하는 목적을 달성할 수 있습니다.

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

ASP.NET 프로그래밍을 하면서 전부터 항상 궁금했던 문제가 하나 있었는데 유독 Windows XP 서비스 팩 3 이후부터, 그리고 Windows Vista부터는 Firefox를 이용해서 Visual Studio ASP.NET 프로젝트를 디버깅하려고 하면 "극단적으로" 브라우징 속도가 급감하는 문제가 있었습니다. 내 컴퓨터만의 고유한 문제가 아닐까 싶어서 처음에는 무시했는데 해결이 될만한 조치 사항들을 모두 적용했어도 별다른 차도가 없어서 같은 문제점이 있는 사람이 있지는 않을까 구글을 통해서 검색해 보았습니다. 그리고 역시 같은 문제로 고민하고 있었고 이에 대한 해결책을 쉽게 찾을 수 있었습니다.

Firefox가 느려지는 이유는 다름이 아닌 IPv6에 관한 문제였습니다. Windows XP SP3 이후부터나 Windows Vista부터는 공식적으로 IPv4와 IPv6를 동시에 이용할 수 있게 되었는데 이에 관한 Firefox의 고유한 문제였던것으로 보입니다. Firefox의 고급 설정을 이용해서 IPv6 기반 탐색을 사용하지 않게 하여 문제를 해결할 수 있었습니다만, IPv6 서비스를 Firefox로 이용하는데는 불편함이 있을 듯 합니다.

  • Firefox 주소 입력란에 about:config 이라고 입력하고 Enter키를 누릅니다.
  • 고급 설정을 사용하겠느냐는 질문에 동의합니다.
  • 주소 표시줄/도구모음 입력란 바로 아래의 필터 입력란에 network.dns.disableIPv6 를 입력합니다. 입력하다보면 위의 항목이 자동으로 필터링되어 하단에 나타나는 것도 볼 수 있습니다.
  • 정확한 항목을 찾으면 값을 false에서 true로 바꾸고 그 상태에서 모든 Firefox 브라우저 창을 닫은 뒤 다시 엽니다.

출처: http://code.commongroove.com/archive/2007/10/27/fix-firefox-slowdown-on-vista-while-debugging-localhost.aspx

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)
최근 진행 중인 asp.net 웹 어플리케이션 프로젝트에서 한 가지 특이한 문제점을 발견하였습니다. 여러가지 새로운 형태의 웹 프로그래밍 컨셉을 시도하던 중에 발견한 문제점으로 어떻게 보면 기술상의 한계와도 관련이 있을 듯합니다.

IDE를 이용하여 개발하게 되는 경우, 근래에는 닷넷 프레임워크 2.0이 제공하는 partial 키워드를 이용하여 Code Behind를 구현하게 됩니다. 이렇게 Code Behind로 분리하여 구현을 하게 되는 경우 C# 컴파일러가 제공하는 문법적 확장 기능, 특히 문자열에 관해서는 매우 자유로운 접근이 가능합니다.

Code Behind에서는 다음의 코드는 올바른 코드입니다.

string myScript = @"<script language=""text/javascript"">
window.alert('test');
</script>";

하지만 위의 코드를 다음과 같이 Inline Compilation으로 변경하여 구현하면 컴파일 오류가 발생할 수 있습니다.

<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
     string myScript = @"<script language=""text/javascript"">
window.alert('test');
</script>";
}
</script>

위에서 강조 표시한 부분에 의하여 "상수에서 줄 바꿈 발생" 오류가 나타납니다. 아마도 이것은 ASP.NET Compilation Engine이 문자열 리터럴을 정확하게 구분해내지 못한 기술적인 한계 때문에 발생한 문제인것으로 보입니다.

위의 문제를 해결하기 위해서 제가 택한 방법은 Code Behind 대신 App_Code 폴더 안에 관련 코드를 보관하는 것이었습니다. 더 좋은 방법이 있을지는 한 번 즈음 찾아봐야 할 듯 합니다.
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

근래에 들어서 ASP.NET AJAX도 나왔고 본격적으로 Visual Studio 2008이나 Visual Web Developer 2008을 통해서 Java Script 인텔리센스도 사용할 수 있게 되면서 참 좋아졌습니다. 하지만 JavaScript에서도 OOP가 가능하다는 사실을 모르는 분들도 많고 알고 난 뒤의 당황스러움 또한 말로 표현하기 어려우실 겁니다. :-)

JavaScript의 OOP는 기존의 OOP 프로그래밍 언어에서 최소한의 내용만을 가져왔고 복합적인 형태를 띕니다. 아래의 연속된 박스들을 보면서 어떻게 OOP가 완성되는지 살펴보도록 하겠습니다.

function myClass()
{
    // 보통은 이곳에 함수의 내용을 프로그래밍하는 것으로 알고 있고 그렇게 합니다.
}
function myClass()
{
    // 그러나, this라는 키워드가 있습니다. 그리고 this라는 키워드에 임의의 변수를 새로 정의하는 것이 가능합니다.
    this.something = 'Hello World!';
}
function myClass()
{
    // 한걸음 더 나아가서, something의 내용을 브라우저의 메시지 박스로 띄워주는 함수도 만들어볼까요?
    this.something = 'Hello World!';
    this.showSomething = function() {
        alert(this.something);
    }
}
var test = new myClass();
test.showSomething();

위의 연속된 박스들을 보면서 몇 가지 특징을 한꺼번에 설명해보겠습니다.

우선 myClass라는 함수이자 클래스는 보통의 함수로 사용되면 의미가 없습니다. 반드시 new 연산자에 의해 생성될 필요가 있습니다. 이 때, myClass 안에 들어있는 선언부 외의 모든 일반적인 코드들은 myClass의 생성자와 같은 일을 합니다.

그리고 따로 선언한 적이 없는 변수나 함수가 this 키워드에 이름을 지정하는 것 만으로 생성이 되는 것을 알 수 있는데, 이렇게 생성된 변수나 함수 모두 액세스 한정자가 public인 멤버로 볼 수 있습니다. 만약 로컬 변수를 사용하고 싶어서 var 키워드를 써서 변수를 정의했다면 로컬 변수로도 취급됩니다. var 키워드의 경우 브라우저의 해석 방법에 따라서는 private 액세스 한정자 멤버로 취급될 수 있는것도 같습니다만 정확한 것은 아닙니다.

이와 같이 JavaScript OOP를 이용하여 새로운 형식을 만든다는 것은 어려울 것이 없는 단순명료한 작업입니다. 여기에 기존의 브라우저들이 제공해왔던 다양한 형태의 API와 XMLHttpRequest와 같은 서비스를 결합시킨다면 유용할 것입니다. ASP.NET AJAX를 비롯하여 여러 JavaScript 고급 서비스들은 JSON (Java Script Object Notation)을 통하여 직렬화와 역직렬화 서비스를 구현하고 있으며 이를 통하여 클래스에 영속성을 부여하기도 합니다.

JavaScript OOP를 성공적으로 활용하는 사례는 도처에 널려있습니다. ASP.NET AJAX의 XML 웹 서비스 연동 기능, 자바스크립트 객체 영속성을 위한 JSON, 자바스크립트 코드 검증 및 분석 도구인 JSLINT 등이 있습니다.

ASP.NET AJAX를 통하여 새로운 기능을 배우는 것도 좋지만 JavaScript의 OOP 능력도 시험해보고 좀 더 낳은 코드를 제작할 수 있도록 아이디어를 찾아보는 시도 또한 중요할듯 싶습니다.

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

개인적인 호기심에 Java Script 기반의 암호화 알고리즘 구현이 있을까 검색해보게 되었다. 혹시가 역시였는데 매우 다양한 버전의 Java Script 기반의 암호화 알고리즘을 찾을 수 있었다. 클라이언트에서 데이터를 암호화한 후 이것을 서버로 전송하고 이것을 서버에서 같은 비밀 키를 사용하여 해독한다는 개념은 이제는 너무 일반적인 것이라 굳이 언급하지 않아도 될 정도다. 하지만 놀랍게도 이런 구현 절차를 ActiveX에 너무 많이 기대고 있다는 것 또한 사실이다.

ActiveX 없이 다중 브라우저를 지원하면서도 일정 수준 이상의 보안을 충족하는 암호화 시스템을 어쩌면 간단히 구현해볼 수도 있지 않을까라는 호기심이 생겨서 몇 번 코드를 끄적여보았을 뿐인데 개인적으로나 일반적인 커뮤니티에 적용하기에는 딱 좋은 수준의 암호화 시스템이 나와서 글을 써본다. Security Critical한 서비스에서는 HTTPS, SSL, IP/sec 등을 사용하는 것이 100배 안전하지만 이것은 어디까지나 일상적인 암호화만을 다루는 것이다.

기본적인 원리는 간단하다. 같은 Java Script Source Code를 가지고 하나는 Internet Browser용 Java Script Code로 사용하고 또 하나는 JScript .NET 컴파일러용으로 패키징하여 ASP.NET에 통합하는 것이다. 이 글에서는 AES (Advanced Encryption Standard) 알고리즘을 채택하였다.

Java Script AES Implementation: http://www.movable-type.co.uk/scripts/aes.html

위의 사이트에서 핵심적인 AES 구현을 먼저 가져왔다. AES 알고리즘과 비밀 키를 통하여 평문을 암호문으로, 암호문을 평문으로 바꾸는 것이 정확하게 작동한다는 것을 테스트하였다. 하지만 암호문을 평문으로 바꾸는 과정에 있어서 암호문이 바이트의 배열로 출력된다는 점이 걸린다. 인코딩에 따라서는 완전히 다른 내용으로 읽혀져 손상될 가능성이 있기 때문이다. 그래서 BASE64 알고리즘을 다시 찾게 되었다.

Java Script BASE64 Implementation: http://rumkin.com/tools/compression/base64.php

AES 암호문을 BASE64로 보호하고, BASE64 디코딩으로 얻어낸 AES 암호문을 평문으로 바꾸는 것 또한 정확히 동작함을 확인하였다. 그리고 이번엔 정말 실용성이 있는지 확인해보고 싶어서 2바이트 문자열을 가지고 암호화 복호화를 시험해보았다. 하지만 이번엔 정확히 복원해내지 못한다는 것을 확인할 수 있었다. 다행히 2바이트 문자열에 대해서는 자바스크립트 내장 함수인 encodeURI와 decodeURI를 통하여 처리할 수 있었다. 평문에 관한 문제는 해결이 되었지만 비밀 키의 경우에는 이 방법도 의미가 없었다. 비밀 키는 1바이트 문자열 수준에서 해결해야 하는듯 보였다.

이러쿵 저러쿵하여 만든 JavaScript 코드와 바이너리를 ZIP 파일로 묶어서 올려본다. 여러 메서드가 있지만 이 글의 내용을 반영하여 만든 실질적인 메서드는 다음과 같다.

// JavaScript
AesEncrypt128(plainText, password);
AesEncrypt192(plainText, password);
AesEncrypt256(plainText, password):
AesDecrypt128(cipherText, password);
AesDecrypt192(cipherText, password);
AesDecrypt256(cipherText, password):

// C# (Need JScript.NET Runtime Assembly)
SecurityManaged.ComplexAes aesModule = new SecurityManaged.ComplexAes();
aesModule.AesEncrypt128(plainText, password);
aesModule.AesEncrypt192(plainText, password);
aesModule.AesEncrypt256(plainText, password);
aesModule.AesDecrypt128(cipherText, password);
aesModule.AesDecrypt192(cipherText, password);
aesModule.AesDecrypt256(cipherText, password);

클라이언트 측에서는 AesEncrypt로 보호할 내용을 암호화한 후 서버에 전송하고, ASP.NET - 또는 - 이를 받아들일 소켓 서버 등에서는 SecurityManaged.dll 파일을 레퍼런스로 참조하고 SecurityManaged.ComplexAes 클래스의 인스턴스를 만들어 위의 AesDecrypt로 내용을 복구하면 되겠다. 참고로 128/192/256은 키의 길이에 해당된다.

첨부된 파일 안의 .Managed.js 파일은 JScript.NET 문법에 맞게 재배치한 것으로 DLL로 컴파일하는 것을 가능하게 해준다. 안의 내용이나 코드 문법은 오리지널 Java Script과 전혀 차이가 없지만 닷넷 어셈블리로 만들기 위해서 package 구문과 class 구문을 추가하였을 뿐이다. 또한, 가능성만을 타진해보기 위함이었으므로 JScript.NET에서만 가능한 명시적인 형식 지정 또한 누락되어있다. 만약 좀 더 최적화를 원한다면 코드를 수정해서 사용할 것을 권하며 필요한 경우 어트리뷰트 지정을 통하여 지연된 서명을 추가해볼수도 있겠다.

닷넷 프레임워크 2.0을 설치하였다면 명령 프롬프트에서 다음과 같이 입력하면 원하는 어셈블리를 직접 얻을 수 있다. (이 작업을 위해서 Visual Studio 2005나 2008은 필요하지 않다.)

%windir%\microsoft.net\framework\v2.0.50727\jsc.exe /target:library AesImpl.managed.js

이제 우리들만의 일상적이고도 간단한 AES 암호화 알고리즘 시스템을 얻을 수 있게 되었다. 그 다음 활용 방안은 다시 고민해봐야 하겠다. 자바스크립트 기반에 닷넷까지 지원되니 ASP.NET AJAX와 Silverlight에도 잘 어울릴듯 하다.

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

오늘은 자투리 시간을 이용하여 Visual Web Developer 2008을 설치해서 가장 써보고 싶었던 기능인 JavaScript 편집 기능을 활용해 보았다. 평소에 JavaScript 에디터 중에 무료로 사용할 수 있으면서도 완벽한 기능을 보여주는 에디터가 없는게 큰 불만이었던터라 무척 반가웠다.

Visual Web Developer 2008의 자바스크립트 기능이 특별한 이유는 바로 JavaScript OOP를 지원하기 때문이며 부수적으로 HTML DOM을 완벽하게 해석하기 때문에 정확한 코딩을 할 수 있어서 좋다. 만약 JavaScript를 분석할 일이 있지만 까탈스러운 문법때문에 고민중이라면 당장이라도 Visual Web Developer 2008만은 다운로드받아서 활용해보길 바란다. 덤으로 테스트용 웹 서버까지 따라오므로 IIS도 필요없다.

본업인 닷넷 프레임워크 기반 개발 환경에 대해서도 당연히 관심이 있기에 ASP.NET AJAX가 2005때보다 얼마나 더 개발하기 편리해졌는지, 그리고 WCF (Windows Communication Foundation) 프레임워크 기반의 서비스 개발의 능력도 체크해 볼 생각이다.

Visual Web Developer 2008은 이 글을 쓰는 현 시점에서 아직까지 영문판 전용이지만 곧 한글판도 나올 것으로 보인다. http://msdn.microsoft.com/express 에서 받을 수 있다.

아래는 기념으로 만든 예제 코드이다. 요즈음은 어떤 환경이던간에 Hello World를 못할리가 없으므로 나는 예제 코드로 좌항과 우항을 더해서 결과값을 반환하는 사칙 연산 로직을 앞으로의 새로운 프로그래밍 언어에 대한 시험 코드로 써볼 생각이다.

[CODE]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Untitled Page</title>
    <script type="text/javascript">
    function exception(content) {
        this.message = content.toString();
       
        this.alert = function() {
            alert(this.message);
        }
       
        this.toString = function() {
            return this.message;
        }
    }

    function calc(leftVal, rightVal) {
        this.left = parseInt(leftVal.toString(), 10);
        this.right = parseInt(rightVal.toString(), 10);
       
        if (isNaN(this.left)) {
            throw new exception('left is NaN!');
        }
       
        if (isNaN(this.right)) {
            throw new exception('right is NaN!');
        }
       
        this.add = function() {
            return this.left + this.right;
        }
       
        this.sub = function() {
            return this.left - this.right;
        }
       
        this.multi = function() {
            return this.left * this.right;
        }
       
        this.div = function() {
            if (this.right == 0) {
                throw new exception('div/0!');
            }
            return this.left / this.right;
        }
       
        this.mod = function() {
            return this.left % this.right;
        }
       
        this.pow = function() {
            return Math.pow(this.left, this.right);
        }
    }
    </script>
</head>
<body>
    <div id="Test"></div>
    <script type="text/javascript">
    var test = new calc(3, 4);
    alert(test.add());
    alert(test.sub());
    alert(test.multi());
    alert(test.div());
    alert(test.mod());
    alert(test.pow());
    </script>
</body>
</html>


[/CODE]
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)
이번에 참여한 홈페이지 리뉴얼 프로젝트를 통하여 ASP.NET의 한 가지 중대한 문제점을 발견하게 되었다. ASP.NET은 틀림없이 XHTML을 지원하고 있다. 하지만 이것이 정말 완벽한 지원일지는 '?' 라고 해야하지 않을까?

ASP.NET 2.0이 타깃으로 잡고 있는 XHTML은 XHTML 1.0 Transitional 모델인데, XHTML 1.0 Transitional을 기초로 모든 것을 렌더링하기 때문에 XHTML 1.1이나 그 이상의 다른 모델로 전환하는 것에 대한 적당한 방법이나 설정이 없는 것 같다.

XHTML 1.0 Transitional을 완벽히 소화하고 있으므로 ASP.NET 2.0의 XHTML 지원이 부적당하다는 의미는 아니지만 확장성은 아직도 고려하고 있지 못한 게 아닌가 싶은 아쉬움이 많이 든다.

꼭 XHTML 1.1에 관해서만이 아니라 앞으로 구체화될 HTML 5.0에 대한 지원을 위해서라도 ASP.NET의 렌더링 방법은 좀 더 확장될 필요가 있지 않을까 싶다.
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

1. 이 글에 첨부된 patch.zip 파일을 다운로드하여 patch.js 파일을 원하는 곳에 저장한다.

2. 패치를 적용할 웹 문서나 웹 어플리케이션의 소스를 연다.

3. 문서의 <HEAD> ~ </HEAD> 섹션 안에 다음과 같이 반영될 수 있도록 편집한다. 보통의 HTML 문서로 말할 것 같으면 다음과 같다고 할 수 있다.

[CODE]
...
<head>
<meta http-equiv="content-type" content="text/html; charset=euc-kr">
<title>제목 없음</title>
<script src="patch.js" language="javascript"></script>
</head>
...
[/CODE]

4. patch.js에는 docWrite 함수 하나만 들어있으며 단지 document.write를 대신 써주는 일 뿐이다. 하지만 이 HTML 페이지에서 직접 document.write를 호출하는 것과는 차이가 있다.

5. 이제 ActiveX 컨트롤이 삽입된 곳으로 가서 <OBJECT> ~ </OBJECT> 섹션의 내용을 모두 복사한다.

6. docWrite 함수를 호출하되 문자열 인수를 넘겨주면된다. 그러나 다음의 사항을 지킬 필요가 있다.

6-1. 편의상 문자열 인수의 시작과 끝을 작은 따옴표로 할 것을 권장한다. Well-Formed XHTML Document의 경우 모든 Property를 쌍 따옴표로 열고 닫는 관습이 있는데 여기에 일일이 Escape Sequence 처리를 하는것은 비효율적이기 때문이다.

6-2. 가독성을 위하여 String Concatenation을 사용할 것을 권장한다. 물론 한 줄로 이어서 쓰더라도 별 문제는 없겠으나 한 번만 쓰고 말 것은 아니지 않겠는가. 잘 모르는 사람들을 위해서 설명하자면 Enter키로 입력한 줄 띄우기 부분이 JavaScript 문자열에서는 자동으로 이어지는 것이 아니기 때문에 곧 이어 나올 예제와 같이 표기하는 방식을 말하는 것이다.

위의 6-1과 6-2에 따라서 내용을 표기한다면 다음과 같다.

[CODE]
<script language="javascript" type="text/javascript">
<!--
docWrite('<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0" namo_flashbutton width="400" height="70">' +
'<param name="movie" value="banner_02.swf">' +
'<param name="play" value="true">' +
'<param name="loop" value="true">' +
'<param name="quality" value="high">' +
'<param name="WMode" value="Window">' +
'<embed width="400" height="70" src="banner_02.swf" play="true" loop="true" quality="high" WMode="Window" pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash">' +
'</object>');
-->
</script>
[/CODE]

완성된 문서/스크립트는 patch.zip 파일 안에 그대로 저장되어있으니 한 번 살펴보기 바란다.


내용 출처: http://cafe.naver.com/repay.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=345
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

Visual Basic Extension, Object Linking Embedded, Component Object Model, Binary Behavior, Distributed Component Object Model, Component Object Model Plus, Windows DNA 등 Microsoft가 C++과 객체 지향 기술을 이용하여 개발해왔던 다양한 프레임워크들 중 하나인 ActiveX가 이제는 그 수명을 다하려는듯한 결정적인 루머를 내고 있다.

당장 내년 1월에 새롭게 출시될 Windows Vista에 포함된 IE7에서는 ActiveX 컨트롤 자체가 완벽하게 Sand-Box 처리가 될 것이라고 한다. ActiveX 인스턴스는 어차피 Internet Explorer와 함께 그 수명을 같이하는 것이므로 이상할 것이 없지만 Sand-Box 라는 것은 다소 생소하실 분들이 많겠다.

요약하자면, ActiveX 컨트롤을 PC에 다운로드하여 Install하는 작업을 하지 않고 마치 Java Applet이나 Flash Content 또는 Script 처럼 동작하게 만들겠다는 의미가 된다. 보안 상으로는 틀림없이 이득이 될테지만 ActiveX를 개발하여 배포해왔던 업체들에게는 정말 큰 일인셈이다.

퍼블릭 릴리즈로 나온 IE7을 먼저 써본 사람들은 새로운 모드인 "안전 모드"에 대하여 궁금해 했을 것이라 생각한다. 이 "안전 모드"가 바로 이 루머와도 관련이 있겠다. 단순히 설치된 ActiveX 컨트롤 전체를 사용하지 않는 것으로 시작해서 유입되는 모든 ActiveX 컨트롤이 하드 디스크에 저장되거나 설치되는 것을 통제하고, 퍼미션 조절을 통하여 작업에 제약을 걸어놓는 모드이다. 정식으로 나올 Windows Vista의 IE7에서는 아마도 이 "안전 모드"를 기본 모드로 사용하도록 권하기 때문에 이런 루머가 나온 것이 아닐까 싶다.

더 재미있는 사실은, Windows Vista가 이제는 .NET Framework 3.0을 기본으로 내장하고 있다는 사실이다. 이것이 의미하는 바는 ActiveX의 운명을 더욱 확실하게 만들어주고 있다. .NET Framework 2.0부터 강화된 ClickOnce는 Windows Forms로 개발된 .NET Application을 Internet Explorer와 연동할 수 있도록 도울 것이며, Windows Presentation Framework의 XAML은 Internet Explorer 7.0이 직접 렌더링하는 것도 가능하다. 또한 Windows Presentation Framework Everywhere는 경량화된 응용프로그램을 지원할 것이다. 지금 언급한 이 세 가지 기술을 적극 유치하고 유도하는 것이 MS의 실제 목표다. ActiveX는 보안 상의 문제가 많다는 점을 이용하여 오히려 뒤로 빼려는 셈이다.

또한 이제는 ActiveX보다는 Flash, Java를 이용한 개발을 더욱 선호하는 추세이다. 컨텐츠 프로바이더의 입장에서도 ActiveX는 메리트가 없는 셈이다. 그리고 기억하는 사람들도 아직 있으리라 생각되는 이올라스社의 소송 승리도 ActiveX의 숨통을 조르고 있다.

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

안녕하세요. 3월이 되기 직전에 어쩌면 마지막으로 올리는 강좌일 수도 있겠군요. 저 개인적으로는 수시 1학기때 대입에 관련된 모든 것을 끝을 내야 하는 입장인지라 당분간은 잠수를 타겠지요. ㅎㅎ 하지만 잠수를 타기 전에 잊지 않고 강좌를 올리고 갑니다. ^^

ASP .NET을 요즈음 들어서 많이 연구하는 중입니다. ASP .NET은 여러가지 장점도 있고 재미있는 토픽이 많지만 한 가지 불편한 점이 있습니다. 디자인 타임과 코드 비하인드 사이를 넘나드는 일이 그리 쉽지는 않다는 점입니다. ASP .NET 2.0 에서는 partial 키워드가 지원이 되므로 복잡한 상속 체인을 이용할 필요가 없습니다. (상속 체인을 쓰지 않아도 된다는 말의 본질적인 뜻은 결국 서술하는 위치만이 다를 뿐 결국에는 하나의 단일 클래스를 완성할 수 있다는 뜻이 되기도 합니다.) 하지만 아직은 ASP .NET 1.1이 많이 쓰이는 시대. 김칫국만을 마실 수는 없겠지요?

이번 강좌는 아주 약간의 노력으로 디자인 타임과 코드 비하인드 모두에서 편리하게 세션을 사용하는 방법을 소개 합니다. 디자인 타임에서는 코드 비하인드와 달리 복잡한 구문을 이용하는 것이 적절하지 않습니다. 반면 코드 비하인드는 디자인 타임처럼 자유로운 배치를 하거나 예약 변수가 전혀 없으므로 대체로 코드가 길어지기 마련입니다.

Step1. 클래스를 정의한다

여러분이 원하시는 이름의 클래스를 정의하시면 됩니다. 다만, 여기에 네임스페이스를 정의해야 한다면 약간의 추가 사항이 포함됩니다. 디자인 타임에서는 <%# Import Namespace="네임스페이스 식" %>를 상단부에 배치해 주세요. 코드 비하인드에서는 늘 그래왔듯이 using (C#) 구문이나 Imports (VB.NET) 구문을 사용하여 네임스페이스 참조를 해주시는 것을 잊지 않도록 해야 하겠지요.

Step2. 구현하는 인터페이스로 반드시 System.Web.SessionState.IRequiresSessionState를 포함한다!

Step2를 놓쳐서 흔히 "안되겠구나" 하는 생각을 가지고 좌절을 맛보시는 분들이 많을겁니다. 놓치시면 안되겠지요? ^^

아, 그리고 인터페이스라고 해서 구현해야 하는 멤버수가 많지 않나 하여 걱정하시는 분들이 계실 거라 생각합니다. (저도 그렇게 생각하고 있습니다.) 하지만 다행히도 이 인터페이스는 단순한 표식 인터페이스로서 포함하는 멤버가 없습니다. 아주 간단한 스탬프를 하나 찍어놓는다는 기분으로 가볍게 써주세요. ^^

참고할 것은, 이 인터페이스는 세션 변수를 읽기/쓰기 할 수 있도록 표기하는 것입니다. 단순히 세션 변수를 읽기만 할 요량으로 설계할 클래스라면 이 인터페이스보다는 System.Web.SessionState.IReadOnlySessionState 인터페이스를 대신 써주시면 됩니다. 이 인터페이스도 마찬가지로 표식 인터페이스이므로 추상 멤버가 없습니다.

Step3. 어디서나 세션 변수에 접근하려면? System.Web.HttpContext.Current 속성에 주목하라!

Step2에서 좌절하고 Step3를 몰라 포기하실겁니다. 실수하지 말자구요. ^^

HttpContext.Current 속성은 정적 속성입니다. 그래서 위와 같은 표기로 접근하는 것이 맞습니다. 이 속성을 통하여 현재 시점에서 처리 중인 HTTP 요청에 대한 모든 것을 다룰 수 있습니다. 이 속성을 호출하는 대상이 누구인지, 현재 시점이 언제인지를 떠나서 웹 요청을 처리하는 클래스 라이브러리 (ASP .NET 응용프로그램)와 연결만 되면 항상 유효하므로 걱정하실 필요는 없습니다. (단 Out-Of-Process 상태인 콘솔, WinForm, GTK#, NT 서비스, 데몬 등의 프로그램 등에서는 유효하지 않을 수도 있습니다.)

그리고 디자인 타임에서 개체 생성 없이 빠르게 사용하시려면 가급적 이 클래스의 모든 멤버를 정적 멤버 (C#에서는 static, VB.NET에서는 Shared)로 선언해주는 것이 좋습니다.

Step4. 디자인 타임에서 쓰는 방법

<% = SessionHelper.UserIdentity %>님, 방문을 환영합니다!

<asp:Label id="test"><%# SessionHelper.UserIdentity %></asp:Label>

간단하지요? ^^

많은 도움이 되시기를 바랍니다. ^^

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)