asp.net2007. 11. 22. 00:00

현재 우리 회사 솔루션의 ASP.NET 웹 애플리케이션에는, 빈번하게 사용되는 개인 정보(혹은 설정값)을 담는 용도로 쿠키를 사용하고 있다. 쿠키는 사실 참 편리하다. 서버의 리소스를 점유하지도 않고, 만료기간만 지정해두면 서버가 다운되건 말건 계속 유지도 되고.. 서버사이드, 클라이언트 사이드 어디서나 쉽게 접속할 수 있기도 하고.

하지만, 솔루션에 대한 보안 감사 끝에.. 쿠키를 제거하기로 결정이 되었다. 사실 보안 측면에서 보자면 쿠키라는 것은 꽤 위험하다. 문제는 이 쿠키가 클라이언트에 저장되는 Plain Text파일인데다가, 모든 Web Server에 대한 Request/Response시에 전송이 된다는 것이다. 즉, 클라이언트에서 이 파일을 열어 볼 수도 있고, 네트워크 패킷을 스니핑해서 내용을 볼 수도 있다. 거기다가 위/변조하기도 당연히 쉽다. 또 일부 국가 - 어딘지는 잘 모른다 - 에서는 법적으로 쿠키를 금지하기도 하고, Internet Explorer등의 브라우저에서도 쿠키를 허용하지 않는 옵션을 장착하고 있기 때문에 어떤 사용자들의 경우 쿠키를 아예 사용할 수 없을 가능성도 있는 것이다.

서두가 장황했는데, 암튼 쿠키를 모두 제거하기로 하고 우리가 선택한 대안은 ASP.NET 세션이었다. 사실 빈번하게 사용되는 사용자 개인의 설정값등을 담아둘 수 있는 가장 이상적인 공간이기도 하고, 쿠키와 매우 유사하게 서버사이드에서 사용할 수도 있기 때문이었다. 하지만 이 ASP.NET 세션에는 한 가지 문제가 있다. 그 문제는 바로, 이 ASP.NET 세션이 기본적으로 쿠키를 사용한다는 것이다.

ASP.NET 세션을 사용하면 생성되는 쿠키는 이렇게 생겼다.

ASP.NET_SessionId=d1ucyg30qyjw1f554szadoqy;

즉, ASP.NET 세션에서 각 사용자를 구분하는 것 자체가 이 쿠키를 사용하는 것이다.

그런데, ASP.NET에는 Cookie-less Session이라고 해서, 쿠키를 사용하지 않고 세션을 사용할 수 있게 해주는 모드 또한 있다. 이것은 별도의 코딩이 필요한 것은 아니고 단지 Web.Config의 SessionState 부분에 Cookieless를 True로 바꿔주기만 하면 된다.

<sessionState
            mode="InProc"
            stateConnectionString="tcpip=127.0.0.1:42424"
            sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes"
           
cookieless="true"
            timeout="20"
    />

이 Cookie-less Session에 대한 자세한 내용은 Dino Esposito씨의 다음 Article을 보면 알 수 있다.

위 아티클을 보면 알 수 있겠지만, 이 Cookieless Session은 세션을 쓰면서도 Cookie를 완전히 쓰지 않아도 된다는 점에서 나의 고민을 완벽하게 해주는 것이었다. 그러나 나는 몇 가지 문제를 발견했다..-_-;;

첫째로 이 Cookieless Session을 쓸 경우 모든 URL이 조금씩 바뀌게 된다는 것이다. 즉, 요청한 URL이 이렇다면..

http://localhost/CookielessSessionWebSample/Webform1.aspx

실제로 페이지가 열린 다음에는 이렇게 바뀌게 된다.

http://localhost/CookielessSessionWebSample/(mkwgif552tavi2vtxhgq1a45)/Webform1.aspx

위의 URL에 가운데 부분에 이상하게 끼어든 (mkwgif552tavi2vtxhgq1a45)이 바로 쿠키의 SessionID의 역할을 하는 것이다. 즉 쿠키를 쓰는 대신에 URL에 세션ID를 넣어서 사용한다고 생각하면 되겠다.

두번째로 바로 위 사실 때문에 몇가지 제약 사항이 발생한다. Server.Transfer와 Response.Redirect 등을 사용할 때, Root로부터 시작하는 URL 즉 이런 형태 - /RootDir/Somepage.aspx - 를 사용하지 못하며, Full URL - http://ServerName/RootDir/Somepage.aspx - 를 또한 사용하지 못한다. 이 사실은 EggHeadCafe라는 사이트의 한 게시물에서 알게 되었다.

