클럽(카페) 도메인을 만들어 보도록 하자.

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (7/1/2008 1:45:05 PM) Viewing : 4983

간만의 아티클이다..ㅎㅎ

아티클이라고 하기엔 좀 거시기 하지만..어쨋든..

오늘 알아 볼 것은 초보개발자들이 아마도 많이 궁금해 하던 것인지도 모르고...
왠만한 개발자들은 다 아는 간단한..것...

클럽(카페) 도메인을 만들어 보도록 하겠다.
제목이 좀 이상하긴 하지만...
예를 들자면 http://도메인/클럽이름

이런 형식이 되겠다.

기본 프로세스는 이러하다.

브라우저에서 해당 url에 대한 요청을 받게 되면 기본적으로 클럽이름은 폴더로 인식하여 시작페이지가 없다면 404 에러를 내게 된다.
여러 가지 방법이 있겠지만 내가 선택했던 방법은.

HttpModule을 이용한 방법이다 
url의 요청을 받으면 이 모듈에서 해당 url에 대한 유효성을 검증한다.
그 후에 유효한 도메인 이라면 default.aspx 로 던지고 default.aspx 에서는 프레임셋을 만들어 내부의 메인 프레임에 
기본 페이지 (예시에서는 Main.aspx) 에 clubid=클럽이름 과 같은 형식으로 redirection 시킨다.

그렇게 되면 동적으로 프레임셋이 생겨 이후 페이지 이벤트에서는 모두 메인프레임내부에서만 작동되기 때문에 
브라우저의 url은 초기의 http://도메인/클럽이름 으로 고정되게 되겠다.

이제 HttpModule 부터 알아 보도록 하겠다.

    1 public class RewriterModule : IHttpModule

    2 {

    3     private string clubId;

    4 

    5     #region IHttpModule 멤버

    6 

    7     /// <summary>

    8     ///    <see cref="T:System.Web.IHttpModule"></see>을 구현하는 모듈에서 사용하는 리소스(메모리 제외)를 삭제합니다.

    9     /// </summary>

   10     void IHttpModule.Dispose()

   11     {

   12     }

   13 

   14     /// <summary>

   15     /// 모듈을 초기화하고 요청을 처리할 수 있도록 준비합니다.

   16     /// </summary>

   17     /// <param name="context">ASP.NET 응용 프로그램 내의 모든 응용 프로그램 개체에 공통되는 메서드, 속성 및 이벤트에 액세스할 수 있도록 하는 <see cref="T:System.Web.HttpApplication"></see>입니다.</param>

   18     void IHttpModule.Init(HttpApplication context)

   19     {

   20         context.BeginRequest += new EventHandler(OnBeginRequest);

   21     }

   22 

   23     #endregion

   24 }

 먼저 RewriterModule 이라는 모듈을 생성했다. 이는 IHttpModule 인터페이스를 구현한다.
이 인터페이스에는 2개의 메서드가 있는데 주목할 것은 Init 메서드이다.
Init 메서드의 BeginRequest 이벤트를 정의 해서 이 이벤트에서 url을 처리 하도록 하겠다.

    1 /// <summary>

    2 /// Called when [begin request].

    3 /// </summary>

    4 /// <param name="sender">The sender.</param>

    5 /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>

    6 void OnBeginRequest(object sender, EventArgs e)

    7 {

    8     if (this.IsValidatedUrl())

    9     {

   10         if (HttpContext.Current.Request.RawUrl == "/" + this.clubId)

   11         {

   12             HttpContext.Current.RewritePath("/Default.aspx?ClubId=" + this.clubId);

   13         }

   14         else

   15         {

   16             HttpContext.Current.RewritePath(HttpContext.Current.Request.RawUrl.ToLower());

   17         }

   18     }

   19     else

   20     {

   21         if (HttpContext.Current.Request.RawUrl.ToLower() == "/default.aspx")

   22         {

   23             ///적절한 처리

   24         }

   25         return;

   26     }

   27 }

8행에서 유효한 url인지 검사를 한다.
유요한 url이라 함은 도메인/클럽이름 혹은 특정페이지.aspx?ClubId=클럽이름 의 경우가 있다.
이에 따란 10행~17행은 분기를 한다.
만약에 도메인/클럽이름으로 접근 하였다면 처음 설명하였듯이 default.aspx 페이지로 넘긴다.

