Korea Evangelist

Developer & Platform Evangelism, Microsoft Korea

August, 2010

  • Korea Evangelist

    [PHP개발] 후덜덜~ 진짜? WebMatrix로 깔끔하게 PHP 개발이 가능?

    • 3 Comments

    안녕하세요. 코난 김대우 입니다.

    웹 개발을 해 오신 분에게는 약간 의아 할지도 모르겠습니다.

    - “오잉? 마이크로소프트 웹 개발 도구인 WebMatrix로 PHP 개발이 가능해? 그래 봐야 어플리케이션 동작도 안되는 거 투성이겠지…”

    조금만 다르게 봐 주셔도 좋을 것 같습니다.

     

    WebMatrix는

    - WebMatrix는 완전한 무료 개발 플랫폼으로, 하나의 도구에서 웹서버, 개발, 배포, DB작업이 가능합니다. 
    - WebMatrix는 무료로 제공됩니다.
    -  WebMatrix로 PHP 개발은 APM 기반 구성만큼 쉽고, 빠르게 PHP 개발 환경을 지원합니다

     

    아~ PHP 개발자셔서 WebMatrix 가 생소 하시다면, 이에 대한 소개는 아래 내용을 참고 하세요.

     

    (1) WebMatrix와 Razor! 이제 시작합니다.
    (2) WebMatrix 설치부터 Hello World까지
    [동영상 강좌] (1) WebMatrix 첫 실행 & Hello World까지 달려요~
    [동영상 강좌] (2) WebMatrix 5분 리뷰~

    서론이 길었나요? 이제 PHP 개발을 위한 개발 환경 구성을 알아 보도록 하겠습니다.


    (1) WebMatrix에서 PHP를 개발하기 위한 개발환경 구성
    사실 쉬운 방법으로 설치할 경우에는, 클릭질 몇 번이면 5분 만에 끝나서 뭐라 말씀 드리기 부끄럽습니다. 쿨럭.
    WebMatrix로 PHP를 개발하기 위한 “쉬운” 환경을 구성 하시려면 아래 링크를 통해 그냥, WordPress를 설치 하시길 권장해 드립니다.(추천 드립니다.)
    WordPress 어플리케이션을 설치 하시면 자동으로 PHP구동을 위한 모든 요소들을 자동 설치하고, WebMatrix에 포함된 웹서버인 IIS Developer Express에 PHP 세팅도 자동으로 완료 합니다. – 너무 쉽나요. ^_^;;;
    쉬운 PHP 개발 환경 구성을 원하시면, 아래 문서를 보시고, WebMatrix에서 WordPress를 설치 하세요. PHP 개발 경험이 있으시니 아주 쉬우실 거에요.
    PHP 구성 : WordPress를 5분 안에 설치 완료하는 방법 - WebMatrix 설치
    쭉~ WordPress 설치 강좌를 보시면 느끼실 겁니다. 와우~ 분명 PHP로 만들어진 오픈 소스 블로그인 WordPress가 WebMatrix에서 아주 잘 동작하지요.  당연히 저랑 같이 진행하는 것도 잘 될거라는 느낌이 오시겠지요? 그럼 이제 저와 함께 빈 웹사이트를 하나 만들고 phpinfo(); 를 날려 보도록 하지요.


    (2) 비어있는 웹사이트를 만들고, PHP 환경을 구성합니다.
    image
    빈 웹사이트를 만들기 위해, WebMatrix에서 왼쪽 맨 위의 메뉴를 클릭하고, Site From Template를 선택합니다.

    image
    Empty Site를 선택하고, 웹사이트 이름은 PHP Test로 짓겠습니다.

    image
    PHP Test 웹사이트가 만들어진 게 보이실 겁니다. 이제 PHP 파일을 추가 해야지요. 왼쪽 하단의 Files를 선택합니다.

    image
    이렇게 폴더 구조의 화면이 보이실 거에요. “Add a file to your site”를 클릭하시거나 New를 통해 파일을 추가합니다.

    image
    아쉽게도 “아직 까지는(많은 의미가 있지요? ^_^;;;)” 파일 포맷에 PHP를 공식 지원하지는 않습니다. 하지만 가능 하다는 거!!!
    파일 이름은 HTML을 고르시고, 아무렇게나, 저는 phpinfo.php 파일로 했습니다.

    image
    PHP개발자라면 처음 PHP 설치 여부 테스트를 위해 늘상 돌려 보시는 phpinfo();를 실행합니다. 저장하시고 F12를 누르시거나, 왼쪽 위의 Run 버튼을 누르시면 실행됩니다.

    image
    PHP가 아주 자알~ 동작 합니다~


    (3) 어떤 PHP가 설치된 겁니까? PHP 코드 하일라이팅 기능 등의 환경도 지원하나요?
    WordPress를 설치하는 화면을 자세히 보신 분은 아실 겁니다.
    WebMatrix의 “웹 플랫폼 설치 관리자” 기능을 통해 다운로드한 모든 PHP 구동을 위한 파일은, 공식 웹사이트(PHP나 MySQL, WordPress 설치 파일들 모두)에서 공식 버전을 자동으로 다운로드해 설치되며, 설정 파일이 변경된 커스텀 패키징이나 다른 수정 패키지를 이용하지 않습니다.

    공식 버전이기 때문에 설정 파일도 따로 가공되어 있지 않고 설치되는 것이 장점입니다. – 배포할 경우에 장점이 되지요. WebMatrix에 포함된 웹서버는 아파치가 아닌 마이크로소프트의 웹서버인 IIS가 설치되어 있으며, PHP 구동을 위한 환경을 제공합니다.
    혹시, 알고 계신지요? 지금 보고 계신 이 SQLER 웹사이트도 PHP기반 XpressEngine이 IIS에서 PHP on Windows로 오늘도 자알~ 구동되고 있습니다.

    PHP를 IIS에서도 잘 돌리실 수 있으며 다른 웹서버나 플랫폼들에 비해 여러 장점들을 제공합니다. – 곧 상세한 포스트로 풀어 보도록 할게요. PHP 개발자들이 참고하셔도 좋을 IIS에 대한 포스트는 phpschool에서 제공되고 있는 IIS 강좌와 여기, SQLER에서 제공되는 IIS 강좌를 참고 하시길 바랍니다.

    PHPSchool의 강좌 게시판에서 제공되는 IIS 강좌 : http://phpschool.com/gnuboard4/bbs/board.php?bo_table=teach
    SQLER에서 제공되는 IIS 강좌와 팁 게시판 : http://www.sqler.com/bIISLec

    image
    PHP 코드 하일라이팅 기능이나 PHP 테스트 & 실행, 배포를 환경을 모두 지원합니다. SEO 분석이나, 오류 로깅, DB연동 등의 자세한 WebMatrix의 기능은 아래 링크를 참고하세요.

    (1) WebMatrix와 Razor! 이제 시작합니다.
    (2) WebMatrix 설치부터 Hello World까지
    [동영상 강좌] (1) WebMatrix 첫 실행 & Hello World까지 달려요~
    [동영상 강좌] (2) WebMatrix 5분 리뷰~

     

    (4) WordPress 설치를 하지 않고 PHP를 WebMatrix에 구성하는 방법
    WordPress를 설치하면서 자동으로 PHP가 IIS에 구성된다고 말씀 드렸는데요. 개발자는 어떤 구성이 이루어지는지 알아야겠지요.
    아주 간단합니다. 정확히는, WebMatrix의 문제가 아니라, WebMatrix에 포함된 개발용 웹서버인 IIS Developer Express의 config 파일을 변경해 php 모듈이 동작하게 돕는 것이지요.

    - WebMatrix를 처음 설치 완료하신 상태
    - PHP를 공식 사이트에서 다운로드 받으시고“c:\php” 에 설치
    - WebMatrix에 기본 포함된 웹서버인 IIS Developer Express의 config  구성 파일 두 군데 수정이 필요합니다.
    이 WebMatrix의 IIS 구성 파일은 이 경로에 위치하고 있습니다.
    C:\Users\[현재로그인한 사용자]\Documents\IISExpress8\config  폴더의 applicationhost.config 파일을 메모장으로 열어 주세요.

    <fastCgi />

    위의 한 줄을 아래로 변경해 주세요.

    <fastCgi>
        <application fullPath="C:\PHP\php-cgi.exe"
                     activityTimeout="600"
                     requestTimeout="600"
                     instanceMaxRequests="10000">
            <environmentVariables>
                <environmentVariable name="PHP_FCGI_MAX_REQUESTS"  value="10000" />
                <environmentVariable name="PHPRC"  value="C:\PHP" />
            </environmentVariables>
        </application>
    </fastCgi>

    주의 하실 것은, C:\php 폴더에 PHP를 설치 하셨을 경우 입니다. 만약 다른 폴더라면 위의 두 군데 PHP 설치 경로를 수정해 주세요.
    참고로 이 작업은 IIS가 FastCGI로 PHP를 실행 하도록 매핑 해주는 작업입니다.

    이 config 파일의 맨 마지막 라인이 아래처럼 되어 있을 겁니다.

    </configuration>

    이 부분을 아래처럼 수정해 주세요.
    즉,  <configuration> 위에 <localtion path="PHPSite"> 부터 시작되는 라인들을 추가하는 거에요.

    ...
    <location path="PHPSite">
    <system.webServer>
           <handlers>
                  <add name="PHP via FastCGI"
                       path="*.php" verb="*"
                       modules="FastCgiModule"
                       scriptProcessor="C:\PHP\php-cgi.exe"
                       resourceType="Either" />
           </handlers>
    </system.webServer>
    </location>

    </configuration>

    참고로, 이 작업은 IIS의 처리기(Handler)로 php 확장자를 가진 파일에 대한 요청을 실행하는 처리기(php-cgi)를 구성하는 작업입니다.
    이렇게 수행하시고, 마찬가지로 위에서 수행한 PHP 파일을 만들고 phpinfo();를 실행하시면 PHP가 잘 동작하는 게 보이실 겁니다.

     

    (5) WebMatrix로 MySQL 데이터베이스를 GUI 기반으로 처리(테이블 생성, 조회, 쿼리 등의 작업 가능)
    GUI기반 테이블이나 데이터베이스 툴이 없는 MySQL은 저처럼 GUI기반 툴이 익숙한 사람에게는 고역입니다.  특히, 명령프롬프트에서 mysql.exe를 가지고 쿼리 짤때는 저같은 정말 머리 터지는데요… 쿨럭…
    WebMatrix를 이용하시면 이렇게 PHP로 자주 사용되는 MySQL DB 뿐만 아니라, MSSQL도 쉽게 연결해 GUI기반 관리 작업이 가능합니다.
    image

    왼쪽 아래의 “Databases”를 선택하고, 상단의 “New Connection”을 실행하면 이렇게 DB 커넥션 설정 화면이 나옵니다. 이어서, MySQL 접속 정보를 넣으시면 아래와 같은 화면을 볼 수 있습니다.

    image
    GUI 기반 테이블 데이터 조회 – 테이블에서 Data를 누르거나 테이블을 더블클릭 하면 됩니다.

    image
    Definition을 하시면 이렇게 테이블 디자인 화면이 나옵니다. - GUI 기반 테이블 디자인 생성이나 수정

    image
    SQL 쿼리 수행을 위해서는 상단의 “New Query”를 누르고 수행할 쿼리를 쿼리 창에 넣은 후 “Execute”나 F5를 누르면 쿼리가 실행되어 결과창에 결과가 표시 됩니다.  이렇게, MySQL이나 MSSQL DB기반 작업을 GUI로 처리 가능한 무료 툴이 WebMatrix입니다.

    개인적으로 MySQL 기반 개발 하시는 분들에게는 큰 메리트가 아닐까 생각됩니다.

     

    (6) PHP 어플리케이션 배포(Deploy) – FTP 방식 등을 자체에서 지원
    WebMatrix는 만든 PHP나 웹 어플리케이션을 쉽게 배포할 수 있도록 배포 기능을 기본 포함하고 있습니다.

    WebMatrix17.png
    이렇게 Publish를 하시면 됩니다. – 또는 즉석에서 호스팅 서비스를 찾을 수도 있습니다.(현재 호스팅 서비스 찾기는 해외만 지원됩니다.)

    image

    배포는 이렇게 FTP와 FTP/SSL 방식, Web Deploy 방식을 지원합니다. Web Deploy 방식은 약간 생소하실지 모르겠습니다만, IIS 웹서버에서 웹 배포 도구를 설치하시고 통신할 수 있는 기능입니다. FTP방식 등은 아마 익히 잘 알고 계실 거에요. 서버 정보나 로그인 정보 등을 넣으시면 바로 만드신 PHP 어플리케이션 배포가 가능해집니다.

    이렇게 WebMatrix의 PHP 개발 기능을 간단히 살펴 봤습니다. 어떠세요? 도움이 되셨는지 모르겠습니다. 

    - WebMatrix는 Razor는 물론,  PHP도 웹서버 + 데이터베이스 GUI 관리  + 개발 + 배포 과정을 하나의 툴에서 수행 가능한 통합 개발 환경입니다.
    - WebMatrix 안에 자체 내장된 IIS Developer Express를 이용하면 가볍고 빠른 개발용 웹서버 기능에 PHP도 완전하게 지원합니다.
    - MSSQL은 물론 MySQL과 같은 데이터베이스 역시 WebMatrix에서 쉽고 편한 GUI 기반으로 보면서 DB관리와 개발이 가능합니다.
    - 배포 도구도 내장되어 있어 개발 후 즉시 배포해 테스트가 가능합니다.

    도움이 되셨는지 모르겠네요. WebMatrix로 PHP를 개발하시면 많은 도움 되실 겁니다.

    상세히 설명 드렸으니 꼭 저처럼 수행해 보시고 궁금하신 점이나 필요하신 점을 댓글로 말씀 주시면 최선을 다해 도움 드리겠습니다.
    좋은 하루 되세요.

     

    참고자료 :
    (1) WebMatrix와 Razor! 이제 시작합니다.
    (2) WebMatrix 설치부터 Hello World까지
    [동영상 강좌] (1) WebMatrix 첫 실행 & Hello World까지 달려요~
    [동영상 강좌] (2) WebMatrix 5분 리뷰~
    http://ruslany.net/2010/07/install-php-applications-with-webmatrix/
    http://blogs.msdn.com/b/brian_swan/archive/2010/07/12/creating-php-websites-with-webmatrix.aspx
    WordPress를 5분 안에 설치 완료하는 방법 - WebMatrix 설치
    마이크로소프트 웹 플랫폼 - (2) 마이크로소프트 웹 플랫폼은 무엇인가?
    [1-1] Microsoft 웹 플랫폼 설치 관리자(Windows Platform Installer)
    [1-2] PHP 어플리케이션을 위한 IIS 웹 서비스 설치 및 구성
    [1-3] SQL Server Driver for PHP 설치
    [1-4] 인터넷 정보 서비스 관리자의 웹 사이트 기능 소개
    [1-5] 인터넷 웹 서비스를 위한 Internet Information Services (IIS) 7 의 소개

  • Korea Evangelist

    Java vs. .NET 성능 비교 (2010.07)

    • 3 Comments

    약 한달 전 쯤인 2010년 7월 2일 마이크로소프트가 닷넷과 자바에 관한 웹 애플리케이션 및 웹 서비스에 관한 성능 비교 자료를 내놓았다. 이름하여 "Microsoft .NET Framework 4.0 vs. IBM WebSphere 7 StockTrader Benchmark Report”로서 이는 작년 2009년 3월에 공개한 성능 비교 자료에 대한 업데이트이다.  작년 비교자료에 대해 올렸던 이전 포스트를 참고하면서 이 포스트와 함께 비교하며 읽으면 한층 재미가 있을 것으로 생각한다. 비교자료에 관한 상세한 정보는 http://msdn.microsoft.com/stocktrader 에서 찾을 수 있으며, 이 테스트에 사용된 모든 자바 및 닷넷 소스 코드 또한 이 싸이트에서 다운로드 받을 수 있다. 
    예전 비교와 달라진 것은 .NET Framework 버전이 3.5에서 4.0으로 업그레이드 되었고, Windows Server 버전이 2008에서 2008 R2로 달라졌고 따라서 IIS 또한 7.0에서 7.5로 높아졌다. 아울러 모든 테스트 환경은 64 Bit인 것은 작년과 동일하다.

    이 테스트는 IBM이 WebSphere 기반으로 J2EE의 베스트 프랙티스를 바탕으로 만든 애플리케이션인 Trader를 닷넷 버전으로 만들어 아키텍처나, 각종 WAS 세팅에 대한 정보를 공개하여 독자 검증을 거치고 있으며, 성능과 확장성을 검증하며 이에 드는 비용을 산정하여 가장 비용 합리적인 애플리케이션 구축 방안을 제시함을 목적으로 한다. (예전 PetStore 관련 비교시와는 전혀 다르며 아키텍처나 소스 코드를 모두 공개하여 자신있게 결과를 공표하고 있다.)

    서버 사양
    1. IBM Power 570 with IBM WebSphere 7 and AIX 5.3
    2. Hewlett Packard BladeSystem C7000 with IBM WebSphere 7 and Microsoft Windows Server 2008 R2
    3. Hewlett Packard BladeSystem C7000 with Microsoft .NET 4.0 and Windows Server 2008 R2
    JavaEE의 경우 IBM Power 570에서 한번, HP BladeSystem에서 한번, 이렇게 두번 진행하고 .NET의 경우 HP BladeSystem에서 한번 진행했다. (아마도 오해의 소지를 없애기 위해 JavaEE의 경우 IBM H/W에서 한번, 동일한 조건의 HP H/W에서 한번 진행한 것으로 보인다.)

    테스트 항목 (작년과 동일)
    1. 일반적인 웹 애플리케이션 성능 비교 : 웹 페이지에서 비지니스 로직을 호출하고 데이터베이스에서 가져온 정보를 웹에 뿌리는 일반적인 웹 애플리케이션 성능 비교로서 자바의 경우 JSP + Servlet + JDBC direct 호출 방식으로 오해를 없애기 위해  EJB를 사용치 않았다. 닷넷의 경우 ASP.NET + BLL + ADO.NET의 일반적인 방식을 따른다.
    2. 미들티어 웹 서비스 성능 비교 : 클라이언트 부분은 배제하고, 비지니스 로직에서 데이터베이스 접근 로직을 거쳐 가져온 데이터를 SOAP 기반의 표준 웹 서비스로 노출하는 것 까지를 포함한다. 즉, SOAP 메시지로 serialization하는 성능까지만 포함한다.
    3. 웹 서비스 벤치마크 (WSTest) : 애초 Sun 만들어 배포한 WSTest를 수정하여 진행하는 것으로 비지니스 로직을 전혀 담지 않고 순수하게  자바와 닷넷의 웹 서비스 스택 성능만을 비교한다. 즉, IBM WebSphere의 웹 서비스 스택 즉 JAX-WS 구현체와 마이크로소프트의 웹 서비스 구현체인 WCF의 성능을 비교한 것이다.

    위 세가지 경우에 있어서 공통적으로 적용한 규칙은 테스팅 툴을 사용하여 30분간 부하를 적용하고 유지가능한 최고 TPS (Transaction per second)를 선정하는 것이다. 또한 성능 테스트에서 인프라가 방해를 하지 않도록 데이터베이스 서버의 CPU는 항상 50% 미만을 유지하도록 하였고, 비지니스 로직이 올라가는 서버 (WAS)의 CPU는 96% 정도 유지하여 최상의 성능을 발휘하도록 설정하였다.

    시스템 아키텍처
    웹 애플리케이션 성능 비교의 경우 Mercury의 LoadRunner를 사용하였으며, 32대의 물리적 클라이언트가 사용되었고, 각 클라이언트는 수백명의 서로 다른 사용자로 부하를 생성했으며, 각 사용자는 매 요청마다 1초의 Think time을 갖는 방식으로 진행되었으며 30분간 진행되었다. 에러 발생 빈도는 측정 기간동안 0.01%이내에 위치하도록 모니터링되었다.

    image

    미들티어 웹 서비스 성능 비교 및 WSTest 웹 서비스 벤치마크의 경우에는, .NET Capacity Planner 웹 서비스 테스트기를 이용하였고, 0.1초의 Think Time을 갖는 10개의 서로 다른 클라이언트에서 부하를 생성하였다.

    image

    공정한 벤치마크 테스팅을 위한 고려사항
    1. 자바의 경우, Java EE 5 기반의 WebSphere 7에서 최적화되고 가장 빠른 Trader 애플리케이션 적용하였으며, EJB사용하지 않고 직접 JDBC를 호출하여 데이터베이스 작업하는 방식으로 JSP 와 Servlet 만을 이용하여 개발되었다. 또한 최적의 성능을 위해 WebSphere의 경우 쓰레드 풀, 커넥션 풀, queue connection factory, Heap size 등등에 대한 튜닝이 진행되었으며 결과적으로 최고 TPS 측정시 CPU 사용량이 96~100%이 될 수 있도록 하였다.
    2. 캐쉬의 경우 양쪽 모두 적용하였다. 자바의 경우 WebSphere Servlet Caching을 적용하였고 닷넷의 경우 .NET Cache API를 적용하였다.
    3. 데이터베이스의 부하 측면에서는 StockTrader를 만든 IBM의 기본 부하보다 더 현실적으로 하기 위해 500,000계정으로 각 계정마다 5개의 주문, 100,000 quote를 기본으로 가져가도록 했다.
    4. 데이터베이스 구성은 IBM WebSphere 7의 경우 All-IBM 구성을 따랐으며 IBM DB2 v9.5 (Enterprise Edition), 최신의 IBM DB2 v9.5 JDBC 드라이버가 사용되었다. .NET의 경우 SQL Server 2008 (Enterprise Edition)을 사용하였다. 이 벤치마크는 데이터베이스 성능 비교가 아니기 때문에 데이터베이스때문에 결과가 왜곡되지 않도록 충분한 성능을 발휘하는 H/W를 제공되었다. (자세한 H/W 사양은 결과 리포트를 참고하시길...)
    5. 총 36페이지 보고서에 공정한 테스트를 위한 고려사항 무려 6페이지를 차지할 정도로 닷넷과 자바 양 진영에서 모두 수긍할 수 있는 수준을 유지하려 했다.
    6. 뒷 부분 부록에는 6페이지에 걸쳐 이 테스트에 사용된 각종 하드웨어, 소프트웨어에 대한 목록과 가격표를 제공한다. 또한 부록 B에는 3장에 걸쳐 WebSphere와 IIS에 대해 설정한 각종 설정값 및 튜닝한 정보를 상세히 제공하여 오해의 소지를 없앴다.

    벤치마크 결과
    1. 일반 웹 애플리케이션 성능 비교
    앞서 기술한 대로 IBM WebSphere 7의 경우 EJB 없이 JSP/Servlet만으로 직접 JDBC 호출한 것이며, .NET의 경우 ASP.NET/Web Forms에서 ADO.NET을 통해 데이터베이스 호출한 경우이다.  작년 결과와 비교하면, 약간 의외의 사실도 발견할 수 있다. 전반적인 결과는 작년과 비슷하나 TPS 측면에서 Windows Server 2008 기반의 WebSphere의 성능은 향상되었고, IIS의 성능은 약간 내려가서 오히려 Windows Server 2008 R2 기반에서 WebSphere가 IIS보다 TPS숫자는 아주 약간 높게 나왔다. 물론 Power 570 보다는 Windows Server 2008 R2기반일 때 성능이 훨씬 좋다.

    image

    위와 같은 TPS를 달성하기 위해 지출된 비용을 산정하여, 역으로 하나의 TPS를 달성하기 위한 지불된 비용을 계산하면 아래와 같다.

    image

    이를 통해 다음과 같은 사실을 알 수 있다.
    1. .NET / Windows Server 2008 R2 / HP BladeSystem C7000 조합이 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 기반의 Java EE에 비해 37% 성능이 우수함을 알 수 있으며, 서버를 구성하기 위해 들어간 절대 비용 측면에서는 오히려 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우가 .NET / Windows Server 2008 / HP BladeSystem C7000 에 비해 419% 더 지출된 것을 알 수 있다.
    2. IBM WebSphere 7 / Windows Server 2008 R2 / HP BladeSystem C7000 의 성능이 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 에 비해 성능이 39% 더 나은 것을 알 수 있으며, 서버 구성에 들어간 절대 비용 측면에서는 오히려 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 조합이 IBM WebSphere 7 / Windows Server 2008 / HP BladeSystem C7000조합보다 198% 더 비싼 것을 알 수 있다.
    3. 전반적으로 Windows Server 2008 R2 기반의 닷넷이 비용 성능 측면에서 훨씬 우수함을 알 수 있다. IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 조합은 .NET / Windows Server 2008 R2 / HP BladeSystem C7000 조합보다 성능 대비 비용이 8배 높은 것으로 나타났다. 이는 결국, 같은 부하를 감당하는 시스템을 구축할 경우 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 조합이 .NET / Windows Server 2008 R2 / HP BladeSystem C7000 조합에 비해  비용을 8배나 더 지출해야함을 의미한다.

    2. 미들티어 웹 서비스 테스트
    이 테스트는 StockTrader의 비지니스 서비스 앞단에 웹 서비스를 위한 Facade를 만들고 이 Facade부터 데이터베이스 단까지의 성능을 비교한 것이다. 앞의 웹 애플리케이션 성능 비교와 다른 점은 전체 페이지가 아닌 개별 SOAP 요청이 처리되는 것을 기준으로 TPS가 산출된다는 것이다.
    IBM WebSphere의 경우 웹 서비스 Facade는 JAX-WS로 구현되었고 표준 SOAP/WSDL 기반의 서비스를 노출하며, 사용자의 요청을 IBM HTTP Server가 WebSphere상의 웹 서비스 티어로 전달하는 구조로 되어 있다. .NET의 경우 WCF를 사용하여 웹 서비스 Facade를 구현하였고 SOAP/WSDL 기반의 표준 웹서비스를 노출하며, IIS 7.5가 사용자의 요청을 WCF 기반의 서비스에 전달한다.
    .NET Capacity Planner 웹 서비스 테스트 툴을 이용하여 SOAP 요청을 생성하여 테스트를 진행하였다.

    image

    비용 대비 성능비 (Price Performance Ratio) 는 아래와 같다.

    image

    결과를 통해 다음과 같은 사실을 알 수 있다.
    1. .NET / Windows Server 2008 R2 / HP BladeSystem C7000 조합이 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 조합에 비해 웹 서비스 성능이 111% 더 우수함을 알 수 있다. 반면, 서버 구성에 지출된 절대 비용 측면에서는 오히려 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 서버의 경우가 .NET / Windows Server 2008 / HP BladeSystem C7000 의 경우보다 419% 더 지출된 것을 알 수 있다.
    2. IBM WebSphere 7 / Windows Server 2008 R2 / HP BladeSystem C7000 조합의 경우가 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우보다  성능이 37% 더 우수함을 알 수 있다.  반면 서버 구성에 지출된 절대 비용 측면에서는 오히려 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우가 IBM WebSphere 7 / Windows Server 2008 / HP BladeSystem C7000의 경우보다 198% 더 지출된 것을 알 수 있다.
    3.전반적으로 비용 대비 성능 측면에서 Windows Server 2008 R2 기반의 닷넷 시스템이 훨씬 나은 결과를 보여주고 있다. .NET / Windows Server 2008 R2 / HP BladeSystem C7000 의 경우가 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우에 비해 비용 대비 성능 측면에서 10배 우수함을 보여준다. 이는 결국 같은 웹 서비스 성능을 내는 시스템을 구축할 경우, IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 을 사용할 경우 .NET / Windows Server 2008 R2 / HP BladeSystem C7000 을 사용할 때보다 10배 비싼 구축 비용을 지불해야 함을 의미한다.

    3. WSTest 벤치마크
    WSTest는 뒷단 비지니스 로직이나 데이터베이스 엑세스 없이 순수하게 구현 플랫폼의 웹 서비스 스택 성능 (즉, XML Serialization/Deserialization, http 네트웍 접근 등) 을 비교하는 것이다. WSTest는 원래 썬마이크로시스템즈에서 고안한 것으로 마이크로소프트가 보완하여 적용하였다.
    IBM WebSphere 7의 경우, 앞의 미들티어 웹 서비스 성능 벤치마크에서와 마찬가지로 JAX-WS 기반의 웹 서비스 스택에서  SOAP/WSDL 기반의 표준 웹 서비스로 노출시켜 진행하였으며, 전달된 요청은 IBM Http Server가 IBM WebSphere 7 서버내의 웹 서비스 구현체에 전달하는 구조로 되어있다.
    .NET의 경우, WCF를 이용하여 SOAP/WSDL 기반의 표준 웹 서비스를 노출시켰고, 전달된 요청은 IIS 7.5이 WCF 기반의 웹 서비스 구현체에 전달하는 형태로 되어 있다. 표준 기반의 웹 서비스이기 때문에 IBM WebSphere 7기반의 자바 구현체와 .NET 기반의 구현체 사이에 상호 운용이 가능하다.

    image

    비용 대비 성능비 (Price Performance Ratio)로 환산한 결과는 다음과 같다. 비용 산출에 대한 근거는 리포트의 Appendix에 상세히 설명되어 있다.

    image

    위 결과를 통해 다음과 같은 사실을 알 수 있다.
    1. .NET / Windows Server 2008 R2 / HP BladeSystem C7000 조합이 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 조합의 경우에 비해 최소 120% 성능이 더 우수함을 알 수 있다. (WSTest의 각 Operation별로 조금씩 다르다.) 반면 서버 구성에 지출된 절대 비용 측면에서는 오히려 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 서버의 경우가 .NET / Windows Server 2008 R2 / HP BladeSystem C7000의 경우보다 419% 더 지출된 것을 알 수 있다.
    2. IBM WebSphere 7 / Windows Server 2008 R2 / HP BladeSystem C7000 조합의 경우가 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우보다  성능이 51% 더 우수함을 알 수 있다.  반면 서버 구성에 지출된 절대 비용 측면에서는 오히려 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우가 IBM WebSphere 7 / Windows Server 2008 R2 / HP BladeSystem C7000의 경우보다 198% 더 지출된 것을 알 수 있다.
    3. 전반적으로 비용 대비 성능 측면에서 Windows Server 2008 R2 기반의 닷넷 시스템이 훨씬 나은 결과를 보여주고 있다. .NET / Windows Server 2008 R2 / HP BladeSystem C7000 의 경우가 IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 의 경우에 비해 비용 대비 성능 측면에서 10배 우수함을 보여준다. 이는 결국 같은 웹 서비스 성능을 내는 시스템을 구축할 경우, IBM WebSphere 7 / IBM AIX 5.3 / IBM Power 570 을 사용할 경우 .NET / Windows Server 2008 R2 / HP BladeSystem C7000 을 사용할 때보다 10배 비싼 구축 비용을 지불해야 함을 의미한다. (최대 TPS 달성시 기준으로 단위 TPS당 드는 비용 산출)

    결론
    웹 애플리케이션을 구축할 경우, Windows Server 2008 R2 기반의 닷넷 시스템이 IBM Power 570 기반의 WebSphere 7 기반 Java EE 시스템에 비해 가격은 1/5 수준으로 성능은 37% 더 나은 시스템을 구축할 수 있음을 알 수 있다. 같은 WebSphere 7 기반의 웹 애플리케이션 시스템 구축의 경우에도 Windows Server 2008 R2 / HP BladeSystem C7000 위에서 구동하는 것이 IBM AIX 5.3 / IBM Power 570 위에서 구동하는 것에 비해 가격은 1/3 수준으로, 성능은 39%  더 나은 결과를 제공할 수 있음을 알 수 있다.
    웹 서비스를 구축할 경우에도, Windows Server 2008 R2 기반의 닷넷 시스템이 IBM Power 570 기반의 WebSphere 7 기반 Java EE 시스템에 비해서 가격은 1/5 수준으로 성능은 111% 더 나은 웹 서비스를 구축할 수 있음을 알 수 있다. 같은 WebSphere 7 기반의 자바 웹 서비스 시스템 구축의 경우에도 Windows Server 2008 R2 / HP BladeSystem C7000 위에서 구동하는 것이 IBM AIX 5.3 / IBM Power 570 위에서 구동하는 것에 비해가격은 1/3 수준으로 성능은 37%  더 나은 결과를 제공할 수 있음을 알 수 있다.

    image

  • Korea Evangelist

    (8) Razor 강좌 - 데이터베이스 처리

    • 1 Comments

    안녕하세요. 김대우 입니다.

    코난이와 함께하는 Razor & WebMatrix 시리즈 강좌리스트

    (1) WebMatrix와 Razor! 이제 시작합니다.

    (2) WebMatrix 설치부터 Hello World까지

    (3) Razor 강좌 - 기본 구문 및 주석 처리

    (4) Razor 강좌 - 코드 블록과 POST 처리

    (5) Razor 강좌 - 재사용 가능한 코드 생성

    (6) Razor 강좌 - 레이아웃 페이지 구조 처리

    (7) Razor 강좌 - 파일처리, 파일 업로드

    (8) Razor 강좌 - 데이터베이스 처리 - (지금 보고 계신 내용)

    (9) Razor 강좌 - Helper 소개(이미지, 비디오)

    (10) Razor 강좌 - 디버깅

    (11) Razor 강좌 - 캐시 처리

    지난 시간에는 “(7) Razor 강좌 - 파일처리, 파일 업로드” 강좌를 진행 했습니다.

    이번 시간에는 바로 이어서,(8) Razor 강좌 - 데이터베이스 처리” 강좌를 진행 하도록 하겠습니다. 

    이번 시간은 데이터베이스 관련 내용이에요. 아마 이 Razor & WebMatrix 관련 내용을 기다리시는 분들 중에 이 데이터베이스 부분이 가장 궁금한 부분이실 것 같네요.

    개인적으로, 가장 먼저 제가 테스트해보고 공부한 부분이 바로 이 데이터베이스 처리 부분인데요.

    기존 웹 개발 언어들의 스파게티 코드를 얼마나 분리해냈고, DB처리가 간결하게 구성되어 있는지 비교하면서 보셔도 좋을 것 같습니다.

    SQL과 같은 데이터베이스를 처음 하시는 분들의 참고자료 :

    음... 부족한 제 강좌 글을 보시는 분들 중에는 데이터베이스가 어떤 것인지 잘 감이 안 잡히는 분도 계실 것 같은데요, 제가 예전에 데이터베이스 기본 개념을 설명한 강좌 몇개를 소개해 드릴 예정이니 처음 데이터베이스를 공부하시는 분들도 참고 하시면 많은 도움 되실 거에요. – 시간이 조금 지난 강좌라도 걱정 마세요. 데이터베이스 기본 개념은 여전 하답니다.  한번이라도 =, MSSQL이나 MySQL이나 오라클 등을 아주 잠시라도 접해보신 분들은 아마 이하 내용을 쉽게 이해 하실것 같아요. 하지만, 전혀 DB에 대해 경험이 없는 분이라면 아래 내용을 참고 하셔도 좋을 것 같습니다.

    데이터베이스를 처음 하시는 분들이 참고하시면 좋을 내용

    데이터베이스란 무엇이고 왜 사용하는가?
    SQL프런티어가 전해 드리는 SQL2008 기본 강좌 – 최근에 진행된 SQLER의 SQL프런티어 강좌 입니다.
    SQL2000강좌 게시판 – 앞 부분의 SELECT, INSERT, UPDATE, DELETE를 보시면서 감을 잡으시는 것도 좋을 것 같습니다.

    웹 개발과 데이터베이스 처리는 뗄래야 뗄 수 없는 그런 찰떡 같은 관계입니다. 이번의 요즘 좀 한다는 분들이 관심좀 가지시고 계신 Razor가 데이터베이스 관련 개발을 공부할 좋은 기회라고 생각하시고 꼭 DB와 SQL 처리에 대한 감을 잡으시는 것도 좋을 것 같아요.
    PHP나 ASP를 사용 하셨고, 예전에 사용해 보신 DB가 MSSQL이나 MySQL 또는 이기종의 DB라서 걱정되세요?
    전혀 걱정 안하셔도 됩니다. 소견으로 감히 말씀 드리면, PHP보다 쉽고 다양한 편의성을 제공하며, ASP.NET의 엔터프라이즈급 성능과 안정성을 제공하는게 Razor 입니다. 당연히, WebMatrix에 포함된 DB도 SQL서버처럼 ANSI 표준을 따르고, 아무 DB나 경험이 있으시다면 쿼리 방식에는 차이가 없기 때문에 어려움 없이 개발을 진행 가능하답니다~ 이 강좌가 끝날 때 즈음이면 저 코난이처럼 “후덜~ Razor DB처리 이거 겁나 쉽네”를 연발 하시게 될거에요~!!
    Razor와 WebMatrix에서의 데이터베이스의 관계?
    예전 강좌에서 소개해 드렸는데요. WebMatrix에서는 간단히 SQL서버보다 더 작고 가벼운 SQL Server Compact Edition 4가 WebMatrix에 포함되어 있습니다.  전문 웹 개발자 분들을 위해 조금 더 상세한 설명을 드리자면, 무료 데이터베이스 엔진으로 .NET 기반의 API를 제공해 WebMatrix를 통한 손쉬운 웹 개발이 가능하며, SQL Server로 쉬운 데이터 마이그레이션이 가능합니다.(WebMatrix에서 자체 마이그레이션 도구를 제공합니다.)
    처음 데이터베이스 관련 개발을 Razor와 WebMatrix로 진행하셔도 아무 걱정하지 마세요. 데이터베이스 쿼리나 테이블 생성 디자인 등도 모두 WebMatrix가 책임집니다~ 개발, DB, 배포 모든 과정을 하나의 심플하고 빠른 개발 도구, WebMatrix에서 진행 하실 수 있어요~

    우워~ 세상 점점 좋아 지는구나~ 생유 생유~
    WebMatrix의 데이터베이스 기능 참고자료 :
    [동영상 강좌] (2) WebMatrix 5분 리뷰~ – 동영상으로 Database는 물론 WebMatrix에 대한 전반적인 기능을 보실 수 있습니다.
    WebMatrix에서 데이터베이스 작업, 테이블 작업 뿐만 아니라 쿼리도 가능하다고 계속 말씀 드렸습니다. 실제로 이번 강좌를 진행할때 다 해보도록 할께요.

    WebMatrix에서 데이터베이스 생성
    db1

    (1) 왼쪽 아래의 Databases를 클릭해 데이터베이스 영역으로 넘어 갑니다.
    (2) 중간의 Add a Database to your site를 클릭해 데이터베이스를 생성하세요.
    (3) 위의 웹사이트 하위에 WebSite1.sdf라는 DB가 잘 만들어 진게 보이시면 완료 되신 겁니다. ^_^
    이제 Database 이름을 변경해 보도록 할께요.(아쉽지만, 현재 버전-Beta1 - WebMatrix는 Databases 섹션에서 DB이름 변경이 불가해요.)
    db2
    Database 이름 변경
    (1) Files를 선택하고
    (2) 해당 데이터베이스를 선택, 마우스 우버튼 후 “Rename” 이름을 변경합니다.
    (3) 이름을 저처럼 CohoWinery.sdf 로 잡아 주세요.(이후 예제에서 이 이름으로 사용합니다.)
    자, 데이터베이스도 만들었으니, 이제 실제 데이터를 넣고 테스트를 하기 위한 테이블 생성, 샘플 데이터 삽입 작업을 할 차례입니다.

    WebMatrix에서 테이블 생성

    WebMatrix에서 테이블을 생성하기 위해 아래 절차를 진행 하세요~
    db3
    (1) 왼쪽 하단의 Databases를 클릭하고,
    (2) 왼쪽 상단에서 조금 전 만든 해당 DB를 선택 하신 후에
    (3) 중간 위의 “New Query”를 클릭해 새로운 SQL 쿼리를 수행합니다.
    참고로, WebMatrix는 쿼리가 아닌 UI가 있는 화면으로 테이블 생성, 관계 설정 등도 가능합니다. 위의 화면 New Table을 누르고 UI로 제작도 가능하니 지금은 참고만 해 두세요~
    테이블 생성 쿼리 수행

    CREATE TABLE Customers (    
            CustomerID int NOT NULL
    ,       FirstName  nvarchar(128) NOT NULL
    ,       LastName   nvarchar(128) NOT NULL
    ,       Address    nvarchar(256) NOT NULL
    ,       Phone      nvarchar(15)  NOT NULL
    ,       Email      nvarchar(128) NOT NULL
    ,       PRIMARY KEY (CustomerID)
    );

    위의 테이블 생성 구문을 수행하시면 테이블이 생성됩니다. 실행을 위해서는, WebMatrix의 지금 열려 있는 쿼리 창에 붙여 넣으시고, F5를 누르시거나, 상단 중간 정도에 위치한 “Execute”를 클릭 하셔도 됩니다.

    Command(s) completed successfully 라고 나오실 거에요. 그럼 성공~
    확인을 위해 왼쪽 맨 위의 우리 DB인 “CohoWinery.sdf” 펼치고 나오는 Tables에서 마우스 우측 버튼 - “Refresh”를 실행하면, Customers라는 테이블이 보이실 겁니다. 또는, 왼쪽 메뉴에서 Customers 테이블을 더블클릭하거나 우클릭 후 "Data"를 클릭 하셔도 데이터 조회가 가능합니다. - 참 쉽죠? ^_^;;;
    바로 이어서, 샘플 데이터를 삽입해 보도록 할게요.

    샘플 데이터 삽입 – INSERT 처리
    쿼리창의 CREATE TABLE 구문을 지우고 아래 INSERT 구문을 “한 줄씩” 복사해 실행합니다.

    주의 – 아래 쿼리들을 한 Insert 구문씩 복사해 넣으세요.

    INSERT INTO Customers VALUES (1, 'Jim', 'Corbin', '3425 23 Ave SE New York 87905', '555-0100', 'JC@cpalnd.com');
    INSERT INTO Customers VALUES (2, 'Eva', 'Coretta', '800 100 St Portland 34567', '555-0101', 'EC@cpalnd.com');
    INSERT INTO Customers VALUES (3, 'Sara', 'Davis', '1123 Main St Orcas 3444', '555-0200', 'SW@contoso.com');
    데이터 조회 구문
    SELECT * FROM Customers;

    (한 줄씩 복사해 개별 실행하려니 갑갑 하시죠? 현재 WebMatrix가 MSSQL 관리 도구나 개발도구와 달리, 몇몇 부분이 조금 불편하실 수 있습니다. 정식 버전에서는 이런 불편함이 대부분 수정될 예정이라고 하니 참고 하시길 바랍니다.)

    자~ 이렇게 해서 간단히 데이터베이스 작업을 수행 했습니다. 저희가 해본 작업은
    (1) 데이터베이스 생성
    (2) 테이블 생성
    (3) 쿼리 도구를 이용해 데이터 삽입, 데이터 조회
    작업을 진행해 보았습니다. 그럼 이제 본편~ Razor에서 데이터베이스를 처리하는 부분을 진행해 보도록 하지요~
    Razor에서 데이터 조회 – SELECT 처리

    @{    
        var db = Database.OpenFile("CohoWinery.sdf");    
        //var db = Database.OpenFile("~/App_Data/CohoWinery.sdf");    
        //var db = Database.OpenFile(@"Data Source=C:\Users\사용자명\Documents\My Web Sites\WebSite1\App_Data\CohoWinery.sdf");    
        var selectQueryString = "SELECT * FROM Customers ORDER BY CustomerID";
    }

    <!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>고객리스트 </title>
        </head>
        <body>   
            <h2>         Coho Winery 고객리스트     </h2>         
            <table border="1">        
                <thead>            
                    <tr>                
                    <th>이름</th>                
                    <th>성</th>                
                    <th>주소</th>               
                    <th>전화번호</th>                
                    <th>Email</th>            
                    </tr>        
                </thead>        
                <tbody>            
                    @foreach (var row in db.Query(selectQueryString)) {                
                    <tr>                    
                        <td>@row.FirstName</td>                   
                        <td>@row.LastName</td>                   
                        <td>@row.Address</td>                      
                        <td>@row.Phone</td>                   
                        <td> <a href="mailto:@row.Email" style="text-decoration: underline;">@row.Email</a></td>                
                    </tr>            
                }        
                </tbody>    
            </table>
        </body>
    </html>

    “DB” 폴더를 웹사이트 루트에 만들고 “01_select.cshtml” 파일을 만들고 복사해 실행합니다.
    Razor는 기존의 많은 웹 개발 방식과 달리, 더 쉽고 더 빠른 웹개발을 그 목표로 하고 있습니다.

    개인적으로 저 코난이가 Razor에 푸욱~ 빠지게 된 이유는 바로 이 데이터베이스 처리 방식. 스파게티 코드 없이 깔끔하고, DB처리를 우리 웹 개발자에게는 눈물겹게 감사하도록, 딱 한큐로 끝내고 있습니다. DB처리 방식이나 Helper를 이용해 그 동안 있었던 웹 개발의 어려움과 복잡함을 덜어내고, 개발자에게 더 쉽고 빠른 개발이 가능하게 돕는 녀석이지요.
    지~ 코드를 봐 볼까요~
    DB연결 방식으로 Database.OpenFile을 이용합니다. (주석들을 참고하시면 여러 DB연결 방식 참조가 가능합니다.)

    var db = Database.OpenFile("CohoWinery.sdf");   

    저는 이렇게 연결 했습니다. 이어서, SQL 쿼리 구문을 만들고, 아래 Foreach 구문에서 db.Query로 한큐에 실행합니다.
    @foreach (var row in db.Query(selectQueryString))
    사실 위의 두 줄로 DB연결이 끝난 겁니다. 잊지 마시고, 이 두 과정을 꼭 잘 눈에 익혀 두시면 나중에도 DB관련 처리를 하실 때 많은 도움 되실 겁니다.

    개발 경험이 있으신 분들을 위해… WebMatrix에 기본 포함된 SQL CE가 아니라, 타 DBMS를 이용하실 경우(MSSQL서버와 같은)에는 기존 방식과 마찬가지로, Connection String을 이용해 처리가 가능합니다.(현재 WebMatrix Beta1에서 Connection String은 Web.config에 저장됩니다. Connection String 구성 등은 나중에 요청이 있으시거나 하면 상세하게 풀어 볼게요.) 
    그럼 이어서 Razor로 데이터 삽입 처리를 보도록 하겠습니다.

    Razor에서 데이터 삽입 – INSERT 처리

    @{    
        var db = Database.OpenFile("CohoWinery.sdf");      
        var CustomerID = Request.Form["CustomerID"];    
        var FirstName = Request.Form["FirstName"];    
        var LastName = Request.Form["LastName"];    
        var Address = Request.Form["Address"];    
        var Phone = Request.Form["Phone"];    
        var Email = Request.Form["Email"];             
        if (IsPost) {        
            // 사용자의 입력 값 저장 & 입력값을 검사
            CustomerID = Request["CustomerID"];        
            if (CustomerID.IsEmpty()) {            
                Validation.AddFieldError("CustomerID", "고객 ID 번호를 입력하세요.");      
            }                  
            // 사용자의 입력 값 저장 & 입력값을 검사   
            FirstName = Request["FirstName"];        
            if (FirstName.IsEmpty()) {            
                Validation.AddFieldError("FirstName", "이름을 입력하세요.");        
            }                 
            // 사용자의 입력 값 저장 & 입력값을 검사     
            LastName = Request["LastName"];        
            if (LastName.IsEmpty()) {            
                Validation.AddFieldError("LastName", "성을 입력 하세요.");        
            }                 
            // 사용자의 입력 값 저장 & 입력값을 검사
            Address = Request["Address"];        
            if (Address.IsEmpty()) {           
                Validation.AddFieldError("Address", "주소를 입력하세요.");        
            }                
            // 사용자의 입력 값 저장 & 입력값을 검사     
            Phone = Request["Phone"];        
            if (Phone.IsEmpty()) {            
                Validation.AddFieldError("Phone", "전화번호를 입력하세요.");        
            }                 
            // 사용자의 입력 값 저장 & 입력값을 검사    
            Email = Request["Email"];        
            if (Email.IsEmpty()) {            
                Validation.AddFieldError("Email", "이메일 주소를 입력하세요.");        
            }        
            if(Validation.Success) {           
                // 입력받은 값을 파라미터화 후 insert 구문에 전달
                var insertQueryString =             
                "INSERT INTO Customers (CustomerID, FirstName, LastName, Address, Phone, Email) VALUES (@0, @1, @2, @3, @4, @5)";                         
                // 쿼리 실행
                db.Execute(insertQueryString, CustomerID, FirstName, LastName, Address, Phone, Email);                         
                // 삽입 후 데이터 조회 페이지로 이동
                Response.Redirect("01_select.cshtml");        
            }    
        }     
    }

    <!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>고객 정보 추가</title>    
            <style type="text/css">       
            label {                
                float: left;                
                width: 8em;                
                text-align: right;               
                margin-right: 0.5em;
                }                       
            fieldset {                    
            qpadding: 1em;                    
            border: 1px solid;                    
            width: 50em;}       
            legend {                
            padding: 0.2em 0.5em;                
            border: 1px solid;                
            font-weight: bold;
            }    
            </style>
            </head>
        <body>   
            <h2>새로운 고객 정보 추가</h2>         
            <div style="font-weight:bold; color:red">        
                @Html.ValidationSummary("입력값 오류가 있습니다.")    
            </div>         
            <form method="post" action="">             
                <fieldset>            
                    <legend>고객 추가</legend>            
                    <div>                
                        <label>고객ID번호:</label>                
                        <input name="CustomerID" type="text" size="50"  value="@CustomerID" />                            
                    </div>
                    <div>                
                        <label>이름:</label>                
                        <input name="FirstName" type="text" size="50" value="@FirstName" />            
                    </div>            
                    <div>                
                        <label>성:</label>                
                        <input name="LastName" type="text" size="50" value="@LastName" />            
                    </div>            
                    <div>                
                        <label>주소:</label>                
                        <input name="Address" type="text" size="50" value="@Address" />            
                    </div>            
                    <div>                
                        <label>전화번호:</label>                
                        <input name="Phone" type="text" size="50" value="@Phone" />                       
                    </div>            
                    <div>                
                        <label>Email:</label>                
                        <input name="Email" type="text" size="50" value="@Email" />            
                    </div>            
                    <div>                
                        <label>&nbsp;</label>                
                        <input type="submit" value="Insert" class="submit" />            
                    </div>        
                </fieldset>    
            </form>
        </body>
    </html>

    02_Insert.cshtml 파일로 저장합니다.
    참고하실 내용이 두 개 정도가 있는데요. INSERT 구문을 수행하실 경우에는 이렇게 파라미터화 된 값을 전달합니다.
    // 입력 받은 값을 파라미터화 후 insert 구문에 전달
    var insertQueryString =              
    "INSERT INTO Customers (CustomerID, FirstName, LastName, Address, Phone, Email) VALUES (@0, @1, @2, @3, @4, @5)";                         

    또한, 이번에 새롭게 등장한 또 하나의 Razor Helper인 “Html.ValidationSummary” 녀석인데요.

    이 Html.ValidationSummary을 이용하면, 입력 값을 손쉽게 검사해 입력 오류 여부를 사용자에게 쉽게 알릴 수 있습니다.

    간단히 빈 값을 입력하게 되면 해당 체크 영역에서 값을 처리해 @Html.ValidationSummary 영역에 표시하게 됩니다.
    db4
    요렇게 자동으로 도와 줍니다.  개발자의 번거로운 작업인 입력값 체크 처리를 간략화 시킬 수 있는 깔꼼한 녀석이에요. 저희들의 경우 이런 validation을 쓰는 개발자 분들과 UI를 위해 직접 만들어 사용하시는 경우도 꽤 있는 것 같습니다.

    다음은 Update를 알아 보도록 할게요. 이제 데이터베이스 처리 좀 감이 잡히시죠? Update도 전혀~ 어렵지 않습니다.
    Razor로 데이터베이스 수정 – Update 처리
    데이터를 수정하려면, 먼저 조회를 하고, 수정 루틴을 넣은 후에 수정 화면이 있어야겠지요. 조회는 위의 SELECT와 유사하고, Update 값 화면은 INSERT 화면과 유사합니다.

    @{       
        var db = Database.OpenFile("CohoWinery.sdf");        
        var selectQueryString = "SELECT * FROM Customers ORDER BY CustomerID";
    }

    <!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>고객 정보 수정</title>
        </head>
        <body>   
            <h2>          고객 정보 수정     </h2>
            <form method="post" action="" name="form">        
                <table border="1">            
                    <thead>                
                        <tr>                    
                        <th/>                    
                        <th>이름</th>                    
                        <th>성</th>                    
                        <th>주소</th>                    
                        <th>전화번호</th>                    
                        <th>Email</th>                
                        </tr>            
                    </thead>            
                    <tbody>                
                    @foreach (var row in db.Query(selectQueryString)) {                    
                        <tr>                        
    <td><a href="@Href("~/db/04_update_02.cshtml", row.CustomerID)">수정</a></td>
                            <td>@row.FirstName</td>                        
                            <td>@row.LastName</td>                        
                            <td>@row.Address</td>                        
                            <td>@row.Phone</td>                        
                            <td><a href="mailto:@row.Email"     style="text-decoration: underline;">@row.Email</a></td>                    
                        </tr>                
                    }            
                    </tbody>        
                </table>    
            </form>
        </body>
    </html>

    03_update_01.cshtml 파일로 저장해 두겠습니다. 이어서 UPDATE에 필요한 후속 파일을 만들어 주세요. 위의 “04_update_02.cshtml” 페이지로 CustomerID를 넘겨주고 있어요. 참고 하시길 바랍니다.

    @{    
        var db = Database.OpenFile("CohoWinery.sdf");        
        var selectQueryString = "SELECT * FROM Customers WHERE CustomerID=@0";        
        //  업데이트를 위해 고객ID번호로 정보를 읽어 옵니다.
        //  고객ID는 앞의 update 페이지에서 넘겨 받았습니다. 
        var CustomerID  = UrlData[0];         
        if (CustomerID.IsEmpty()) {        
            Response.Redirect("03_update_01.cshtml");    
        }             
        // 업데이트를 위해 고객 정보를 조회
        var row = db.QuerySingle(selectQueryString, CustomerID);    
        // Update 입력 상자에 넣기 위해 변수에 값을 저장
        var FirstName   = row.FirstName;     
        var LastName    = row.LastName;    
        var Address     = row.Address;    
        var Phone       = row.Phone;    
        var Email       = row.Email;

       if (IsPost) {        
        CustomerID = Request["CustomerID"];        
        if (CustomerID == null) {              
            Validation.AddFieldError("CustomerID", "고객ID 번호를 입력하세요.");        
        }                  
        FirstName = Request["FirstName"];        
        if (String.IsNullOrEmpty(FirstName)) {            
            Validation.AddFieldError("FirstName", "이름을 입력하세요.");        
        }                 
        LastName = Request["LastName"];        
        if (String.IsNullOrEmpty(LastName)) {            
            Validation.AddFieldError("LastName", "성을 입력하세요.");        
        }                 
        Address = Request["Address"];        
        if (String.IsNullOrEmpty(Address)) {            
            Validation.AddFieldError("Address", "주소를 입력하세요.");        
        }                
        Phone = Request["Phone"];        
        if (String.IsNullOrEmpty(Phone)) {            
            Validation.AddFieldError("Phone", "전화번호를 입력하세요.");        
        }                 
        Email = Request["Email"];        
        if (String.IsNullOrEmpty(Email)) {            
            Validation.AddFieldError("Email", "이메일 주소를 입력하세요.");        
        }        
        if(Validation.Success) {           
            // 업데이트 처리를 위해 파라미터화 작업    
            var updateQueryString = "UPDATE Customers SET FirstName=@0, LastName=@1, Address=@2, Phone=@3, Email=@4 WHERE CustomerID=@5" ;             
            // UPDATE 쿼리 구문 실행
            db.Execute(updateQueryString, FirstName, LastName, Address,               
                Phone, Email, CustomerID);             

            // 업데이트를 위한 리스트 페이지로 이동
            Response.Redirect("~/db/03_update_01.cshtml");        
        }    
    }
    }
    <!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>고객 정보 수정</title>         
            <style type="text/css">       
            label {                
                float: left;                
                width: 8em;                
                text-align: right;                
                margin-right: 0.5em;
            }       
            fieldset {                    
                padding: 1em;                    
                border: 1px solid;                    
                width: 50em;
            }       
            legend {                
                padding: 0.2em 0.5em;                
                border: 1px solid;                
                font-weight: bold;
            }    
            </style>
        </head> 
        <body>   
            <h2>       고객 정보 수정 페이지     </h2>         
            <div style="font-weight:bold; color:red">        
                @Html.ValidationSummary("입력값에 오류가 있습니다 :")    
            </div>         
            <form method="post" action="">              
                <fieldset>            
                    <legend>고객정보 수정</legend>            
                    <div>              
                        <label>고객ID 번호:</label>              
                        <input name="CustomerID" type="text" size="50" value="@CustomerID" />             
                    </div>            
                    <div>                
                        <label>이름:</label>                
                        <input name="FirstName" type="text" size="50" value="@FirstName" />             
                    </div>            
                    <div>                
                        <label>성:</label>                
                        <input name="LastName" type="text" size="50" value="@LastName" />                             
                    </div>            
                    <div>                
                        <label>주소:</label>                
                        <input name="Address" type="text" size="50" value="@Address" />            
                    </div>            
                    <div>
                        <label>전화번호:</label>                
                        <input name="Phone" type="text" size="50" value="@Phone" />              
                    </div>            
                    <div>                
                        <label>Email:</label>                
                        <input name="Email" type="text" size="50" value="@Email" />            
                    </div>            
                    <div>                
                        <label>&nbsp;</label>                
                        <input type="submit" value="Update" class="submit" />            
                    </div>        
                </fieldset>    
            </form>
        </body>
    </html>

    04_update_02.cshtml 파일로 저장합니다. 실행을 위해 앞에서 만들었던 03_update_01.cshtml 업데이트 리스트 페이지를 실행하세요.
    위의 업데이트 화면은 Insert 처리와 마찬가지로 validation 후에 파라미터화 된 값을 처리하게 되면서 마무리 됩니다. 마지막 삭제처리 - DELETE를 알아 보도록 할께요~
    Razor로 데이터베이스 값 삭제 – DELETE 처리
    어느덧 마지막 내용이네요. 삭제 처리를 위한 DELETE는 더 쉽습니다. 데이터 조회 리스트 화면에서 해당 값을 선택해 “삭제”를 클릭하면 처리가 완료되는 처리 입니다.

    @{    
        var db = Database.OpenFile("CohoWinery.sdf");        
        var selectQueryString = "SELECT * FROM Customers ORDER BY CustomerID";     
        if (IsPost) {                
            var deleteQueryString = "DELETE FROM Customers WHERE CustomerID=@0";        
            db.Execute(deleteQueryString, Request["rowID"]);    

        }
    }

    <!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>고객 정보 삭제</title>     
            <script type="text/javascript">                 
                function deleteRow(rowID) {          
                    var answer = confirm("정말 삭제 하시겠습니까?")          
                    if (answer==true)            
                    {                
                        document.form.rowID.value = rowID;                
                        document.form.submit();            
                    }        
                }        
            </script> 
        </head>
        <body>   
            <h2 class="SubHeader">         고객 정보 삭제     </h2>     
            <form method="post" action="" name="form">        
                <input type="hidden" name="rowID" value="" />        
                <table border="1">            
                    <thead>                
                        <tr>                    
                            <th/>                    
                            <th>이름</th>                    
                            <th>성</th>                    
                            <th>주소</th>                    
                            <th>전화번호</th>                    
                            <th>Email</th>                
                        </tr>            
                    </thead>            
                    <tbody>
                        @foreach (var row in db.Query(selectQueryString)) {                    
                        <tr>                    
                            <td><a href="Javascript:deleteRow('@row.CustomerID')"> 삭제</a></td>                        
                            <td>@row.FirstName</td>                        
                            <td>@row.LastName</td>                        
                            <td>@row.Address</td>                        
                            <td>@row.Phone</td>                        
                            <td><a href="mailto:@row.Email" style="text-decoration:underline;">@row.Email</a></td>                    
                        </tr>                
                        }            
                    </tbody>        
                </table>    
            </form>
        </body>
    </html>

    05_del.cshtml 파일로 저장하고 실행하세요.

    마지막으로, 데이터를 손쉽게 웹에서 표시해주는 WebGrid Helper를 소개해 드리려고 합니다. 기본 제공되는 Grid로 그리드로 사용하기 편리하실 거에요. 자동 페이징이나, 쉬운 디자인 등등... 이번에는 맛보기 정도만 하고, 나중에 기회되면 이 WebGrid도 잘 풀어 보도록 할께요. ^_^

    WebGrid Helper를 이용한 손쉬운 데이터 표시

    @{
        var db = Database.OpenFile("CohoWinery.sdf");
        var selectQueryString = "SELECT * FROM Customers";
        var data = db.Query(selectQueryString);
        var grid = new WebGrid(data, defaultSort: "FirstName", rowsPerPage: 5);
    }

    <!DOCTYPE html>
    <html>
        <head>
            <title> WebGrid에 데이터를 표시 합니다. </title>
            <style type="text/css">
                h1 {font-size: 14px;}
                .grid { margin: 4px; border-collapse: collapse; width: 600px; }
                .head { background-color: #E8E8E8; font-weight: bold; color: #FFF; }
                .grid th, .grid td { border: 1px solid #C0C0C0; padding: 5px; }
                .alt { background-color: #E8E8E8; color: #000; }
                .FirstName { width: 200px; }
            </style>
        </head>
        <body>
        <h1>웹그리드로 데이터를 표시</h1>
            @grid.GetHtml(
                tableStyle: "grid",
                headerStyle: "head",
                alternatingRowStyle: "alt",
                columns: grid.Columns(
                    grid.Column("FirstName", "이름", style: "product"),
                    grid.Column("Address", "주소", format:@<i>@item.Address</i>),
                    grid.Column("Phone", "전화번호", format:@<text>@item.Phone</text>)
                )
            )

    </html>

    WebGrid로 저장하고 실행해 보세요. 그럼 이런 형태로 보이실 겁니다. ^_^

    db5

    짧은 코드로 그리드가 아주 깔끔하게 나오죠? 이런 방법도 Razor와 WebMatrix는 기본제공하고 있으니 참고 하시길 바랍니다.

    Razor와 WebMatrix를 이용한 데이터베이스 개발의 장점은?
    데이터 처리에 대한 예를 말씀 드렸어요. 어쩌면 Razor가 기존의 웹개발 방식과 가장 차별화를 제공하는 부분이 바로 이 데이터베이스 처리 부분일 겁니다.

    Razor & WebMatrix의 데이터베이스 개발 작업의 장점은
    (1) 자체 내장된 SQL DB를 이용하고
    (2) 무료 SQL서버인 SQL Express나 SQL서버 상위 버전으로 100% 마이그레이션을 WebMatrix 내부에서 지원하며
    (3) 간결한 데이터베이스 접근 처리 방식
    (4) 개발과 쿼리, 데이터베이스 작업을 모두 하나의 도구인 WebMatrix에서 제공
    하는 것은 Razor와 데이터베이스 개발에 대한 큰 매력이 아닐까 생각합니다.
    데이터베이스에 경험이 없으신 분들은 내용이 조금 어려웠을지도 모르겠습니다. 곧, 이 강좌에 대해서도 동영상 강좌를 준비하고 있으니 많은 도움 되시길 바랍니다.

    그럼 다음 강좌인 (9) Razor 강좌 - Helper 소개(이미지, 비디오) 에서 뵙도록 하겠습니다. ^_^

    참고자료 :

    (1) WebMatrix와 Razor! 이제 시작합니다.
    (2) WebMatrix 설치부터 Hello World까지
    (3) Razor 강좌 - 기본 구문 및 주석 처리
    (4) Razor 강좌 - 코드 블록과 POST 처리
    (5) Razor 강좌 - 재사용 가능한 코드 생성
    (6) Razor 강좌 - 레이아웃 페이지 구조 처리
    (7) Razor 강좌 - 파일처리, 파일 업로드
    [동영상 강좌] (1) WebMatrix 첫 실행 & Hello World까지 달려요~
    [동영상 강좌] (2) WebMatrix 5분 리뷰~
    [동영상 강좌] (3) Razor 강좌 - 기본 구문 및 주석 처리
    [동영상 강좌] (4) Razor 강좌 - 코드 블록과 POST 처리

  • Korea Evangelist

    (9) Razor 강좌 - Helper 소개(이미지, 비디오)

    • 0 Comments

    안녕하세요. 김대우 입니다.

    코난이와 함께하는 Razor & WebMatrix 시리즈 강좌리스트

    (1) WebMatrix와 Razor! 이제 시작합니다.

    (2) WebMatrix 설치부터 Hello World까지

    (3) Razor 강좌 - 기본 구문 및 주석 처리

    (4) Razor 강좌 - 코드 블록과 POST 처리

    (5) Razor 강좌 - 재사용 가능한 코드 생성

    (6) Razor 강좌 - 레이아웃 페이지 구조 처리

    (7) Razor 강좌 - 파일처리, 파일 업로드

    (8) Razor 강좌 - 데이터베이스 처리

    (9) Razor 강좌 - Helper 소개(이미지, 비디오) - (지금 보고 계신 내용)

    (10) Razor 강좌 - 디버깅

    (11) Razor 강좌 - 캐시 처리

    지난 시간에는 “(8) Razor 강좌 - 데이터베이스 처리” 강좌를 진행 했습니다.

    이번 시간에는 바로 이어서,(9) Razor 강좌 - Helper 소개(이미지, 비디오)” 강좌를 진행 하도록 하겠습니다. 
    Razor와 WebMatrix에서 Helper는 무엇인가요?
    넵. 지난 강좌에서도 몇 번 소개해 드렸습니다만, Helper는 웹에서 사용되는 여러 기능들을 손쉽게 이용 가능하도록 구조화시킨 모듈입니다. 즉, 다양하고, 복잡한 웹의 기능을 개발자가 쉽게 이용 가능하도록 돕는 부품이지요.
    그렇다면, Helper는 어떤 종류가 있나요?
    Razor는 이러한 Helper를 기본적으로 포함하고 있으며, 사용자가 직접 만들어 사용할 수 있도록 역시 돕고 있습니다. 기본적으로 현재 WebMatrix Beta1에 포함된 Helper들의 리스트를 보여 드리자면 아래와 같아요.
    WebMatrix Helpers 종류 - 영문
    위의 링크를 통해 대략 이런 종류의 다양한 Helper들이 Beta1에서 기본 제공되고 있구나~ 정도만 보셔도 좋을 것 같습니다. Beta1에서 이 정도로 많고 앞으로 공개 예정인 녀석들 등도 많이 있으니 정식 버전에서는 엄청나겠지요? ^_^ 기대됩니다.

    이번 강좌에서는 이러한 Helper들 중에서 종종 사용 하시게 될 Image처리, Video 처리, 두개 정도의 기본 Helper를 상세히 살펴봐서 어떻게 Helper를 이용하는지, 또한 Helper가 얼마나 우리의 웹 개발 닭질을 줄여 줄지 기대해보는 시간을 가지도록 하겠습니다.
    참조 : 사용자가 직접 Helper를 만들고 사용하는 방법 – 영문

    Image 처리 Helper – WebImage
    소개해 드릴 녀석은 WebImage Helper 입니다. 이 녀석으로 어떤걸 할 수 있냐고요?
    - 웹 서버 경로의 이미지 로드
    - 사용자에 의해 업로드 된 이미지 로드
    - 이미지 파일을 웹 서버 특정 경로에 저장
    - 이미지에 워터마크(텍스트 또는 이미지) 추가 표시
    - 이미지 Flip이나 회전
    - 이미지 크기조절(Resize를 이용한 섬네일 표시)
    와 같은 웹 개발에서 종종 사용하게 될 기능을 제공합니다.
    그럼 요 기능들 중에서 섬네일로 사용하기 위한 크기조절(Resize) 처리와 텍스트 워터마크 기능을 살펴 보도록 하겠습니다.

    아! 제 강좌는 수많은, 모든 Helper들의 기능이나 사용 예를 보여드리는 게 아니에요. 제가 보여드릴 소개 샘플들을 봐 보시면서 Helper란 이런 것이고, 이런 목적으로 Helper를 사용하고, 이렇게 Helper 이용 가능하구나 부분에 초점을 맞추셔야, 앞으로도 쏟아져 나오게 될 수많은 Helper 들 중에 원하시는 Helper를 직접 찾아 사용 가능하실 겁니다.  막상 이용 방법 설명이라고 해 봐야 코드 한 줄 정도에 파라미터 값들 넣는 게 다네요.(쿨럭) 워낙 쉬워서 사용 방법 설명이라고 하기도 좀 거시기 합니다. ^_^;;; 그럼 시작해 볼게요~
    WebImage – 섬네일 이미지 표시(Resize)
    예제 실행을 위해 WebMatrix로 “WebImage” 폴더를 만들고, 그 하위에 “images”, 또 그 하위에 “tumbs” 폴더를 미리 생성합니다.

    @{
    WebImage photo = null;
        var newFileName = "";
        var imagePath = "";
        var imageThumbPath = "";
        if(IsPost){
    photo = WebImage.GetImageFromRequest();
            if(photo != null){
                newFileName = Guid.NewGuid().ToString() + "_" +
                    Path.GetFileName(photo.FileName);
                imagePath = @"images\" + newFileName;
    photo.Save(@"~\WebImage\" + imagePath);
                imageThumbPath = @"images\thumbs\" + newFileName;
                photo.Resize(
                    width: 60,
                    height: 60,
                    preserveAspectRatio: true,
                    preventEnlarge: true
                );
    photo.Save(@"~\WebImage\" + imageThumbPath);
            }
        }
    }
    <!DOCTYPE html>
    <html>
        <head>
            <title>이미지 리사이징</title>
        </head>
        <body>
            <h1>섬네일 이미지 자동 추출</h1>
    <form action="" method="post" enctype="multipart/form-data">
                <fieldset>
                    <legend> 섬네일 이미지 생성 </legend>
                    <label for="Image">이미지</label>
                    <input type="file" name="Image" />
                    <br/>
                    <input type="submit" value="Submit" />
                </fieldset>
            </form>

            @if(imagePath != ""){
                <div class="result">
                <img src="@imageThumbPath" alt="Thumbnail image" />
                <a href="@Html.AttributeEncode(imagePath" target="_Self">
                    실제이미지 보기
                </a>
                </div>
            }
        </body>
    </html>

    WebImage 폴더에 ResizeImage.cshtml 파일로 저장하시고 실행하세요.
    아무 사진이나 업로드를 하시면 됩니다.코드를 통해 처리되는 내용을 설명 드리면,
    - 이미지를 form으로 업로드 받고
    - WebImage 개체인 photo에 GetImageFromRequest로 이미지가 로드 됩니다.
    - Save를 통해 업로드 된 이미지를 저장하고,
    - 이어서 WebImage.Resize로 이미지 크기를 줄여
    - Thumbnail 이미지를 한번 더 Save하게 되지요. 
    WebImage Helper - 이미지에 워터마크(Watermark) 표시
    다음으로 워터마크(Watermark) 처리를 확인해 보도록 할게요. 이미지 소스에 대한 보호, 불법적인 이미지 도용 방지 등의 목적으로 보통 이 워터마크 방식을 이용하게 됩니다. 예제를 보면서 설명 드리도록 하겠습니다.

    @{
        var imagePath= "";
    WebImage photo = new WebImage("images/photo.jpg");
        if(photo != null){
            imagePath = "images/photo.jpg";
    photo.AddTextWatermark("Photo by http://www.sqler.com - 워터마크", fontColor:"Yellow", fontFamily:"Arial");
            photo.Save(imagePath);
        }
    }
    <!DOCTYPE html>
    <html>
    <head>
        <title> 워터마크 이미지 처리 </title>
            <meta http-equiv="content-type" content="text/html;charset=utf-8" />
        </head>
        <body>
            <h1>이미지에 워터마크를 텍스트를 추가합니다.</h1>
                @if(imagePath != ""){
                    <div class="result">
                        <img src="@imagePath" alt="Image" />
                    </div>
                }
        </body>
    </html>

    WebImages 폴더 하위에 watermark.cshtml로 저장하세요. 실행을 위해선 WebImages 폴더 아래 images 폴더에 jpg 파일을 두세요. 저는 위의코드처럼 photo.jpg 파일로 두었습니다. 이 파일에 대해 워터마크를 찍는 처리 입니다.

    코드 진행에 대해선 설명이 많이 필요하지 않으실 듯 합니다. 이렇게 “WebImage.AddTextWatermark”를 호출해 텍스트기반 워터마크 추가가 가능합니다. 또한, “WebImage.AddImagesWatermark”를 이용하면 이미지를 이용해 워터마크 처리가 가능해 집니다. 이렇게, Razor는 즉각적인 이미지 처리가 가능한 Helper등을 통해, 손쉬운 이미지 기반 처리를 가능하게 개발자 편의성을 제공하고 있어요. - 생유생유~

    실행 결과는 아래 처럼 보이실 겁니다.
    image
    아래쪽에 이렇게 아래쪽에 Watermark 텍스트가 찍히실 거에요. (오늘도 자식 자랑 성공~ 아자~ 텨텨텨~)

    이렇게 간단히 이미지 Resize, 워터마크 처리에 대해서 알아 보았습니다.

    다음으로는 웹에서 실행 가능한 Video 처리에 대해서 소개해 드리도록 하겠습니다.
    WebMatrix & Razor에서 Video helper로 Flash, Silverlight, WMV 비디오나 어플리케이션 실행
    느끼시는 것처럼, Razor에서는 Adboe Flash 비디오와 WMV 비디오 파일(스트리밍도) 플레이도 가능하며 Microsoft Silverlight파일인 xap 파일도 처리가 가능합니다. 이번 소개에서는 간단히 Silverlight를 실행해 보도록 하겠습니다..

    <!DOCTYPE html>
    <html>
        <head>
            <title>Silverlight Video 실행</title>
        </head>
        <body>
        @Video.Silverlight(
            path: "
    http://www.sqler.com/lab/sl_install/publish/ClientBin/SLTest01.xap",
            width: "300",
            height: "200",
            bgColor: "Black",
            autoUpgrade: true
        )

        <p> Silverlight 실행  </p>
        </body>
    </html>

    웹사이트 상위에 Video 폴더를 만들고, 여기에 Silverlight.cshtml 파일로 저장 했습니다.

    정확히 Flash나 Silverlight, 미디어 플레이어와 같은 처리에 사용되는 조금은 복잡한 HTML인 <OBJECT> 태그를 자동으로 생성해주는 처리라고 보시면 됩니다. 위와 같이 Video를 실행하면 실버라이트를 HTML에서 수행토록 하는 아래 코드가 생성되지요.
    <object width="300" height="200" type="application/x-silverlight-2" data="data:application/x-silverlight-2," >

    <param name="source" value="http://www.sqler.com/lab/sl_install/publish/ClientBin/SLTest01.xap" />

    <param name="background" value="Black" />

    <a href="http://go.microsoft.com/fwlink/?LinkID=149156" style="text-decoration:none">

    <img src="http://go.microsoft.com/fwlink?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>

    </a>

    </object>

    예상대로(?)시죠? 복잡한 HTML 코드 등을 자동으로 캡슐화해 생성해 줍니다. -  개발자는 여러 종속성이나 복잡성 등을 고민할 필요 없이 개발 작업간 코드를 표준화, 캡슐화 키셔서 손쉽게 개발에 적용은 가능할 것 같아요.

    video helper의 경우 Adobe Flash는 swf 파일, Silverlight은 xap 파일만 처리가 가능합니다. 아울러, 꼭 Video 플레이어일 필요는 없습니다. swf파일이나 xap 파일이면(어플리케이션도) 됩니다. WMV는 자동으로 미디어 플레이어가 붙게 됩니다.
    자~ 이렇게 해서 Helper들에 대해서 알아 보았습니다. Helper에 대해서 정리해 보자면,
    - Helper는 웹에서 사용되는 여러 기능들을 손쉽게 이용 가능하도록 구조화시킨 모듈입니다.
    - 다양하고, 복잡한 웹의 기능을 개발자가 쉽게 이용 가능하도록 돕는 부품이지요. 
    이번 강좌를 통해 Image 처리 등을 보시고 아마 그렇게 느끼셨을 거에요. Razor님은 분명 웹 개발자의 편의성을 위해 신경 좀 써 주신 듯 하네요. ^_^ 앞으로 WebMatrix와 Razor가 발전하면서 계속 다양하고 훌륭한 Helper들이 많이 나오게 될 예정이라고 합니다. 이번 강좌 내용으로 다양한 Helper를 사용하는 방법이 도움 되셨길 바랍니다.
    그럼 다음 강좌인 (10) Razor 강좌 – 디버깅 에서 뵙도록 하겠습니다. 감사합니다. ^_^ 

    참고자료 :

    (1) WebMatrix와 Razor! 이제 시작합니다.
    (2) WebMatrix 설치부터 Hello World까지
    (3) Razor 강좌 - 기본 구문 및 주석 처리
    (4) Razor 강좌 - 코드 블록과 POST 처리
    (5) Razor 강좌 - 재사용 가능한 코드 생성
    (6) Razor 강좌 - 레이아웃 페이지 구조 처리
    (7) Razor 강좌 - 파일처리, 파일 업로드
    (8) Razor 강좌 - 데이터베이스 처리
    [동영상 강좌] (1) WebMatrix 첫 실행 & Hello World까지 달려요~
    [동영상 강좌] (2) WebMatrix 5분 리뷰~
    [동영상 강좌] (3) Razor 강좌 - 기본 구문 및 주석 처리
    [동영상 강좌] (4) Razor 강좌 - 코드 블록과 POST 처리
    사용자가 직접 Helper를 만들고 사용하는 방법

    WebMatrix Helpers 종류

  • Korea Evangelist

    (10) Razor 강좌 – 디버깅

    • 0 Comments

    안녕하세요. 김대우 입니다.

    코난이와 함께하는 Razor & WebMatrix 시리즈 강좌리스트

    (1) WebMatrix와 Razor! 이제 시작합니다.

    (2) WebMatrix 설치부터 Hello World까지

    (3) Razor 강좌 - 기본 구문 및 주석 처리

    (4) Razor 강좌 - 코드 블록과 POST 처리

    (5) Razor 강좌 - 재사용 가능한 코드 생성

    (6) Razor 강좌 - 레이아웃 페이지 구조 처리

    (7) Razor 강좌 - 파일처리, 파일 업로드

    (8) Razor 강좌 - 데이터베이스 처리

    (9) Razor 강좌 - Helper 소개(이미지, 비디오)

    (10) Razor 강좌 – 디버깅 - (지금 보고 계신 내용)

    (11) Razor 강좌 - 캐시 처리

    지난 시간에는 (9) Razor 강좌 - Helper 소개(이미지, 비디오)” 강좌를 진행 했습니다.

    이번 시간에는 바로 이어서,(10) Razor 강좌 – 디버깅” 강좌를 진행 하도록 하겠습니다. 
    Razor에서 디버깅(Debugging)
    웹 개발 이라는게 워낙 엮인 기술들이 짬뽕된, 짜장같은(?) 영역이 많아 우리 웹 개발자 분들 참 고생 많습니다. 특히, 데이터베이스 연계  부분이나, 사이트 제작에 필수적인 게시판이나 CMS 오픈소스 프로젝트 한두개 정도는 꿰고 있어야 하고, 디자인 영역이나 웹 저작 영역인 CSS까지도 이해가 필요합니다. 그뿐인가요, 최근에는 Open API나 외부 서비스 연동 관련 기술은 물론, Flash나 Silverlight과 같은 RIA쪽도 이해가 필요한 상황이지요.
    이런 짜장들이 짬뽕되어(?) 뒹구는 웹개발 업무에, 다방면에 걸쳐 고민해야할 "디버깅"은 참 만만한 녀석이 아닙니다. 이게 서버의 오류인지, 내려 보낸 Ajax 스크립트의 문제인지, 사용자 브라우저 환경 문제인지, DB문제인지 걸러내는 것만 해도, 어떤 경우에는 고민스러울 경우가 많지요. 하지만 Razor에서는 조금 숨 돌리실만 하실 겁니다. WebMatrix와 Razor는 가장 최근에 발표된 웹 개발 방식인 만큼, 이러한 복잡한 웹 개발에 대한 디버깅을 위해 여러 기능들을 제공합니다.

    저와 같이 Razor 디버깅에 대해서 차근차근 살펴 보시지요~
    Razor와 WebMatrix의 디버깅 방식을 간단히 정리해 보면
    - ServerInfo Helper를 이용해 서버 설정 정보를 일괄 출력, 디버깅에 이용 가능합니다.(PHP 하신 분들이라면, phpinfo와 유사하다고 보시면 됩니다.)
    - 10년 넘는 역사를 가지고 있는 기존 ASP.NET의 디버깅-오류 정보 기능을 그대로 이용합니다.
    - WebMatrix 자체 제공하는 Request 처리 기록을 이용해 오류 재현 등이 손쉽게 가능합니다.
    - 기존 ASP나 PHP의 디버깅 방식인 출력값 처리 디버깅(변수 값 찍어보기) 형태로도 디버깅이 가능합니다.
    - ObjectInfo Helper를 이용해 추적을 원하는 개체 정보를 정확히 얻어 디버깅에 도움을 받을 수 있습니다.
    - WebMatrix에 기본 포함된 SEO 리포트 툴을 이용해 SEO관련 오류를 쉽게 처리 가능합니다.

    ServerInfo로 서버 설정 및 환경 정보 조회
    서버의 설정이나 환경 정보를 일괄 조회해 디버깅이나 설치 등이 잘 이루어졌는지 등을 알아볼 수 있습니다. 바로 디버깅의 시작이지요. cshtml 동작 여부 역시 이 테스트를 통해 확인 가능하지요. 아래처럼 수행 가능합니다.

    <!DOCTYPE html>
    <html>
        <head>
            <title></title>
        </head>
        <body>
            @ServerInfo.GetHtml()
        </body>
    </html>

    웹사이트 루트에 Debug라는 폴더를 만들고 하위에 ServerInfo.cshtml 파일을 만들고 위와 같이 올려 두었습니다.
    이렇게 ServerInfo Helper를 실행하시면, 서버의 설정, 구성 환경 정보를 한눈에 보실 수 있습니다.
    image
    PHP에 경험이 있는 분이라면 바로 감이 오실겁니다. phpinfo() 와 같은 역할을 수행 한다고 보시면 됩니다. 다음으로 ASP.NET 디버깅 인터페이스를 봐 보도록 할께요.
    Razor는 10년동안 서비스된 ASP.NET의 정확하고 상세한 오류 페이지 정보를 이용 합니다.
    Razor는 ASP.NET의 성능과 안정성에 PHP처럼, 아니 제 경험상 PHP 이상으로 더 쉬운 개발 방식을 제공하는 기술입니다. 기본 베이스 엔진을 ASP.NET으로 이용하기 때문에 근간이 되는 디버깅이나 오류 정보를 확인 가능하지요.
    예를 들어, Razor로 데이터베이스 삽입을 하다가 이런 오류가 발생한다면.(���시 오류 입니다. 재현하려 애쓰지 마세요~ ^_^;;;)
    image
    개발하면서 이렇게 잘 뽑혀져 나온 오류 정보만 슥슥~ 읽어도 어디 코드가 어떤 오류를 유발했는지 예측과 확인이 가능합니다. – 상세한 추적을 원할 경우에는 Call Stack 정보를 보셔도 어떤 루틴을 타다가 오류가 발생했는지도 확인 가능하지요.(물론 대부분의 운영-Production 환경에서는 이런 화면은 내부적으로 저장만 시키고, 예쁜 일반 사용자 대상 UI의 화면을 출력 하고 계실 겁니다.)
    잊지마세요, Razor는 어느날 뚝딱 나타난 아이돌같은 녀석이 아니라 ASP.NET이라는 엄청난 스폰서(?)가 뒤에서 후원 해주고 있으며 마이크로소프트가 차세대 웹 개발 기술의 한 축으로 엄청나게 밀고 있는  녀석이라는 것 입니다.
    WebMatrix에서 제공하는 Request 처리 요청 로깅을 이용한 디버깅
    이거는 이 WebMatrix 개발 도구의 기능인데요. 개발하는 과정에서 로깅 기능을 이용해 발생하는 오류를 확인 / 상세한 오류 해결을 위한 가이드도 제공이 가능합니다.
    image
    이렇게, WebMatrix 왼쪽 하단의 Site 섹션을 선택하고, 왼쪽 위의 Requests를 선택하고 상단의 “Capture Request가 선택” 되어 있다면-기본선택 개발간 발생한 요청 처리를 자동 기록해 확인 가능합니다. 만약 오류가 발생한 게 있다면 해당 요청을 클릭하세요. 바로 상세 정보와 오류의 해결 방안에 대한 추천 가이드까지 제공 받을 수 있습니다. 와우~ 

    예전 같으면, 개발 환경일지라도, IIS 웹로그 열어 죽어라 파거나 오류 보고 루틴을 직접 만들어 이용하셨을 겁니다. Razor에서는 그럴 필요 없어요~ 넵~ 나름 훌륭합니다. 개발 환경에서 이용하기에는 아주 딱이실 겁니다.
    출력 값 처리 디버깅(변수 값 찍어보기)
    기존 ASP나 PHP의 디버깅 방식인 출력 값 처리 디버깅을 물론 해 보실 수 있습니다. 예를 들어, 이런 형태입니다.

    @{
        var weekday = DateTime.Now.DayOfWeek;

        if(weekday == "Saturday") {
            <p>"토요일"</p>
        }
        else {
            <p>"아마 일요일"</p>
        }

    }

    debug 폴더 하위에 output.cshtml 파일로 저장하고 실행했습니다. 아마도, if문에서 형변환(Casting) 관련 오류가 발생했을 겁니다.
    이렇게 수정하면서 디버깅을 해 보시죠.

    @{
        var weekday = DateTime.Now.DayOfWeek;
        @weekday;
        /*
        if(weekday == "Saturday") {
            <p>"토요일"</p>
        }
        else {
            <p>"아마 일요일"</p>
        }
        */
    }

    아마도, 이런 식으로 @weekday를 찍어보는 처리를 하실 수 있을 겁니다. 이런 방식을 찍어보는, 출력 디버깅 방법이라고 보통 이야기 합니다. 타입 형변환 관련 이슈이기 때문에 weekday  개체가 어떤 타입이길래? 이런 정보도 궁금 하실 겁니다. 이럴때 “ObjectInfo” Helper를 이용 가능합니다.

    @{
        var weekday = DateTime.Now.DayOfWeek;
        @ObjectInfo.Print(weekday);
        /*
        if(weekday == "Saturday") {
            <p>"토요일"</p>
        }
        else {
            <p>"아마 일요일"</p>
        }
        */
    }

    찍어보니 weekday는 "DayOfWeek" 형이네요. String 과 비교하려 했으니 안됩니다. 따라서, String 타입으로 형변환 하면 되겠지요.

    @{
        var weekday = DateTime.Now.DayOfWeek;
        //@ObjectInfo.Print(weekday);
        if(weekday.ToString() == "Saturday") {
            <p>"토요일"</p>
        }
        else {
            <p>"아마 일요일"</p>
        }
    }

    이렇게 ToString으로 형변환해 처리가 잘 되는 것을 확인 가능합니다. 이런 출력 디버깅 방식도 가능합니다.

    참고로, 웹개발 경험이 많으신 분들만을 위한 부가 설명...

    웹개발 경력자 분이시라면, Break point(중단점)을 걸고 단계별로 따라가면서 오류를 확인하고 싶으실 경우에는 무료로 제공되는 Visual Web Developer Express(무료 웹 개발 버전의 비주얼 스튜디오) 나 Visual Studio 이용해 개발하시면 가능합니다. 이 강좌는 WebMatrix와 Razor 강좌로 Visual Studio 디버깅은 보여드리기 좀 그렇네요. 하지만, 나중에 따로, WebMatrix & Razor 강좌 마무리 후에 준비해 보여 드리도록 할께요. ^_^  - 아 알고 있으시지요? Visual Studio에서도 ASP.NET MVC3 부터 Razor 개발이 가능합니다.
    참고자료 : Introducing ASP.NET MVC 3 (Preview 1) - 영문
    위 내용은 본 강좌와 무관하니, 그냥 그러려니 하고 넘어가셔도 됩니다. Razor를 위해 MVC나 ASP.NET을 모두 이해하실 필요는 없습니다.

    WebMatrix에 기본 포함된 SEO 리포트 툴을 이용해 검색엔진과 맞지 않는 SEO관련 오류를 쉽게 처리 가능합니다.
    예전에 WebMatrix 소개 동영상 강좌에서 언급해 드렸습니다만, 요즘은 웹사이트에 대한 사용자 유입에 검색엔진 만한 게 없지요. 이 검색엔진에 의해 잘 검색되도록 SEO 관련 처리도 많이 하고 계실 겁니다. 이 SEO 최적화를 검사 하는 게 만만치 않고 고가의 유료 서비스 등을 이용해야 할 수 있는데요. IIS7과 WebMatrix에서는 이런 SEO 최적화 기능을 제공하고 있습니다.
    참고자료 :
    [동영상 강좌] (2) WebMatrix 5분 리뷰~
    IIS7의 SEO Toolkit 소개

    image
    왼쪽 아래 Reports를 선택하시고, 웹사이트를 선택하시면 이렇게 자동으로 리포트를 만들고, SEO 최적화를 위한 상세한 가이드라인까지 알려 줍니다. - 훌륭하죠~ 이러한 SEO 관련 작업도 WebMatrix와 내장해서 제공하고 있습니다.
    자~ 이렇게 해서 WebMatrix와 Razor가 제공하는 디버깅 방안과 접근 절차에 대해서 소개해 드렸습니다. 기존 웹 개발 경험이 있는 분들은 쉽게 감이 오실 것 같아요~ 개인적인 소견으로 Razor는 어떤 면에서는 PHP의 디버깅 장점과 ASP.NET의 디버깅 장점들을 모두 가지고 있다고 느껴지네요. ^_^
    그럼 다음 강좌는 마지막 WebMatrix & Razor 하는 강좌 (11) Razor 강좌 - 캐시 처리 에서 뵙도록 하겠습니다. 감사합니다. ^_^ 

    참고자료 :

    (1) WebMatrix와 Razor! 이제 시작합니다.
    (2) WebMatrix 설치부터 Hello World까지
    (3) Razor 강좌 - 기본 구문 및 주석 처리
    (4) Razor 강좌 - 코드 블록과 POST 처리
    (5) Razor 강좌 - 재사용 가능한 코드 생성
    (6) Razor 강좌 - 레이아웃 페이지 구조 처리
    (7) Razor 강좌 - 파일처리, 파일 업로드
    (8) Razor 강좌 - 데이터베이스 처리
    (9) Razor 강좌 - Helper 소개(이미지, 비디오)
    [동영상 강좌] (1) WebMatrix 첫 실행 & Hello World까지 달려요~
    [동영상 강좌] (2) WebMatrix 5분 리뷰~
    [동영상 강좌] (3) Razor 강좌 - 기본 구문 및 주석 처리
    [동영상 강좌] (4) Razor 강좌 - 코드 블록과 POST 처리
    IIS7의 SEO Toolkit 소개

    Introducing ASP.NET MVC 3 (Preview 1)

Page 1 of 4 (20 items) 1234