첫번째 문제가 Accept된다면, 사실 대부분의 경우 큰 문제는 없을 것이다. 두번째처럼 만약 코딩을 했다는 것은, 사실 코딩 상에 문제가 있는 거라고 봐야 하니까. 그런데 내 경우는 우리 회사의 솔루션에 저런 것이 없다고 장담하기가 힘들었다는 것이다. 그래서, 우리 솔루션의 경우는 쿠키의 세션ID는 허용하는 방향으로 가기로 했다.

하지만, 쿠키를 완전히 사용할 수 없는 경우가 발생한다면, Cookie-less Session은 매우 좋은 선택이 될 것이다. 그리고 이 Cookie-less Session을 사용한다면 위에서 언급한 코딩상의 주의 사항은 반드시 지켜야 할 것이다.

Posted by kkongchi
asp.net2007. 2. 15. 11:26
MSDN Magazine에 IIS 7.0에 대한 글이 실렸다.

http://msdn.microsoft.com/msdnmag/issues/07/03/IIS7/

IIS 7.0의 개선된 점들을 소개하고 있는데, 아래의 네 가지 항목이다.

Modular Web server functionality (웹 서버 기능의 모듈화 - 설치/제거가 간편해 진 듯)
Simplified deployment and configuration (배포, 구성이 간단해졌다)
Extensibility and ASP.NET integration (확장성과 ASP.NET 통합)
Improved security, performance, and compatibility (보안, 성능, 호환성의 개선)

개발자로서 가장 관심이 가는 부분은 아무래도 ASP.NET과 유기적인 통합을 이루었다는 점일 것이다. 위 글에 실린 그림을 인용해 보자면..

사용자 삽입 이미지

ISAPI Native 모듈을 통하지 않고, 바로 IIS와 ASP.NET이 연결이 된다는 것을 볼 수 있다. 위 글은 다음과 같이 그 효과를 설명하고 있다.

When running in Integrated mode in IIS 7.0, ASP.NET modules run in the unified request processing pipeline side-by-side with native C++ IIS modules. This means that existing ASP.NET services like Output Caching, URL Rewriting, and any others provided by your custom ASP.NET modules can now apply to any content type. Better runtime integration also enables ASP.NET modules to access previously unavailable server functionality, removing the need to write native IIS extensibility in most cases.
IIS 7.0이 통합 모드로 운영될 때, ASP.NET모듈은 Native C++ IIS모듈과 나란히 통합적인 리퀘스트 처리 파이프라인에서 동작하게 된다. Output 캐싱, URL 리라이팅과 같으 기존의 ASP.NET 서비스나 혹은 다른 당신이 만드는 별도의 서비스들이 이제는 모든 컨텐트 타입에 적용되게 된다. 개선된 런타임 통합은 ASP.NET이 이전에는 불가능했던 여러 가지 기능을 할 수 있도록 해주며, 결국 기존에 Native IIS 확장 모듈을 만들어야 했던 경우들은 이제 없게 될 것이다.


예전에 모 프로젝트(ASP.NET으로 진행했었던)에서 나는 C++로 ISAPI 필터를 하나 만들었던 경험이 있다. 이 ISAPI 필터의 역할은 특정 Request Header를 검사해서, 그것이 있다면 ID, PW입력이 없이도 Windows 인증을 통과시켜주는 것이었다. 이 것을 ASP.NET의 HttpModule 혹은 HttpHandler로 작성할 수 없을까 조사를 했었는데, 그 때는 그것이 불가능했었다. 왜냐하면 Windows 인증은 ASP.NET까지 오기전 ISAPI 모듈에서 일어나는 일이었기 때문에 ASP.NET으로서는 전혀 방법이 없었기 때문이다. 그런데, 이 그림을 보아하니 이런 경우도 이제는 가능해지는 것이 아닐까 생각된다. ASP.NET이 이제는 IIS와 Full Integration이 된다면, 아마 성능 상에도 많은 이점이 있을 것 같다. 결국은 단계가 하나 줄어드는 셈이 되는 것이니까. 물론 직접 사용해봐야 알 수 있겠지만, 현재로서는 기대가 많이 된다.

Posted by kkongchi
asp.net2006. 11. 19. 01:19


특정 폴더에 있는 이미지를 웹 화면에 출력해야 하는데, 그 폴더를 웹 가상 디렉토리로 만들기가 힘든 상황이 있을 수가 있다. 아무래도 웹 가상 디렉토리로 노출되는 것은 보안에 문제가 있을 수 있다는 것을 의미하고, 그 폴더가 이미지 외에도 많은 내부 자료들이 들어있는 공용 스토리지라면 가상 디렉토리로 만드는 것은 좋지 않은 선택이다.