19행의 경우에는 유효하지 않는 도메인의 경우인데 이는 바꿔 말하면 도메인/클럽이름 타입이 아니거나 특정페이지.aspx?ClubId=클럽이름 의 형태가 아닌게 되겠다.
이 때는 프로젝트에 따라 적절히 처리해 준다.
default.aspx 인 경우라면 클럽메인(클럽홍보라든가 리스트가 보이는)페이지로 이동같은 경우가 될것이다.

    1 /// <summary>

    2 /// ■유효한 URL 인지 판단합니다.

    3 /// </summary>

    4 /// <returns>

    5 ///    유효한 URL이면 <c>true</c> 그렇지 않으면 <c>false</c>.

    6 /// </returns>

    7 private bool IsValidatedUrl()

    8 {

    9     //http://도메인/페이지.aspx?ClubId=클럽아이디~~ 형태

   10     this.clubId = HttpContext.Current.Request.QueryString["ClubId"];

   11     if (String.IsNullOrEmpty(this.clubId))

   12     {

   13         if (HttpContext.Current.Request.QueryString.Count > 0)

   14         {

   15             return false;

   16         }

   17 

   18         //http://도메인/클럽아이디 형태

   19         this.clubId = HttpContext.Current.Request.RawUrl;

   20         if (this.clubId.StartsWith("/"))

   21         {

   22             this.clubId = this.clubId.Remove(0, 1);

   23         }

   24         if (this.clubId.EndsWith("/"))

   25         {

   26             this.clubId = this.clubId.Remove(this.clubId.Length - 1);

   27         }

   28 

   29         //.나 /가 있으면 다른 페이지를 호출 하는 것이다.

   30         if (this.clubId.IndexOf(',') > 0 || this.clubId.IndexOf('/') > 0)

   31         {

   32             this.clubId = null;

   33             return false;

   34         }

   35 

   36         return (this.clubId.ToLower() == Regex.Match(this.clubId, @"([\w]+)").Value.ToLower());

   37     }

   38     else

   39     {

   40         return true;

   41     }

   42 }

 위 메서드는 유효한 도메인인가를 검사하는 메서드이다..
이로서 RewriteModule 에 대한 정의는 끝이 났다.
이제 이 모듈을 등록 할 차례이다.

등록은 web.config에서 하도록 한다.

    1 <system.web>

    2     <httpModules>

    3         <add name="RewriterModule" type="네임스페이스.RewriterModule, 어셈블리경로"/>

    4     </httpModules>

위 예시 처럼 system.web 노드 아래에 정의 하도록 한다.

이제 이 모듈에서 해당 url이 유효 했다고 판단되었을때 보내는 default.aspx 페이지를 살펴 보자.

