[펌] Smart Client 웹에 embedded 하는 부분.

[![](http://www.hoons.kr/img/hoonsbanner1.gif)](http://www.hoonsbara.com/)
[SmartClient 프로그래밍]
![](http://www.hoons.kr/img/arrow.gif)  [HOONS] (5) 실전 #2 – 윈도우 컨트롤 만들기
 **작성자** : 박경훈  **작성일** : 2006-09-01 오후 3:03:34
 **E-mail** : hoonsbara (at) hotmail.com ** Homepage** : [http://blog.hoons.kr](http://blog.hoons.kr/)
**[스마트 클라이언트(Smart Client) 강좌 순서]**
[(1) 스마트 클라이언트는 무엇인가?](http://www.hoons.kr/Lectureview.aspx?key=Lecture&LECCATE_IDX=29&ref=1&lecture_idx=239) [(2) 코드 엑세스 보안(Code Access Security)](http://www.hoons.kr/Lectureview.aspx?key=Lecture&LECCATE_IDX=29&ref=1&lecture_idx=240) [(3) 스마트 클라이언트의 주요이슈와 닷넷 2.0에서의 대안](http://www.hoons.kr/Lectureview.aspx?key=Lecture&LECCATE_IDX=29&ref=1&lecture_idx=241) [(4) 실전 #1 – 웹 서비스 만들기](http://www.hoons.kr/Lectureview.aspx?key=Lecture&LECCATE_IDX=29&ref=1&lecture_idx=242) [**(5) 실전 #2 – 윈도우 컨트롤 만들기**](http://www.hoons.kr/Lectureview.aspx?key=Lecture&LECCATE_IDX=29&ref=1&lecture_idx=243) [(6) 실전 #3 – 자동 보안설정 프로그램 만들기](http://www.hoons.kr/Lectureview.aspx?key=Lecture&LECCATE_IDX=29&ref=1&lecture_idx=244) [(7) 실전 #4 – 클릭온스를 이용한 보안설정 프로그램 배포](http://www.hoons.kr/Lectureview.aspx?key=Lecture&LECCATE_IDX=29&ref=1&lecture_idx=245)
이제 웹 브라우저에 임베디드(포함시킬) 될 컨트롤을 만들어 보도록 하겠다. 이 컨트롤은 먼저 서버에서 클라이언트로 배포한 후에 클라이언트에서 서버의 웹 서비스를 직접 호출하게 된다. 그리고 전달받은 데이터를 이 컨트롤에서 보여주게 될 것이다. 다음 그림을 보면 전체적인 아키텍쳐를 이해할 수 있을 것이다.![](http://www.hoons.kr/hoons/lecture/SmartClient/26-030.jpg) [스마트 클라이언트의 전체 구조] 윈도우 품에 대한 선수 지식이 있어야 한다. 하지만 여기서 구현할 컨트롤은 아주 간단한 컨트롤이기 때문에 다음 진행사항을 잘 따라 한다면 쉽게 데이터 그리드 뷰를 만들 수 있을 것이다. 기존 프로젝트에 Windows 컨트롤 라이브러리 프로젝트를 하나 추가하도록 하겠다. ![](http://www.hoons.kr/hoons/lecture/SmartClient/26-031.jpg) [Windows 컨트롤 라이브러리 프로젝트 생성] UserControl의 이름을 GridControl로 변경하였다. ![](http://www.hoons.kr/hoons/lecture/SmartClient/26-032.jpg) [GridControl] 그럼 이제 이 UserControl에 데이터그리드뷰 컨트롤을 추가해 보도록 하자. ![](http://www.hoons.kr/hoons/lecture/SmartClient/26-033.jpg) [도구상자] 그리드뷰를 추가하면 폼의 크기를 다음과 같이 늘려 본다. ![](http://www.hoons.kr/hoons/lecture/SmartClient/26-034.jpg) [데이터 그리드뷰] 데이터를 가져오기 전에 할 UI 준비는 끝났다. 이제 컨트롤이 로드 되는 그 시간에 웹서비스를 호출해서 데이터를 바인딩을 시켜주어야 한다. 먼저 Load 이벤트를 만들어 보도록 하겠다. GridControl 속성에서 Load를 더블 클릭 하도록 하자.![](http://www.hoons.kr/hoons/lecture/SmartClient/26-035.jpg) [Load 이벤트] 그럼 다음과 같은 로드 이벤트가 만들어 질 것이다.
privatevoid GridControl_Load(object sender, EventArgs e) { }
Load
이벤트에서는 웹서비스의 데이터를 가져온 다음에 그리드에 바인딩을 하는 작업을 하게 된다. 다음 그림을 참고하면 쉽게 이해할 수 있을 것이다. ![](http://www.hoons.kr/hoons/lecture/SmartClient/26-036.jpg) [Load 이벤트에서 하는 일] 그럼 이제 웹 서비스로부터 데이터를 받아오기 위해서 웹 참조 설정을 하도록 하겠다. ![](http://www.hoons.kr/hoons/lecture/SmartClient/26-037.jpg) [웹 참조 추가] 그럼 웹 참조 창이 뜨게 된다. 이전에 구현한 웹 서비스의 주소로 먼저 서비스를 조회하고, 참조이름을 설정했다면 참조 추가 버튼을 누른다. 피라는 SmartService라는 참조이름을 설정하였다. ![](http://www.hoons.kr/hoons/lecture/SmartClient/26-038.jpg) [웹 참조 추가] 참조가 되었다면 아래와 GridControl 클래스에 다음과 같은 Load이벤트와 메서드를 만들어 보자.
using System.Runtime.Serialization.Formatters.Binary; using System.IO; using System.IO.Compression;
001 privatevoid GridControl_Load(object sender, EventArgs e) 002 { 003   //웹서비스 호출 004   SmartService.Service WebSvr = new SmartService.Service(); 005 006   //압축 풀기 007   byte[] data = Convert.FromBase64String(WebSvr.GetService()); 008   DataSet ds = null; 009   ds = DecompressDataSet(data); 010 011   //그리드에 바인딩 012   dataGridView1.AutoGenerateColumns = true; 013   dataGridView1.DataSource = ds.Tables[0]; 014 } 015 publicDataSet DecompressDataSet(byte[] bytDs) 016 { 017   DataSet outDs = newDataSet(); 018 019   //스트림으로 가져오기 020   MemoryStream inMs = newMemoryStream(bytDs); 021   inMs.Seek(0, 0); 022 023   //1. 압축객체 생성압축 풀기 024   DeflateStream zipStream = newDeflateStream(inMs, CompressionMode.Decompress, true); 025   byte[] outByt = ReadFullStream(zipStream); 026   zipStream.Flush(); 027   zipStream.Close(); 028 029   //2. 스트림으로 다시변환 030   MemoryStream outMs = newMemoryStream(outByt); 031   outMs.Seek(0, 0); 032   outDs.RemotingFormat = SerializationFormat.Binary; 033 034   //3. 데이터셋으로 Deserialize 035   BinaryFormatter bf = newBinaryFormatter(); 036   outDs = (DataSet)bf.Deserialize(outMs, null); 037   return outDs; 038 } 039 040 //스트림을 Byte 배열로 변환 041 publicbyte[] ReadFullStream(Stream stream) 042 { 043   byte[] buffer = newbyte[32768]; 044   using (MemoryStream ms = newMemoryStream()) 045   { 046     while (true) 047     { 048       int read = stream.Read(buffer, 0, buffer.Length); 049       if (read <= 0) 050         return ms.ToArray(); 051       ms.Write(buffer, 0, read); 052     } 053   } 054 }
[소스 설명]
4 줄은 웹 서비스 객체를 초기화 하고 있다. 앞서서 웹 참조 추가할 때 설정한 추가 이름이 바로 여기서 참조하는 네임스페이스 명이 된다. 7 줄은 Base64 형식으로 리턴 하는 문자열을 받아서 byte 배열로 변환하고 있다. 9 줄은 압축되어 있는 데이터를 압축을 해제하고 압축을 해제한 바이너리 데이터를 DataSet 객체로 Desirailize 하는 작업이다. 15~38 줄에 DecompressDataSet() 메서드가 바로 이러한 작업을 대행하는 메서드가 되는것이다. 이번 장은 스마트 클라이언트에 관한 내용을 다루기 때문에 메서드 안에 있는 IO 관련 클래스들의 설명은 생략하도록 하겠다.
이렇게 코드가 작성이 되었다면 컴파일을 실행해서 DLL이 잘 만들어 지는지 확인하도록 한다. ![](http://www.hoons.kr/hoons/lecture/SmartClient/26-039.jpg) [생성된 DLL] 그럼 이제 이 컨트롤을 웹 브라우져에 로드해서 한번 실행 시켜 보도록 하겠다. 현재 프로젝트에 ASP.NET 웹 사이트 프로젝트를 하나 추가해 보도록 하겠다. ![](http://www.hoons.kr/hoons/lecture/SmartClient/26-040.jpg) [ASP.NET 웹사이트 추가] 앞서 만든 SmartContol.dll을 웹사이트가 생성된 곳으로 가져오도록 하자. 여기서 이 dll을 bin 폴더 안에는 넣으면 로드가 안되므로 bin폴더가 아닌 루트(Root)나 폴더를 생성해서 넣도록 하자. 필자는 웹사이트 루트로 이동 시켰다. 이제 웹 페이지를 하나 만들어서 아래와 같은 코드로 컨트롤을 로드 시켜 보자.
<objectid=’OBJECT2′style=’WIDTH: 700px; HEIGHT: 600px’classid=’SmartControl.DLL#SmartControl.GridControl’>object>
classid에서 dll을 참조하는 규칙은 다음과 아래와 같다.
**DLL****파일#네임스페이스.클래스**
이제 준비가 되었다면 브라우져를 열어서 컨트롤이 잘 로드 되는지 확인하도록 하자. 참조 정보가 잘못 설정되었다면 아래처럼 로드 되지 않는다.![](http://www.hoons.kr/hoons/lecture/SmartClient/26-041.jpg) [DLL을 찾을 수 없을 때] ![](http://www.hoons.kr/hoons/lecture/SmartClient/26-042.jpg) [네임스페이스나 클래스 설정이 잘못되었을 때] 올바르게 로드 되었다면 다음과 같은 에러 메시지 창이 뜨게 될 것이다. ![](http://www.hoons.kr/hoons/lecture/SmartClient/26-043.jpg) [보안 정책 에러메세지]![](http://www.hoons.kr/hoons/lecture/SmartClient/26-044.jpg) [그리드가 로드 되지만 데이터 바인딩이 되지 않은 데이터그리드뷰] 앞서서 설명했던 코드 엑세스 보안 정책으로 거슬러 올라가 보겠다. 코드 엑세스 보안 정책은 어디에서 어떤 코드를 실행하는지 검사한다고 했었다. 일단 웹에서 실행된 코드는 Internet 영역에서 보안을 검색하게 된다. Internet 보안 영역 에서는 그리드를 로드하고 웹 서비스를 호출하는 것에 대한 권한은 가지고 있다. 하지만 웹 서비스에서 받아온 데이터를 IO 클래스를 이용하여 압축을 해제하는 부분이 보안영역에 포함되어 있지 않은 부분이다. 앞서 설명한대로 수동으로 설정을 하던 자동으로 설정하는 프로그램을 만들던가 무언가의 설정을 해주어야 프로그램이 동작되는 것을 볼 수가 있다. 그럼 이제 URL 영역에 현재 자신의 IP를 등록시켜 보도록 하자. 코드 엑세스 보안을 수동으로 설정하는 부분은 앞에서 다루었기 때문에 따로 설명을 하지는 않겠다. 대신 주의 할 점은 localhost로 실행한 것과 아이피로 설정한 것은 서로 다른 사이트로 인식한다는 것만 알아두자. 수동으로 localhost에 FullTrust 권한을 주도록 하자. ![](http://www.hoons.kr/hoons/lecture/SmartClient/26-045.jpg) [URL 멤버 자격 조건 설정] 이제 권한을 다 주었다면 브라우져를 다시 열어서 다음과 같이 결과가 잘 출력되는지 확인해보자. ![](http://www.hoons.kr/hoons/lecture/SmartClient/26-046.jpg) [데이터 그리드뷰]