이럴 때, 이미지 파일을 읽어서 웹 화면에 출력해줄 수 있는 ASPX 웹 페이지 코드를 소개한다. 아래 코드는 서버의 파일명을 파라미터로 받아서, 그 파일을 이미지 형태로 웹 화면에 출력하는 코드이다.

일단, ASPX 페이지에는 아무런 HTML 코드가 없어야 한다. 아래와 같이 ASPX 페이지 지시자만 놔두고 모두 삭제하도록 한다.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

비하인드 코드는 다음과 같다. 아래 코드는 Page_Load 이벤트 핸들러에 두면 된다.

System.Byte[] arrBytes = null; //파일을 바이트로 읽기 위한 변수를 선언
string fileName = null; //파일명을 받을 변수 선언

try
{
  Response.ContentType = "image/jpeg" //Content Type을 반드시 image/jpeg 혹은 image/gif 등의 image 유형으로 지정해야 한다.
  fileName = Request["FileName"];

  if (!String.IsNullOrEmpty(fileName)) //파일명이 전달되지 않았을 때의 분기
  {
   arrBytes = new System.Byte[1000000]; //바이트를 넉넉하게 지정하자. 이 크기가 파일보다 작다면 에러가 발생한다.
   System.IO.FileStream fs = null; //파일을 읽기 위해 파일스트림 선언
   string filePath = fileName;
   string defaultFilePath = "c:\\camels.jpg" //파일이 존재하지 않을 때 사용할 이미지
   if (System.IO.File.Exists(filePath))
   {
     fs = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);
   }
   else
   {
     fs = new System.IO.FileStream(defaultFilePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);
   }

   fs.Read(arrBytes, 0, 1000000);
   fs.Flush();
   fs.Close(); //파일스트림객체는 사용한 후에 반드시 해제해야 한다.

   Response.Clear();
   Response.OutputStream.Write(arrBytes, 0, arrBytes.Length); //웹 Response에 파일을 직접 쓴다. 이로써 이미지가 출력된다.
  }
  else
  {
   throw new Exception("파일명이 지정되지 않았습니다");
  }
}
catch (Exception ex)
{
  Response.Write(ex.ToString());
}


이 ASPX 페이지는 다음과 같이 사용하면 된다.

<img src="default.aspx?FileName=C;\\Camels.jpg"/>


사실, 이렇게 이미지를 웹 페이지로 출력하는 방법은 그렇게 좋은 방법은 아니다. 사실은 HttpHandler를 사용하는 것이 더 좋다. HttpHandler를 사용하는 방법은 Dino EspositoImage Generation Service for ASP.NET 1.1를 참조하기 바란다.

그리고, 위 샘플 코드는 파일 경로가 GET 파라미터로 완전히 보이기 때문에 그냥 사용하면 안된다. 적어도 파일 명 앞의 경로는 Config 파일에 두는 방법을 사용하길 바란다.

Posted by kkongchi
asp.net2006. 10. 1. 17:15

Team Foundation Server에서 제공하는 Team build기능에서, 솔루션을 지정하게 되면 그 솔루션에 포함된 모든 프로젝트가 빌드되게 된다. 그러나 솔루션에 웹 사이트가 포함되어 있을 경우에 문제가 약간 있는데.. 이건 빌드가 되지 않는다.. 결과물에 다른 DLL이나 EXE는 있을 지 몰라도, 웹 사이트는 없을 것이다...-_-;;

이건 VS2003, 닷넷 1.X에서 우리가 쓰던 Web Application과 VS2005의 Web Site가 전혀 다른 개념이기 때문이다. Web Site는 사실 굳이 컴파일할 필요가 없다. Runtime에 자동으로 컴파일이 되기 때문이다. 그러므로 사실 팀 빌드에서 포함시킬 필요도 없긴 하겠지만.. Web Application 과 비교해봤을 때 아무래도 다음과 같은 단점이 있게 된다.

소스가 그대로 서버의 디렉토리에 노출된다.
미리 컴파일된 것보다는 Runtime시에 컴파일되는 것이 느릴 것이다. (물론 처음에 한 번만 하겠지만.., 그리고 이 때문에 소스만 바꿔도 컴파일할 필요없이 운영된다는 것은 아주 좋은 점이긴 하다)
실수로 컴파일 에러가 나는 소스가 올라갈 수도 있다.