앞서 설명 하였듯이 이 페이지에서는 해당 url에 ClubId 라는 쿼리 스트링이 있는지 조회를 해서 있다면..
동적으로 프레임셋을 만들어 메인 프레임에 Main.aspx 페이지를 띄우는 형식이다.

    1 /// <summary>

    2 ///    <see cref="E:System.Web.UI.Control.Load"></see> 이벤트를 발생시킵니다.

    3 /// </summary>

    4 /// <param name="e">이벤트 데이터가 들어 있는 <see cref="T:System.EventArgs"></see> 개체입니다.</param>

    5 protected override void OnLoad(EventArgs e)

    6 {

    7     base.OnLoad(e);

    8 

    9     if (HttpContext.Current.Request.QueryString["ClubId"] != null)

   10     {

   11         HttpContext.Current.Response.Write(@"

   12 <!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>

   13 <html xmlns='http://www.w3.org/1999/xhtml'>

   14 <head>

   15 <title>테스트 - 클럽</title>

   16 </head>

   17 <frameset rows='0,100%' border='0'>

   18 <frame src=''>

   19 <frame name='mainFrame' src='/Main.aspx?ClubId=" + HttpContext.Current.Request.QueryString["ClubId"].ToLower() + @"'>

   20 </frameset>

   21 </html>");

   22         HttpContext.Current.Response.End();

   23     }

   24 }

자 이로서 모두 완성 되었다...
간단하지 않은가?????

뭐든 다 그렇듯이..알고 나면 간단하다...그럼 이만 뿅~~~


마지막 업데이트 : (7/1/2008 1:54:14 PM)

TAG : 없음



Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기

VS2008 BETA2 한글판을 써보고

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (8/30/2007 10:16:25 AM) Viewing : 2975

그저께 밤인가 배포가 되어 어제 출근하여 설치를 해 보았다.
오호라...

원래 베타는 잘 안쓰는 편이라..ㅡ.ㅡ;
영문판도 사실은 그저께 설치해 보았던 터이다..ㅡ.ㅠ;

그러나...한글판으로 나왔다는데야...일단 깔아 보자..하고 설치를 해보았다.

대충 살펴본 느낌만 전달하도록 하겠다..^^;

먼저...2005와 거의...유사하다는 느낌이다..
2005를 써봤던 사람이라면..바로 2008로 이전해도 무리는 없을듯 하다.

실제로 이 홈페이지 프로젝트를 2008로 마이그레이션을 하였으나...
단...두가지문제를 제외하고는 100% 예외없이 경고없이 마이그레이션이 되었다.

2가지 문제가 발견되었는데..

그 첫번째는 AJAX.NET 문제이다. 
3.5로 마이그레이션을 하였음에도 불구하고 ScriptMethod라는 어트리뷰트를 인식하지 못하더라..
알고보니 System.Web.Extensions.dll과 System.Web.Extensions.Design.dll 을 찾지 못한 문제였다..

이상도 하지..ㅡ.ㅡ;;
머 일단 AJAX.NET 1.0을 설치 하니 문제가 없어졌다..쿨럭..(뭔가 이상하다..ㅡ.ㅡ;)

그리고 이건 작은 문제인데.
Visual Studio 2005 We Deployment Pojects에서 문제가 발생했다..
뭐..당연하겠지만..ㅡ.ㅡ;;;;

이 외에는 100% 적용되어 마이그레이션이 되었다.

그리고 나서 일단 메뉴를 이것저것 살펴 보던 차에...
재미 있는 것을 발견하였다.
바로 코드메트릭이라는 것이다.
아래 스샷을 참고하길 바란다.

해당 솔루션의 프로젝트와 각 프로젝트의 코드에 대한 메트릭(?)이란다.
유지 관리 편의성 지수, 순환복잡성, 상속 수준, 클래스 결합 수준, 코드 줄수 의 정보가 보인다.

내가 전공자가 아니라서일까...아마도 소프트웨어 공학쪽으로 가면 이런 내용을 배울듯도 한데..
어쨋든...뭐에 쓸려고 만든것인지 모르겠으나..재미있는 지표라고 생각한다.

VS2008의 기능에 대해서는 이미 많이 접해 보았으리라 생각이 된다.
Multi-Targetting(VS2008에서는 .NET Framework의 버전을 선택할 수 있다. 2.0, 3.0, 3.5) 이라든지 자바스크립트의 디버깅 지원이라든지 웹디자이너뷰에서의 창 분할 이라든지...
이런 몇가지 유용한 장점이 있다..(IDE의 장점 말이다.)

눈에 띄는것은 웹사이트 프로젝트가 사라졌다는 점이다..쿨럭....

어쨋든...

이러한 장점을 사용하고자 한다면 일단은 지금 즉시 VS2008을 설치 해보고 마이그레이션이 아니라 .NET Framework 2.0으로 개발하여도 큰 문제가 없으리라 생각된다.

http://www.microsoft.com/downloads/details.aspx?FamilyId=428C076F-E3EF-4290-9FF4-F6FD8F180B7D&displaylang=ko

위 링크에서 다운로드 받을수 있다.
참고로 덧붙이자면..

한국 마이크로소프트 R&D팀 말에 의하면..ㅡ.ㅡ;
자국어로 번역된 최초의 버전이라고 한다..짝짝짝..박수 한번 쳐주고..사용해 보기를..^^;

PS : MSDN은 영문이랍니다..^^; 혹시나 해서..


마지막 업데이트 : (8/30/2007 10:21:36 AM)

TAG : 없음



Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기

Dynamic DropDownList Binding using XML

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (5/11/2007 3:40:11 PM) Viewing : 2894

오늘은 재미있는 읽을 꺼리를 제공하고자 한다..ㅡ.ㅡ;

초보자들이 많이 고민하고 실제로 나도 지금껏 이런 저런 방법으로 고민도 많이 했었던 문제인데.
DropDownList(이하 DDL) 의 연동 문제다.

무슨 말인고 하니..
첫번째 DDL을 선택하면 두번째 DDL이 바인딩되는 뭐...그런거다.

바인딩되어야 하는 분량이 적다면 처음 로딩시에 script에서 배열로 받아 가지고 있을 수도 있고.
데이터가 조금 많다면..어떻게 했을까.

온갖 가지가지 방법들을 동원해서 써 왔었다.

숨겨진 iframe도 있었고 Webservice Behavior를 이용하는 방법, XmlHttp를 이용하는 방법에다가 
AJAX.NET Control Toolkit의 CascadingDropDown 까지..

많은 개발자들이 이러한 방법을 써 왔을 것이다.

문제는...
첫번째 DDL을 한번 선택할때마다 라운드 트립이 일어나며 서버에 댕겨와야 한다는 문제다...
이게...생각보다 부하가 크다..쿨럭.

그래서 이번엔 다른 방법을 소개한다.

XML을 이용한 방법...

먼저 xml 포맷을  예시를 통해 보도록 하자

<?xml version="1.0" encoding="utf-8"?>

<Sample>

    <Category Name="대분류1" Id="1">

        <SubCategory Name="소분류1" Id="1" />

        <SubCategory Name="소분류2" Id="2" />

    </Category>

    <Category Name="대분류2" Id="2">

        <SubCategory Name="소분류3" Id="3"/>

        <SubCategory Name="소분류4" Id="5" />

        <SubCategory Name="소분류5" Id="6"/>

    </Category>

</Sample>

뭐..그리 어려운 것은 아니다.
웹서버에 이런 형식의 Xml 파일을 만들어 놓고 내부의 데이터가 추가되거나 삭제 되면 Xml 파일을 수정 하면 되겠다.

대부분의 2 Depth 라면 이정도면 될것이도 3 Depth 이상이어도 뭐..달라질 것은 별루 없다.

이제 스크립트에서 이 xml 를 로드 하고 바인딩 하는 부분을 알아 보도록 하자.

    1 var xmlDoc = false;

    2 var isIE = true;

    3 

    4 function LoadPathogenicXml()

    5 {

    6     if(!xmlDoc)

    7     {

    8         if (window.ActiveXObject)

    9         {

   10             xmlDoc=new ActiveXObject("Microsoft.XMLDOM");

   11             xmlDoc.async = false;

   12             xmlDoc.load("/Xml/PathogenicList.xml");

   13             isIE = true;

   14 

   15             var err = xmlDoc.parseError;

   16             if (err.errorCode != 0)

   17             {

   18                alert("XML 문서 해석 실패 : " + err.reason);

   19                return false;

   20             }

   21         }

   22         else if (document.implementation && document.implementation.createDocument)

   23         {

   24             xmlDoc=document.implementation.createDocument("","",null);

   25             xmlDoc.async = false;

   26             xmlDoc.load("/Xml/PathogenicList.xml");

   27             isIE = false;

   28         }

   29         else

   30         {

   31             alert('현재 브라우저에서는 이 기능이 지원되지 않습니다.');

   32         }

   33     }

   34     return true;

   35 }

위 처럼 JS 파일을 만들어 보자..
1라인의 xmlDoc 은 xml문서의 개체이며 2 라인의 변수는 클라이언트의 브라우저를 판별하는 boolean이다.
8라인에서 IE의 경우에는 true를 리턴하며 그 외에는 false를 리턴한다.
22 라인에서는 firefox의 경우는 테스트를 해 보았으나 기타 브라우저에서는 테스트를 해 보지 못하였다.
xmlDoc 개체의 async 속성은 false를 주어야 한다.
설정을 하지 않게 되면 기본값 true가 되어 xml를 로드 하기 전에 다음 프로세스를 진행하는 경우가 발생된다.  그렇게 되면 xml 파일이 로드되지 않은 상태이기 때문에 바인딩이 되는 않는 경우를 볼 수 있다.

   37 function ShowSubCategory(categoryCode, ctl)

   38 {

   39     if(LoadPathogenicXml())

   40     {

   41         var root = xmlDoc.documentElement;

   42         if (root != null)

   43         {

   44             for(var j=0; j<root.childNodes.length; j++)

   45             {

   46                 var category = root.childNodes[j];

   47                 //IE에서는 localName은 항상 'undefined' 이며 FF에서는 '\n'의 경우 localName 이 null이다.

   48                 if(isIE || (!isIE && category.localName != null))

   49                 {

   50                     if(category.attributes.getNamedItem("Id").nodeValue == categoryCode)

   51                     {

   52                         Bind(category,ctl);

   53                         return true;

   54                     }

   55                 }

   56             }

   57         }

   58     }

   59     return false;

   60 }

페이지에서 호출되어야 하는 메서드이다.
FireFox 호환 땜시 코드가 약간 복잡해 졌다 IE만 지원하면 별 문제 없겠지만..ㅡ.ㅡ;;

어쨋든 ShowSubCategory메서드의 첫번째 인자는 키값이다, 선택된 options의 value 값을 넘겨 보내면 되겠다.
두번째 인자는 바인딩되어야 할 컨트롤이다.

첫번째 DDL을 선택했을때 이 메서드를 호출 한다면 두번재 매개변수의 값은 두번째 DDL의 개체가 될것이다.

44라인에서 root의 childNodes 컬렉션에 루프를 돌게 되는데 위 XML 처럼 입력되었을 경우 
FireFox의 경우에는 캐리지리턴도 하나의 노드로 인식이 된다. (쿨럭~~)
이 부분을 필터 하는 코드가 48 라인이다.

선택된 아이디가 맞으면 이제 바인딩을 하게 된다.

   62 function Bind(category, ctl)

   63 {

   64     while(ctl.length)

   65     {

   66         ctl.remove(0);

   67     }

   68 

   69     for(var i=0; i< category.childNodes.length; i++)

   70     {

   71         var node = category.childNodes[i];

   72         //IE에서는 localName은 항상 'undefined' 이며 FF에서는 '\n'의 경우 localName 이 null이다.

   73         if(isIE || (!isIE && node.localName != null))

   74         {   

   75             var optionElement = new Option(category.childNodes[i].attributes.getNamedItem("Name").nodeValue, category.childNodes[i].attributes.getNamedItem("Id").nodeValue);       

   76             ctl.options[ctl.options.length] = optionElement;  

   77         }

   78     }

   79 }

마지막으로 바인딩 하는 메서드이다.

바인딩 하기 전에 64 라인처럼 타겟 컨트롤의 options 를 모두 비운다.
그리고 넘겨 받은 카테코리의 자식 카테고리를 루프 돌면서 option을 생성하여 입력하게 된다.

75라인과 76라인은 ...
개인적으로 무척 애 먹었던 것이다.

덴장맞을 FireFox 때문인데 지금껏 으레 써 왔던 코드가 전혀 안먹혀서 고생을 했다.

add() 메서드로는 안먹히더라....

xml 로 바인딩을 하게 되면 당연하지만 DB에서 호출하는 것 보다 무쟈게 빠르다..게다가 xml 파일은 브라우저에서 캐시된다. 
물론 자주 데이터가 변경이 되고 변경된 데이터가 바로바로 보여지고 그래야 한다면 고민을 좀 해봐야 할것이다.(캐시를 사용하면 안되니깐.)

그러나 일반적인 경우라면 xmlhttp 보다 webservice behavior 보다 ajax.net toolkit의 cascadingdropdown 보다 월등한 성능을 낸다.

어쨋건..이로서 짧지만..아주 도움되는..xml 파일을 이용한 동적 DDL 바인딩에 대한 글을 마친다.


마지막 업데이트 : (5/11/2007 3:40:11 PM)

TAG : 없음



Trackback 보기 (0)
댓글 보기 (8)
revelati님의 글 (9/14/2007 12:04:14 PM)
apsx페이지에서 DDL를 생성한 후 저 스크립트를 호출하면 되는건가요??



이방은님의 글 (9/14/2007 1:17:18 PM)
네..그렇죠...



revelati님의 글 (9/14/2007 3:55:35 PM)
어느 시점에서 저 스크립트를 호출해야 되나요???
흠....죄송...



이방은님의 글 (9/14/2007 4:09:08 PM)
상위 DDL의 onchange 이벤트 이겠죠..^^;
상위 DDL의 값이 변경되면 하위 DDL을 다시 바인딩 한다..그런 의미죠.



revelati님의 글 (9/14/2007 6:31:50 PM)
방은님 정말 죄송한데요.
이거 예제는 없나요...
되긴 되는데 이상해요....
두번째 DDL에서 data가 살짝 보이는거 같더니만
사라려버리네요.ㅋ
귀찮게 해서 죄송합니다.



이방은님의 글 (9/14/2007 7:00:52 PM)
보였다가 사라지는 부분은...
아마도 바인딩 후에..
다시 초기화를 시키는 코드가 삽입되어 있나 봅니다..^^;
예제는 없습니다..쿨럭..
스크립트 디버깅을 해보셔야 할듯 합니다.



revelati님의 글 (9/15/2007 1:18:52 PM)
3depth로 변경할 때요
스크립트는 변경 안 해도 되고
xml파일만 변경하면 되나요??
서브카테고리 밑에 서브서브카테고리라고 주고 id값은 1부터 줬는데...
주말에 귀찮게 해서 죄송합니다.--;



이방은님의 글 (9/17/2007 10:06:07 AM)
위와 같은 방식으로는 메서드를 따로 만들어야 합니다..^^;
위 방식은 단지 패턴만 보여 주었을 뿐이구요..
만약에 깊이가 깊다면..
위 메서드를 응용해서 다른 메서드를 만들수도 있겠네요..^^;
일단 위 코드를 그대로 쓰기 위해서는 3depth일경우에는 메서드를 따로 만들어 줘야 합니다..
categoryCode, subCategoryCode, ctl 을 매개변수로 받는 메서드가 필요 하겠군요..^^;
범용적인 메서드를 한번 만들어 보시지요..^^;



댓글 쓰기

ASP.NET 2.0에서 Javascript 사용하기 (3)

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (5/10/2007 12:04:49 PM) Viewing : 8724

에 오늘은 PostBack 없이 사용하는 법에 대해서 알아 보겠다.

이전 버전에서 늘상..이용했던 방법은 대략 2가지 였다.

WebService Behavior 라는 기술과 XmlHttp 라는 기술이다.
WebService Behavior 에 대해서는 아래 링크를 참조해서 보도록 하며 XmlHttp는 앞으로 설명할 기술 및 AJAX의 근간이 되는 기술이다. 
이미 과거가 되어 버린 거라서..사용할 일이 있을지도 모르겠지만..

WebService behavior MSDN

뭐 과거에는 이렇게 했었다 라고만 생각해 두자 일단은...

이제 2.0 에 이르러서는  Javascript를 이용한 CallBack 기술이 생겼으며 AJAX 라는 것도 보편화 되어서 AJAX.NET 이라는 것도 정식으로 나오게 되었다.

하나씩 대충.(.ㅡ.ㅡ;;) 살펴 보도록 하겠다.

 


 ICallbackEventHandler

처음 나왔을때 아주 즐겨 썼던 기술이다. 물론 지금은 거의 AJAX.NET을 쓰지만 이 것도..꽤 많이 쓴다.
베타버전때와 구현 방법이 (인터페이스의 메서드가 변경) 달라서 VS2005정식버전 초기에 약간 고생했던 기억도....

이 기술의 내부 구현을 이해 하기 위해서는 XmlHttp의 이해가 필요하다.
내부적으로 이 기술을 이용하기 때문이다. 사실 사용만 하기 위해서는 몰라도 되긴 하지만..

이 기술의 핵심은 제목에서 보여준 ICallbackEventHandler 인터페이스와 GetCallbackEventReference 메서드이다.

GetCallbackEventReference 라는 메서드는 이전 글에서 알아본 ClientScriptManager 클래스의 멤버 메서드이다.
이 메서드를 호출 하게 되면 
HTML에 렌더가 될때 WebForm_DoCallback 라는 스크립트 메서드를 호출하는 구문을 추가 하게 된다.
이 WebForm_DoCallback 라는 스크립트 메서드는 System.Web.dll 어셈블리에 임베디드 되어 있는 Webforms.js파일에 정의 되어 있다.

이 스크립트 파일을 다운 받아 열어 보게 되면 아래와 같은 블럭을 볼 수 있다.

    var xmlRequest,e;

    try

    {

        xmlRequest = new XMLHttpRequest();

    }

    catch(e)

    {

        try

        {

            xmlRequest = new ActiveXObject("Microsoft.XMLHTTP");

        }

        catch(e) {

        }

    }

이 구문은..XmlHttp 를 사용할 때 개체를 생성하는 구문이다..
그렇다. ICallBackEventHandler는 XmlHttp를 이용하는 것이었다.

뭐 더 자세한 것을 알고 싶어 하는 사람이 있을까마는...있다면 이 js파일을 분석해 보기 바란다.

다시 원점으로 돌아 와서...

    1 String cbReference = this.Page.ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context");

    2 String callbackScript = "function CallServer(arg, context) {" + cbReference + "; }";

    3 this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "CallServer", callbackScript, true);

위 코드를 보게 되면 RegisterClientScriptBlock 메서드를 이용해서 CallServer라는 스크립트 메서드를 Page에 등록한다.
앞서 설명하였지만 GetCallbackEventreference 메서드는 WebForm_DoCallback 메서드를 등록하고 이는 CallServer메서드에서 호출된다.
이 부분을 렌더링 하게 되면 아래와 같이 된다.

<script type="text/javascript">

<!--

function CallServer(arg, context) {WebForm_DoCallback('__Page',arg,ReceiveServerData,context,null,false); }// -->

</script>

자 이제 스크립트에서 CallServer 메서드를 호출 하면 된다. 
이 메서드는 2개의 매개변수를 갖는다 첫번째는 서버에 넘결주 인자이며 두번째는 해당 개체의 컨텍스트이다.
이르자면 아래 코드 처럼 호출 할 수 있다.

<input type="text" onkeyup="CallServer(this.value, this)" />

서버 컨트롤이든 아니든 전혀 상관 없다 어짜피 스크립트 메서드를 호출 하는 것이므로,,,
위 예를 보게 되면 arg에 해당 텍스트박스의 value를 context에 해당 컨트롤을 넘겼다.

GetCallbackEventReference 메서드는 재정의가 되었는데 자세한 사항은 MSDN을 참조하기 바란다.
세번째 매개변수에 주목하기 바란다.
이 메서드는 Callback을 받을 스크립트 메서드의 이름이다. 위 예제 의 경우 ReceiveServerData로 정의 하였으므로 이 이름을 가진 스크립트 메서드를 만들어야 한다.