Aspnet_compiler.exe와 aspnet_merge.exe를 사용해서 기존의  웹 애플리케이션과 똑같은 형태로 컴파일할 수 있긴 하다. 하지만 과정이 매우 복잡하고, 결정적으로 귀찮다는...-_-;;;; 이 과정을 자동화시킬 수 있는 툴이 있다. 바로 Visual Studio 2005 Web Deployment Project이다. 이건 VS2005에 Add-In으로 간단하게 설치할 수 있고, 아래 주소에서 다운로드 받을 수 있다.

http://msdn2.microsoft.com/en-us/asp.net/aa336619.aspx

사용방법은 간단하다. 아래 그림처럼 웹 사이트에 오른쪽 마우스를 누르면, 컨텍스트 메뉴가 뜨는데 거기서 Add Web Deployment Project를 누르면 된다.

팝업 화면이 뜨는데, 이름과 경로를 입력하면 된다. 입력한 이름은 그 Deployment Project의 이름이 되기도 하지만, 실제 출력되는 웹 DLL의 이름이 되기도 한다.

Debug(혹은 Release - 빌드 옵션에 따라서) 폴더에 가면, ASP.NET 1.X시절과 같은 형태로 출력물이 나온 것을 볼 수 있다. Web Page의 aspx와 bin 폴더 아래의 DLL들.. 이제 이 결과물을 IIS에서 만든 가상 디렉토리에 복사하기만 하면 된다. 아래 그림은 결과물 폴더와 bin 폴더인데, bin 폴더에 보면, 좀 전에 만든 Web Deployment Project의 이름과 똑같이 DLL이 만들어진 것을 볼 수 있다.

Posted by kkongchi
asp.net2006. 9. 18. 22:38

ASP.NET 2.0에는 Master Page라는것이 새로 생겼다.  마스터 페이지의 개념을 MSDN에 나온 그대로 옮기면 다음과 같다.

"ASP.NET 마스터 페이지를 사용하면 응용 프로그램의 페이지에 대해 일관된 레이아웃을 만들 수 있습니다. 단일 마스터 페이지는 응용 프로그램의 모든 페이지 또는 페이지 그룹에 대해 원하는 모양과 느낌 및 표준 동작을 정의합니다. 그런 다음 표시할 콘텐츠가 포함된 개별 콘텐츠 페이지를 만들 수 있습니다. 사용자가 요청한 콘텐츠 페이지는 마스터 페이지와 병합되어 마스터 페이지의 레이아웃과 콘텐츠 페이지의 콘텐츠가 조합된 결과가 만들어집니다."

그런데, Master Page - Content Page가구성이되면, 마치 ASCX처럼 내부로 중첩된 컨트롤들의 Client ID가 아주복잡해지는 것을 소스보기에서 볼 수가있다. 이렇게..

<input name="ctl00$ContentPlaceHolder1$TextBox1" type="text" id="ctl00_ContentPlaceHolder1_TextBox1" />


그래서, 자바스크립트를 사용해서 제어하고자 할 때 반드시 서버사이드에서 그 컨트롤의 ClientID를 구해서 해야한다.다음은 Master Page에서 자바스크립트로 Content Page의 컨트롤을 제어하는 샘플이다.

마스터 페이지에는 버튼 컨트롤과 텍스트 박스 컨트롤을 하나씩 올려 두었다.

ASPX 소스는 아래처럼 된다.

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>
<!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 runat="server">
  <title>제목 없음</title>
</head>
<body> <form id="form1" runat="server">   
       <input id="Button1" type="button" value="button" onclick="return Button1_onclick()" />&nbsp;
       <input id="Hidden1" type="hidden" runat="server" /><br />
       <br />
       <asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
           </asp:contentplaceholder>   
  </form>
</body></html>


컨텐트 페이지에는 텍스트박스 컨트롤을 하나 올렸다.


ASPX 소스는 아래처럼 구성된다.
<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
  <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</asp:Content>


목표는 마스터페이지에서 버튼을 눌렀을 때, 컨텐트 페이지의 텍스트 박스에 "aaa"라는 값이 들어가게 하는 것이고, 이를 자바스크립트를 사용해서 수행하는 것이다. 그 코드는 다음과 같다.