자 이제 서버에서 어떤 형식으로 받는지 알아 보도록 하겠다.

ICallbackEventHandler 인터페이스는 2개의 메서드를 선언한다.

public string GetCallbackResult() 와 public void RaiseCallbackEvent(string eventArgument) 이 그것이다.
참고로 베타 버전에서는 하나의 메서드만 있었으나 정식버전이 나오면서 2개의 메서드로 분리 되었다.

RaiseCallbackEvent 메서드의 경우에는 CallServer 스크립트에서 넘긴 arg 매개변수를 받는 일을 한다.
eventArgument라는 매개변수가 바로 그것이다.

GetCallbackResult 메서드는 실제로 어떠한 작업을 하고 그 결과 값을 리턴한다. 
넘겨 받은 argument 를 같이 사용하기 위해 넘겨 받은 값은 Page 클래스의 멤버 필드로 정의되어야 한다..쩝..

this.insertValue = eventArgument.Trim();

이런 식으로 필드에 값을 입력하고 GetCallbackResult 메서드에서 이 값을 사용할 수 있다.

GetCallbackResult메서드에서 처리하고 리턴 시킨 문자열의 결과 값은 위에서 설정한 스크립트 메서드인 ReceiveServerData에서 Callback을 받는다.

    <script type="text/javascript">

    function ReceiveServerData(rvalue, context)

    {

    }

 이 스크립트 메서드 역시 2개의 매개변수를 갖는데 첫번째 매개변수는 서버의 GetCallbackResult메서드에서 리턴한 문자열 값이며 두번째 매개변수는 CallServer에서 보낸 context 값이다.
이제 리턴 받은 문자열로 작업이 가능하다.

샘플로 AJAX.NET의 AutoComplete 컨트롤과 같은 기능을 하게끔 만들어 보았다. AutoComplete 컨트롤과 비교해 보기 바란다.

예외 처리 부분도 있으나 이 부분은 생략 하였다.

XmlHttp와 약간 차이점이 있다면 XmlHttp는 xml로 리턴을 받을 수 있다는 정도??? 일까...

어짜피 ICallbackEventHandler 인터페이스를 이용하는 방법도 내부적으로는 XmlHttp를 이용하므로 문자열을 리턴 받는 것은 같다고 보아도 되겠다.

이 기술은 단점이 몇개 있는데..
조금 전에 얘기 했던 타입이 문자열밖에 안된다는 문제나...한 페이지에서 서버에서 받는 메서드는 RaiseCallbackEvent 메서드 하나이기에 복수로 사용할수 없다는 문제다.
http://weblogs.asp.net/bleroy/archive/2005/04/08/397761.aspx 
위 링크에서는 커스텀 컨트롤인데 위에서 말한 단점들을 보완한다. 관심있는 분들은 링크를 방문해 보기 바란다.

그리고 아래 링크는 한 페이지에서 여러개의 CallbackEvent를 사용할수 있게끔 하는 코딩 기법을 보여준다.
역시 관심 있는 분들은 링크를 방문해 보기 바란다.
http://west-wind.com/weblog/posts/2302.aspx