protected void Page_Load(object sender, EventArgs e)
{
     //contentPlaceHolder1은 Master페이지에 기본적으로 들어있는 PlaceHolder 컨트롤의 이름이다.
     //이 내부에 각 컨텐트 페이지의 컨트롤들이 들어있다.
     //즉 ContentPlaceHolder1.Controls 를 뒤지면 나온다는 얘기다.
     //그래서 루프를 돌면서 찾도록 한다.
     foreach (Control con in this.ContentPlaceHolder1.Controls)
     {
         //원하는 것을 찾기 위해서는 종류나 ID 같은 것을 알면 된다.
         if (con.GetType().Name == "TextBox" con.ID == "TextBox1")
         {
             //ClientID를 알 수 있다. 히든에다 넣는다.
             this.Hidden1.Value = con.ClientID;
         }
     }
     //자바스크립트를 생성한다.
     //렌더링된 자바 스크립트는 아래와 같은 모양이다.
     //        function Button1_onclick() {
     //        var conID = document.all.item("ctl00_Hidden1").value;
     //        eval("document.all.item('" + conID + "').value = 'aaa'");
     //        }
     //즉, 히든에 넣은 textbox 컨트롤의 ID를 구한 후,
     //eval문을 사용해서 컨트롤에 'aaa'라는 값을 넣는 스크립트를 실행하는 것이다.
     string scriptCode = "function Button1_onclick() {" + System.Environment.NewLine;
     scriptCode += " var conID = document.all.item(\"" + this.Hidden1.ClientID + "\").value;" + System.Environment.NewLine;
     scriptCode += "eval(\"document.all.item('\" + conID + \"').value = 'aaa'\");" + System.Environment.NewLine;
     scriptCode += "}";

     //페이지에 클라이언트 스크립트를 등록한다.
     this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Click", scriptCode, true);
}


주석에도 설명이 되어 있지만, 포인트는 마스터 페이지에 있는 PlaceHolder 컨트롤 내부에서 그 컨텐트 페이지에 있는 컨트롤을 찾는 것이다. 일단 찾은 후에는 그 ClientID 속성을 구할수 있으므로, 이 샘플보다 복잡한 스크립트도 얼마든지 수행시킬 수가 있다.
Posted by kkongchi
asp.net2006. 6. 21. 00:34

ASP.NET 2.0에서는 웹파트를 추가할 수 있는 카탈로그 컨트롤 등의 장치를 제공한다. 하지만, 이 카탈로그 컨트롤을 쓰지 않고, 별도의 팝업 페이지 등을 사용해서 웹 파트를 선택하고 페이지에 추가하고 싶을 때에는 웹파트를 프로그래밍 방식으로 추가해야 한다. 이럴 때에는 WebPartManager 클래스에 있는 AddWebPart 메서드를 다음과 같이 사용하면 된다.

첫 번째 파라미터에는 추가할 웹파트 클래스의 인스턴스를,

두 번째 파라미터는 그 웹파트가 들어갈 웹파트존을 지정한다.

세 번째 파라미터는 웹파트존에서의 위치를 숫자 인덱스로 지정하면 된다.

//웹파트 인스턴스 초기화
MyWebPart oWebPart = new MyWebPart();
//웹파트존에 웹파트 추가
this.WebPartManager1.AddWebPart(oWebPart, this.WebPartZone1, 1);
 
Posted by kkongchi
asp.net2006. 5. 10. 16:53

1. 웹 파트 개요


     a. ASP.NET 웹 파트는 최종 사용자가 웹 페이지의 내용, 모양 및 동작을 브라우저에서 직접 수정할 수 있는 웹 사이트를 만드는 데 사용할 통합 컨트롤 집합이다.


     b. 수정 내용은 사이트의 모든 사용자 또는 개별 사용자에게 적용될 수 있다. 사용자가 페이지와 컨트롤을 수정하는 경우 이후의 여러 브라우저 세션 간에 사용자의 개인 기본 설정을 유지할 수 있도록 설정을 저장할 수 있다. 이 기능을 개인 설정이라고 한다.


     c. 이러한 웹 파트 기능을 통해 개발자는 개발자나 관리자의 개입 없이도 최종 사용자가 웹 응용 프로그램을 동적으로 개인 설정할 수 있도록 권한을 부여할 수 있다.

2. Web Part 에서 사용자가 조절할 수 있는 것들


     a. 페이지 내용 개인 설정 - 사용자는 새 웹 파트 컨트롤을 페이지에 추가하거나 제거하고, 숨기거나 최소화할 수 있다.


     b. 페이지 레이아웃 개인 설정 - 사용자는 웹 파트 컨트롤을 페이지의 다른 영역으로 끌어 오거나 페이지의 모양, 속성 및 동작을 변경할 수 있다.


     c. 컨트롤 내보내기 및 가져오기 - 사용자는 다른 페이지 또는 사이트에 사용할 웹 파트 컨트롤 설정을 가져오거나 내보낼 수 있다.


     d. 연결 만들기 - 예를 들면 차트 컨트롤에 주식 기호 컨트롤의 데이터 그래프가 표시되도록 컨트롤을 서로 연결할 수 있다.


     e. 사이트 수준 설정 관리 및 개인 설정 - 권한이 부여된 사용자는 사이트 수준의 설정을 구성하고, 사이트 또는 페이지에 액세스할 수 있는 사용자를 결정할 수 있으며 컨트롤에 대한 역할 기반 액세스를 설정할 수 있다.

3. 웹 파트 구성



4. 웹 파트 호스팅 페이지


     a. 페이지 레이아웃용 영역 사용
             i. 웹 파트 용어로 영역, 즉 페이지에서 웹 파트 컨트롤을 포함하는 영역이라고 한다.
            ii. 페이지에는 영역이 하나 이상 있을 수 있으며 세로 또는 가로 방향으로 페이지를 레이아웃할 수 있는 각 영역에는 하나 이상의 웹 파트 컨트롤이 포함될 수 있다.


     b. 영역 내의 웹 파트 컨트롤
             i. 각 컨트롤은 컨트롤에 링크, 단추 또는 클릭할 수 있는 이미지로 나타낼 수 있는 UI, 즉 사용자가 수행할 수 있는 작업을 포함한다.
            ii. 각 컨트롤에 대한 메뉴에는 해당 컨트롤에 대한 세부 정보를 변경하는 옵션과 컨트롤을 이동하거나 삭제하고 도움말을 가져오는 등 일반적인 작업을 수행하는 기타 옵션이 포함되어 있다.


     c. 광범위한 개인 설정을 활성화하는 링크
               i. 사용자는 페이지의 내용, 색 및 레이아웃을 변경할 수 있다. 예를 들어 Add Content 링크를 클릭하여 사용자가 선택적으로 페이지에 추가할 수 있는 컨트롤 카탈로그를 표시할 수 있다

Posted by kkongchi
asp.net2006. 4. 29. 15:26

1. 테마
a. 테마는 페이지와 컨트롤의 모양을 정의하고 웹 응용 프로그램의 페이지, 전체 웹 응용 프로그램 또는 서버의 모든 웹 응용 프로그램 간에 일관된 모양을 적용할 수 있는 속성 설정의 모음이다.
b. 테마는 스킨, CSS 스타일시트, 이미지 및 기타 리소스와 같은 일련의 요소로 구성된다. 테마에는 최소한 스킨이 포함된다. 테마는 웹 사이트 또는 웹 서버의 특수 디렉터리에 정의된다.
c. 테마는 웹 사이트에서 \App_Themes 폴더의 하위 폴더에 만들어진다. 각 테마는 \App_Themes 폴더의 개별 하위 폴더이다.

2. 스킨
a. 스킨 파일은 파일 이름 확장명이 .skin이며 Button, Label, TextBox 또는 Calendar 컨트롤과 같은 개별 컨트롤의 속성 설정을 포함한다.
b. 컨트롤 스킨 설정은 컨트롤 태그 자체와 비슷하지만 테마의 일부로 설정되는 속성만 포함한다.
c. 테마 폴더에 .skin 파일을 만든다. .skin 파일에는 여러 컨트롤 형식에 대한 하나 이상의 컨트롤 스킨이 포함될 수 있다. 각 컨트롤에 대해 별도로 스킨 파일을 정의하거나 테마에 있는 모든 스킨을 단일 파일로 정의할 수 있다.
d. 스킨 파일 예

<asp:button runat="server" BackColor="lightblue" ForeColor="black" />

e. 기본 스킨
i. 테마를 페이지에 적용할 때 같은 형식의 모든 컨트롤에 기본 스킨이 자동으로 적용된다. SkinID 특성이 없는 컨트롤 스킨은 기본 스킨이다.
f. 명명된 스킨
i. SkinID 속성이 설정된 컨트롤 스킨이다.
ii. 명명된 스킨은 형식별로 컨트롤에 자동으로 적용되지 않는다. 그 대신 컨트롤의 SkinID 속성을 설정하여 명명된 스킨을 컨트롤에 명시적으로 적용할 수 있다.
iii. 명명된 스킨을 만들면 응용 프로그램에서 동일 컨트롤의 각 인스턴스에 대해 서로 다른 스킨을 설정할 수 있다.