마지막 업데이트 : (5/10/2007 12:06:59 PM)

TAG : 없음



첨부 파일 보기 (1)
Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기

ASP.NET 2.0과 XHTML 1.0 Transitional

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (1/25/2007 6:39:57 PM) Viewing : 2089
요즘 내가 관심을 가지고..주로 보는 부분이다.

예전 부터 html 을 상당히 어려워 했던 터라...

xhtml 또한 쉽지가 않다.

개발하는데 있어 W3C 표준을 준수하지 않아도 뭐..전혀 지장은 없으나..
개발자 가빠가..있지..ㅡ.ㅡ;;

허용하지 않는다.. ㅋ~~

사실 얼마전 FireFox 관련 문의를 받기 전까지는.. 별 생각이 없었으나..
FireFox를 설치 해보고 내 홈페이지를 한번 본후에..생각이 달라졌다..

이제서야 표준을 찾아서 읽어 보고 관련 글을 찾아 보게 되었다.

생각보다 관련들이 상당히 많더라.....

http://msdn2.microsoft.com/ko-kr/library/exc57y7e(VS.80).aspx

asp.net 2.0과 Xhtml 에 관련된 msdn 문서이다.
먼저 읽어 보기를 권한다.

그리고 국내 사이트에서도 xhtml 1.x 관련 글을 많이 볼 수 있다.