3. 테마 설정
a. 단일 웹 응용 프로그램에 대한 테마를 정의할 수도 있고 웹 서버의 모든 응용 프로그램에서 사용할 수 있는 전역 테마를 정의할 수도 있다.
i. @Page 지시문의 Theme 또는 StyleSheetTheme 특성을 사용하여 개별 페이지에 배치할 수도 있다.
<%@ Page Theme="ThemeName" %>

ii. 응용 프로그램 구성 파일의 <pages> 요소를 설정하여 응용 프로그램의 모든 페이지에 적용할 수도 있다. Machine.config 파일에서 <pages> 요소를 정의하면 서버의 웹 응용 프로그램에 있는 모든 페이지에 테마가 적용된다.

<pages theme="ThemeName" />

iii. 프로그래밍 방식 적용 (반드시 PreInit이벤트에 해야 한다)

Protected void Page_PreInit(object sender, EventArgs e)
{
switch (Request.QueryString["theme"])
{
  case "Blue":
   Page.Theme = "BlueTheme";
   break;
  case "Pink":
   Page.Theme = "PinkTheme";
   break;
}
}


4. 테마 적용의 예
a. 한 페이지에 Pink테마, Blue테마를 적용시켜서 버튼의 색깔을 바꿔 본 예제






Posted by kkongchi
asp.net2006. 3. 18. 23:29

1. AJAX (Asynchronous Javascript And Xmlhttp)


Ajax(Asynchronous JavaScript and XML) 혹은 AJAX는 대화식 웹 어플리케이션의 제작을 위해 아래와 같은 조합을 이용하는 웹 개발 기법이다:
표현 정보를 위한 HTML (또는 XHTML) 과 CSS
동적인 화면 출력 및 표시 정보와의 상호작용을 위한 DOM, 자바스크립트
웹 서버와 비동기적으로 데이터를 교환하고 조작하기 위한 XML, XSLT, XMLHttpRequest
(Ajax 어플리케이션은 XML/XSLT 대신 미리 정의된 HTML 이나 일반 텍스트, JSON, JSON-RPC를 이용할 수 있다).
DHTML과 같이 Ajax는 자체가 하나의 특정한 기술을 말하는 것이 아니며, 함께 사용하는 기술의 묶음을 지칭하는 용어이다.
Ajax 어플리케이션은 실행을 위한 플랫폼으로 위에서 열거한 기술들을 지원하는 웹 브라우저를 이용한다. 이것을 지원하는 브라우저로는 모질라 파이어폭스, 인터넷 익스플로러, 오페라, 사파리 등이 있다.


2. Ajax 어플리케이션은 기존의 웹 어플리케이션과 무엇이 다른가


기존의 웹 어플리케이션


폼을 채우고 제출(submit)을 하면, 웹 서버로 요청을 보내도록 한다. 웹 서버는 전송된 내용에 따라서 새로운 웹 페이지를 작성하여 결과물을 되돌려준다.
이때 최초에 폼을 가지고 있던 사이트와 사용자가 이 폼을 채워 결과물로서 되돌려 받은 두 페이지 사이에 중복되는 HTML코드로 인해 많은 대역폭을 낭비하게 된다.
네이티브 어플리케이션과 비교할 때 복잡한 대화형 사용자 인터페이스를 작성하기가 어렵다.


Ajax 어플리케이션


필요한 데이터만을 주도록 웹 서버에 요청할 수 있다.
보통 SOAP나 XML 기반의 웹 서비스 언어를 사용하며, 웹 서버의 응답을 처리하기 위해 클라이언트 쪽에서 자바스크립트를 쓴다.
그 결과로 웹 브라우저와 웹 서버 사이의 교환되는 데이터량이 줄어들기 때문에 어플리케이션의 응답성이 좋아진다. 요청을 주는 수많은 컴퓨터에서 이 같은 일이 일어나기 때문에, 전체적인 웹 서버 처리량도 줄어들게 된다


3. AJAX.NET

http://ajax.schwarz-interactive.de/csharpsample/default.aspx
이 공통 라이브러리는 ASP.NET에서 작성한 메소드를 그 이름 그대로 자바스크립트에서 호출할 수 있게 해준다.(동기/비동기)


* 웹폼 메서드

[Ajax.AjaxMethod]
public string Test(string s)
{
string strReturn = s + " World";
return strReturn;
}

* 자바스크립트에서 바로 웹폼 메서드를 호출