조금씩 조금씩 수정은 해 나가고 있으나 태그의 제한은 참으로  크다고 볼 수 있다.
이 문제가..초초 난감하다..ㅡ.ㅡ;

예를 들어..word-break  스타일의 경우 아주 유용한 스타일인데 이것은..표준이 아니다..IE에서만 지원 되며 W3C유효성 검사에서 걸린다..ㅡ.ㅡ;;;

이 외에..위 msdn에 나와 있지 않는 문제 중에서..
임베디드된 리소스의 렌더링 문제가 걸린다.
스크립트 파일이나 이미지 리소스들을 렌더 할때 쿼리 스트링에 & 대신에 &amp; 가 들어가야 하나..
글쎄..내가 모르는건지...원..@.@
validation나 기타등등의 이미 예약되어 있는 관련된 자동생성되는 리소스들은 정상적으로 &amp;로 렌더된다.
이르자면..

/WebResource.axd?d=KJ8KmyYEIkBWV17-XIEtOQ2&amp;t=632961633134938750

이 처럼 말이다..
그러나 사용자 정의로 만든 리소스들은 & 형태로 렌더가 된다..
이 부분은 좀 더 찾아 봐야 할 듯 하다..쩝..

아직 많은 페이지들을 변경해야 하지만..
아래 기념 샷 하나 남긴다.

기념샷


마지막 업데이트 : (1/25/2007 6:39:57 PM)

TAG : 없음



Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기



<< < 1 2 3 > >>