function btn1_onclick()
{
  var response = WebForm1.Test(“Hello ");
  alert(response.value);
}


4. AJAX.NET 아키텍처


기존에는 XmlHttp를 통해서 웹 페이지 혹은 웹 서비스를 호출하는 함수를 만들어야 했는데, AJAX.NET은 이 라이브러리를 참조하고 AjaxMethod 어트리뷰트를 추가하면 그런 함수를 자동으로 렌더링시켜주게 된다.

5. AJAX.NET 사용법


Step1. ajax.dll 참조
Step2. 다음 내용을 Web.Config에 추가


<configuration>
<system.web>
  <httpHandlers>
  <add verb="POST,GET" path="ajax/*.ashx" type="Ajax.PageHandlerFactory, Ajax" />
  </httpHandlers>      ...
<system.web>
</configuration>


Step3. 페이지 로드에 다음을 추가


private void Page_Load(object sender, EventArgs e){
    Ajax.Utility.RegisterTypeForAjax(typeof(Index));     
    //...
  }


Step4. AjaxMethod를 작성하고, 스크립트에서 호출(위의 예제 참조)

Posted by kkongchi
asp.net2006. 2. 25. 00:42

HTTP 압축은 gzip 등의 알고리즘을 사용해서, HTTP 를 통해서 전송되는 데이터의 양을 최고 50%로 압축하는 기술이다. ASP.NET 으로 만든 페이지들의 사이즈가 커서 Response Time 이 느리거나, 낮은 대역폭 - 이를테면 56K 라인 - 의 사용자들까지도 지원할려고 한다면, 그리고 더 많은 사용자를 지원하기 위해서 서버의 대역폭을 아껴쓰고자 할 때 상당히 유용하다.

HTTP 압축을 위한 상용 모듈도 있지만, Windows 2003에 내장된 IIS 6.0에서는 자체적으로도 지원을 한다. IIS 관리자에서 아주 간단하게 설정을 할 수 있다. IIS 관리자를 열어서, 트리의 "웹 사이트" 노드에다 마우스 오른쪽 버튼을 클릭하면 나오는 메뉴 중에서 속성을 선택한다. 그리고 "서비스" 탭을 선택하면 다음과 같은 화면이 나올텐데, 간단하게 체크만 해주고, IIS를 한번 Restart 시켜주면 바로 HTTP 압축을 사용할 수가 있다.




하지만, 이렇게만 했을 경우에 ASP.NET 의 aspx 는 압축되어서 내려가지 않는다. IIS가 압축하는 파일 유형에 포함되어 있지 않기 때문이다. aspx도 포함을 시키기 위해서는 WIN_DIR\System32\inetsrv\metabase.xml 파일을 편집해야 합니다. 이 파일에서 <IIsCompressionScheme> 노드를 찾아야 합니다
<IIsCompressionScheme Location ="/LM/W3SVC/Filters/Compression/deflate"
HcCompressionDll="%windir%\system32\inetsrv\gzip.dll"
HcCreateFlags="0"
HcDoDynamicCompression="TRUE"
HcDoOnDemandCompression="TRUE"
HcDoStaticCompression="FALSE"
HcDynamicCompressionLevel="0"
HcFileExtensions="htm
html
txt"
HcOnDemandCompLevel="10"
HcPriority="1"
HcScriptFileExtensions="asp
dll
exe
  aspx"
>
</IIsCompressionScheme>
<IIsCompressionScheme Location ="/LM/W3SVC/Filters/Compression/gzip"
HcCompressionDll="%windir%\system32\inetsrv\gzip.dll"
HcCreateFlags="1"
HcDoDynamicCompression="TRUE"
HcDoOnDemandCompression="TRUE"
HcDoStaticCompression="TRUE"
HcDynamicCompressionLevel="0"
HcFileExtensions="htm
html
txt"
HcOnDemandCompLevel="10"
HcPriority="1"
HcScriptFileExtensions="asp
dll
exe
  aspx"
>
</IIsCompressionScheme>

빨간 색으로 되어 있는 부분처럼, aspx확장자를 추가시켜주면 그때부터 aspx파일에 대해서도 IIS가 HTTP 압축을 수행할 것이다. (이 파일은 편집하기 위해서 IIS를 잠시 멈춰야 편집을 할 수 있다)

당연한 거겠지만, 압축을 수행하는 서버와 압축된 컨텐트를 받아서 풀어서 보여줘야 하는 클라이언트 양쪽에 약간씩의 CPU 부담이 있다. 하지만 30-50%에 이르는 압축율은 성능 향상과 대역폭 절약이라는 엄청난 이점을 가져오기 때문에, Windows 2003을 사용하는 웹 사이트에서는 충분히 사용할만한 기술인 것 같다.
Posted by kkongchi