참고 URL

http://support.microsoft.com/kb/307010/ko

Md5

http://www.hoons.kr/Lectureview.aspx?key=Lecture&LECCATE_IDX=26&ref=1&lecture_idx=45

http://msdn2.microsoft.com/ko-kr/library/system.security.cryptography.md5(VS.80).aspx#Mtps_DropDownFilterText

SHA1

http://msdn2.microsoft.com/ko-kr/library/system.security.cryptography.sha1(VS.80).aspx

MD5 클래스

MD5 해시 알고리즘의 모든 구현이 상속될 추상 클래스를 나타냅니다.

네임스페이스: System.Security.Cryptography
어셈블리: mscorlib(mscorlib.dll)

해시 함수는 임의의 길이의 이진 문자열을 고정된 길이의 작은 이진 문자열에 매핑합니다. 암호화 해시 함수는 동일한 값에 해시하는 두 개의 다른 입력을 연산적으로 찾지 못하는 속성, 즉 해당 데이터가 일치하면 두 집합의 데이터 해시도 일치하는 속성을 갖습니다. 데이터에 작은 변경이 있으면 해시에 예측할 수 없는 커다란 변경이 발생합니다.

MD5 알고리즘에 대한 해시 크기는 128비트입니다.

MD5 클래스의 :Track('ctl00_rs1_mainContentContainer_cpe58026_c|ctl00_rs1_mainContentContainer_ctl20',this);" href="http://msdn2.microsoft.com/ko-kr/library/tessz10c(VS.80).aspx">

ComputeHash 메서드는 해시를 16바이트 배열로 반환합니다. 일부 MD5 구현에서는 32자로 된 16진수 형식의 해시를 생성합니다. 이러한 구현을 사용하려면 ComputeHash 메서드의 반환 값 형식을 16진수 값으로 지정합니다.

예제

다음 코드 예제에서는 문자열의 MD5 해시 값을 계산하고 해시를 32자로 된 16진수 형식의 문자열로 반환합니다. 이 코드 예제에서 만든 해시 문자열은 모든 플랫폼에서 32자로 된 16진수 형식의 해시 문자열을 만드는 모든 MD5 해시 함수와 호환됩니다

using System;
using System.Security.Cryptography;
using System.Text;

class Example
{
    // Hash an input string and return the hash as
    // a 32 character hexadecimal string.
    static string getMd5Hash(string input)
    {
// Create a new instance of the MD5CryptoServiceProvider object.
        MD5 md5Hasher = MD5.Create();

  // Convert the input string to a byte array and compute the hash.
        byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));

// Create a new Stringbuilder to collect the bytes
        // and create a string.
        StringBuilder sBuilder = new StringBuilder();

        // Loop through each byte of the hashed data 
        // and format each one as a hexadecimal string.
        for (int i = 0; i < data.Length; i++)
        {
            sBuilder.Append(data[i].ToString("x2"));
        }

     // Return the hexadecimal string.
        return sBuilder.ToString();
    }

// Verify a hash against a string.
    static bool verifyMd5Hash(string input, string hash)
    {
// Hash the input.
        string hashOfInput = getMd5Hash(input);

  // Create a StringComparer an comare the hashes.
        StringComparer comparer = StringComparer.OrdinalIgnoreCase;

        if (0 == comparer.Compare(hashOfInput, hash))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    static void Main()
    {
        string source = "Hello World!";
        string hash = getMd5Hash(source);

        Console.WriteLine("The MD5 hash of " + source + " is: " + hash + ".");

        Console.WriteLine("Verifying the hash...");

        if (verifyMd5Hash(source, hash))
        {
            Console.WriteLine("The hashes are the same.");
        }
        else
        {
            Console.WriteLine("The hashes are not same.");
        }
    }
}

// This code example produces the following output:
//
// The MD5 hash of Hello World! is: ed076287532e86365e841e92bfc50d8c.
// Verifying the hash...
// The hashes are the same.

-------------------------------------------------------------------------------------------------------------------

            string hashedPassword =

               FormsAuthentication.HashPasswordForStoringInConfigFile(password.Text, "MD5");

Response.Write(hashedPassword)

--------------------------------------------------------------------------------------------------------------------

            MD5 md5Hasher = MD5.Create();
            byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(this.password.Text));
            StringBuilder sBuilder = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }

            // Return the hexadecimal string.
Response.Write("<br>md5Hasher=" + sBuilder.ToString().ToUpper() );

위의 두개는 결과값이 같습니다. 편한걸로 쓰세요

SHA1 클래스

입력 데이터에 대한 SHA1 해시를 계산합니다.

byte[] data = new byte[DATA_SIZE];
byte[] result;
 
SHA1 sha = new SHA1CryptoServiceProvider();
// This is one implementation of the abstract class SHA1.
result = sha.ComputeHash(data);

System.Web.UI.PostBackTrigger Sample

출처: http://www.asp.net/AJAX/Documentation/Live/ViewSample.aspx?sref=System.Web.UI.PostBackTrigger/cs/PostBackTriggerCS.aspx

 

 

<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
    private string saveDir = @"Uploads\";
    protected void UploadButton_Click(object sender, EventArgs e)
    {
        if (FileUpload1.HasFile && FileUpload1.FileBytes.Length < 10000 &&
            !CheckForFileName())
        {
            string savePath = Request.PhysicalApplicationPath + saveDir +
                Server.HtmlEncode(FileName.Text);
            //Remove comment from the next line to upload file.
            //FileUpload1.SaveAs(savePath);
            UploadStatusLabel.Text = "The file was processed successfully.";
        }
        else
        {
            UploadStatusLabel.Text = "You did not specify a file to upload, or a file name, or the file was too large. Please try again.";
        }
    }
    protected void CheckButton_Click(object sender, EventArgs e)
    {
        if (FileName.Text.Length > 0)
        {
            string s = CheckForFileName() ? "exists already." : "does not exist.";
            UploadStatusLabel.Text = "The file name choosen " + s;
        }
        else
        {
            UploadStatusLabel.Text = "Specify a file name to check.";
        }
    }
    private Boolean CheckForFileName()
    {
        System.IO.FileInfo fi = new System.IO.FileInfo(Request.PhysicalApplicationPath + 
            saveDir + Server.HtmlEncode(FileName.Text));
            return fi.Exists;
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>PostBackTrigger Example</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <asp:ScriptManager ID="ScriptManager1" runat="server" />
    The upload button is defined as a PostBackTrigger.<br/>
    <asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
    <ContentTemplate>
    <fieldset>
    <legend>FileUpload in an UpdatePanel</legend>
       First, enter a file name to upload your file to: 
       <asp:TextBox ID="FileName" runat="server" />
       <asp:Button ID="CheckButton" Text="Check" runat="server" OnClick="CheckButton_Click" />
       <br />
       Then, browse and find the file to upload:
       <asp:FileUpload id="FileUpload1"                 
           runat="server">
       </asp:FileUpload>
       <br />
       <asp:Button id="UploadButton" 
           Text="Upload file"
           OnClick="UploadButton_Click"
           runat="server">
       </asp:Button>    
       <br />
       <asp:Label id="UploadStatusLabel"
           runat="server" style="color:red;">
       </asp:Label>           
    </fieldset>
    </ContentTemplate>
    <Triggers>
    <asp:PostBackTrigger ControlID="UploadButton" />
    </Triggers>
    </asp:UpdatePanel>
    </div>
    </form>
</body>
</html>

엔터키

TextBoxSearchText.Attributes.Add("onkeypress", "if (event.keyCode == 13) {" + this.Page.GetPostBackEventReference(ImageButtonSearchBtn) + "; return false;}");

 

마우스 클릭시 행선택

LinkButton btn = ((LinkButton)e.CommandSource);
            int row_num = (int)((GridViewRow)btn.Parent.Parent).RowIndex;

             
            e.Row.Attributes.Add("onMouseOver", "this.className='focusBarOver';"); //오버시 행의 클래스를 변경
            e.Row.Attributes.Add("onMouseOut", "this.className='focusBarOut';");
            e.Row.Attributes.Add("onClick", @"document.getElementById('" + LinkButton1 .ClientID+ "').click();");
            e.Row.Style.Add("cursor", "hand");

Fritz Onion

Get the sample code for this article.

코드 다운로드 위치: ExtremeASPNET2007_01.exe


목차

AJAX를 사용한 웹 서비스 호출
작동 원리
Serialization
결론


처음 등장할 때부터 ASP.NET은 서버측 기술을 기반으로 했습니다. 유효성 검사 제어나 최근에 등장한 웹 파트 인프라에서와 같이 ASP.NET이 클라이언트측 JavaScript를 생성하는 경우도 있지만, 이는 단순히 서버측 속성을 클라이언트측 동작으로 변환한 것에 불과합니다. 따라서 개발자는 다음 POST 요청을 수신하기 전까지는 클라이언트와의 상호 작용을 고려할 필요가 없었습니다. JavaScript의 경우에는 보다 대화형에 가까운 페이지를 작성해야 했는데, 이러한 문제는 ASP.NET 2.0 스크립트 콜백 기능을 활용하여 DHTML에서 자체적으로 해결되었습니다. 그러나 작년에 이러한 기능이 완전히 바뀌었습니다.

2005년 9월에 열린 Microsoft Professional Developer's Conference에서 Microsoft는 새로운 ASP.NET 추가 기능을 발표했습니다. 코드명 "Atlas"로 소개된 이 추가 기능은 오로지 클라이언트측 JavaScript, DHTML 및 XMLHttpRequest 개체 활용에만 중점을 두고 개발된 것이었습니다. 즉, 개발자가 보다 대화형에 가까운 AJAX 지원 웹 응용 프로그램을 만들 수 있도록 하는 것을 목표로 한 것이었습니다. Microsoft® AJAX Library 및 ASP.NET 2.0 AJAX Extensions라는 공식 타이틀로 이름이 바뀐 이 프레임워크는 클라이언트측 데이터 바인딩에서 DHTML 애니메이션 및 동작, 그리고 UpdatePanel을 사용한 클라이언트 POST 백의 정교한 차단에 이르기까지 여러 가지 유용한 기능을 제공합니다. 이러한 기능은 대부분 구문 분석 및 클라이언트측 JavaScript 호출을 통한 상호 작용이 용이한 형태로 서버에서 비동기식으로 데이터를 검색하는 기능을 기반으로 합니다. 이 달의 칼럼은 ASP.NET 2.0 AJAX Extensions 지원 페이지의 클라이언트측 JavaScript에서 서버측 웹 서비스를 호출하는 이 새롭고 유용한 기능을 주제로 설명합니다.

AJAX를 사용한 웹 서비스 호출

wsel.exe 유틸리티를 사용하거나 Visual Studio®의 웹 참조 추가 기능을 이용하여 Microsoft .NET Framework에서 웹 서비스를 사용한 경험이 있다면 어렵지 않게 .NET 형식을 사용하여 웹 서비스를 호출하는 작업을 수행할 수 있을 것입니다. 사실 .NET 프록시를 통해 웹 서비스 메서드를 호출하는 것은 다른 클래스에 대한 메서드를 호출하는 것과 다르지 않습니다. .NET 프록시는 사용자가 전달한 매개 변수를 기준으로 XML을 준비하고 수신한 XML 응답을 proxy 메서드에 지정된 .NET 형식으로 세밀하게 변환합니다. .NET Framework를 이용하여 웹 서비스 끝점을 손쉽게 사용할 수 있게 됨으로써 개발자가 선택할 수 있는 폭이 넓어졌으며, 이것이 바로 오늘날 새롭게 탄생한 서비스 지향 응용 프로그램의 핵심입니다.

ASP.NET 2.0 AJAX Extensions를 사용하면 브라우저에서 실행되는 클라이언트측 JavaScript의 웹 서비스에 대해서도 이와 같이 원활하게 프록시를 생성할 수 있습니다. 또한 서버에서 호스트하는 .asmx 파일을 작성하고 클라이언트측 JavaScript 클래스를 통해 해당 서비스의 메서드를 호출할 수 있습니다. 예를 들어 그림 1에는 임의 데이터를 사용하여 가상 주식 시세 검색 기능을 구현하는 간단한 .asmx 서비스가 나와 있습니다.

이 서비스에는 표준 .asmx 웹 서비스 특성 외에 JavaScript 클라이언트에서도 해당 서비스를 사용할 수 있도록 하는 ScriptService 특성이 있습니다. 이 .asmx 파일을 ASP.NET AJAX 지원 웹 응용 프로그램에 배포하면 .aspx 파일의 ScriptManager 컨트롤에 ServiceReference를 추가하여 JavaScript에서 서비스의 메서드를 호출할 수 있습니다. ScriptManager 컨트롤은 Visual Studio에서 ASP.NET AJAX 지원 웹 사이트 템플릿을 사용하여 웹 사이트를 만들 때 기본.aspx 페이지에 자동으로 추가됩니다.

<asp:ScriptManager ID="_scriptManager" runat="server">
  <Services>
    <asp:ServiceReference Path="StockQuoteService.asmx" />
  </Services>
</asp:ScriptManager>

이제 클라이언트측 JavaScript 런타임에서 MsdnMagazine.StockQuoteService 클래스를 사용하여 서비스의 모든 메서드를 호출할 수 있습니다. 호출을 비동기 방식의 메커니즘을 기반으로 이루어지기 때문에 동기식 메서드는 사용할 수 없습니다. 대신 각 프록시 메서드에 표준 입력 매개 변수 외에 추가 매개 변수가 하나 사용됩니다. 이 매개 변수는 메서드가 완료되었을 때 비동기로 호출되는 다른 클라언트측 JavaScript 함수에 대한 참조입니다. 그림 2의 예제 페이지에서는 클라이언트측 JavaScript를 사용하여 주식 시세 웹 서비스 호출 결과를 페이지의 레이블(span)에 인쇄합니다.

클라이언트측 웹 서비스 호출에 문제가 발생한 경우 클라이언트에 알려야 하므로 일반적으로 오류, 중단 또는 시간 초과 발생 시에 호출되는 다른 메서드를 전달하는 것이 좋습니다. 예를 들어 앞에서 나왔던 OnLookup을 다음과 같이 변경하여 문제를 표시하는 OnError 메서드를 추가할 수 있습니다.

function OnLookup()
{           
  var stb = document.getElementById("_symbolTextBox");  
  MsdnMagazine.StockQuoteService.GetStockQuote(
    stb.value, OnLookupComplete, OnError);
}
    
function OnError(result)
{
  alert("Error: " + result.get_message());
}

이렇게 하면 웹 서비스 호출에 실패한 경우 경고 상자를 통해 클라이언트에 알리게 됩니다. 또한 클라이언트에서 만들어지는 웹 서비스 호출에 userContext 매개 변수를 포함할 수도 있습니다. 이 매개 변수는 Web 메서드에 마지막 매개 변수로 전달되는 임의 문자열로, success 및 failure 메서드에 추가 매개 변수로 전파됩니다. 이 경우 다음과 같이 OnLookupComplete 메서드에 표시할 수 있도록 userContext로 요청된 실제 주식 기호를 전달해야 합니다.

function OnLookup()
{           
  var stb = document.getElementById("_symbolTextBox");  
  MsdnMagazine.StockQuoteService.GetStockQuote(
    stb.value, OnLookupComplete, OnError, stb.value);
}

function OnLookupComplete(result, userContext)
{
  // userContext contains symbol passed into method
  var res = document.getElementById("_resultLabel");
  res.innerHTML = userContext + " : <b>" + result + "</b>";
}

웹 서비스에 대한 서로 다른 호출을 여러 개 만들고 각 호출에 동일한 오류 및/또는 완료 메서드를 사용하는 경우 기본 오류 및 콜백 성공 메서드를 전역으로 설정할 수 있습니다. 이렇게 하면 호출을 만들 때마다 콜백 메서드 쌍을 지정할 필요가 없습니다. 단, 원하는 경우 전역으로 정의된 메서드를 각 메서드별로 재설정할 수 있습니다. 다음은 기본 콜백 성공 메서드와 콜백 실패 메서드를 호출별로 설정하는 대신 전역으로 설정하는 OnLookup 메서드 샘플입니다.

// Set default callbacks for stock quote service
MsdnMagazine.StockQuoteService.set_defaultSucceededCallback(
                 OnLookupComplete);
MsdnMagazine.StockQuoteService.set_defaultFailedCallback(
                 OnError);
function OnLookup()
{           
  MsdnMagazine.StockQuoteService.GetStockQuote(stb.value);
}

웹 서비스 메서드를 호출하기 위해 .asmx 파일을 새로 작성하는 대신 페이지 클래스에 직접 웹 서비스 메서드를 포함할 수도 있습니다. 호출할 메서드에 대해 완전한 웹 서비스 끝점을 만들 수 없는 경우에는 서버측 메서드를 페이지에 추가(페이지에서 직접 추가하거나 코드 숨김 파일에 추가)하고 WebMethod 특성을 연결하여 클라이언트측 JavaScript에서 호출 가능한 웹 메서드를 페이지에서 제공할 수 있습니다. 그러면 클라이언트측 개체 PageMethods를 통해 해당 메서드를 호출할 수 있습니다. 그림 3에는 별도의 웹 서비스로 나누는 대신 전체가 단일 페이지에 포함되도록 다시 작성된 주식 시세 서비스 샘플이 나와 있습니다.

이러한 클라이언트측 프록시는 ASP.NET .asmx 끝점, Windows Communication Foundation .svc 끝점 또는 페이지에 직접 포함된 웹 메서드에서만 생성할 수 있으며 임의 웹 서비스를 호출하는 일반적인 메커니즘은 없습니다. 사실 보안상의 이유로 기본 XmlHTTPRequest 개체에는 요청이 페이지가 로드된 도메인으로 제한되기 때문에 클라이언트측 프록시에서 지원되는지 여부에 관계없이 이러한 방식으로 임의 웹 서비스를 호출할 수 없습니다. 외부 웹 서비스를 호출해야 하는 경우 wsdl.exe를 사용하거나 Visual Studio의 웹 참조 추가 명령을 통해 생성한 .NET 프록시 클래스를 호출하는 응용 프로그램에서 외부 웹 서비스에 대한 브리지 .asmx 끝점을 설정하는 것이 최선의 방법입니다.

Back to top

작동 원리

표준 .asmx 웹 서비스를 가져와 브라우저에서 클라이언트측 JavaScript를 통해 거의 변경되지 않은 상태로 액세스할 수 있다는 사실이 처음에는 놀랍게 느껴질 수 있습니다. 이러한 기능은 모든 ASP.NET AJAX 지원 웹 사이트의 구성 파일에 추가된 새로운 .asmx HTTP 처리기가 등록되면서 가능해졌습니다.

<httpHandlers>
  <remove verb="*" path="*.asmx"/>
  <add verb="*" path="*.asmx" 
       type="Microsoft.Web.Services.ScriptHandlerFactory" 
       validate="false"/>
</httpHandlers>

새로 등록된 이 처리기는 .asmx 끝점에 대한 표준 웹 서비스 요청이 전달되면 표준 웹 서비스 처리기(System.Web.Services.Protocols.WebServiceHandlerFactory)를 호출합니다. 그러나 요청의 URL 뒷부분에 /js 옵션이 있거나 mn= 변수를 사용한 쿼리 문자열(예: ?mn=GetStockQuote)이 포함되어 있으면 처리기는 웹 서비스에 사용할 클라이언트측 프록시를 생성하는 JavaScript를 반환(/js 옵션을 사용한 경우)하거나 웹 서비스 파생 클래스에 정의된 해당 메서드를 호출하고 JSON(JavaScript Object Notation)으로 인코딩된 문자열로 응답을 패키징(?mn= 옵션을 사용한 경우)합니다.

페이지에 ScriptManager 컨트롤의 ServiceReference 요소를 통한 클라이언트측 .asmx 서비스 참조가 있으면 .asmx 파일을 참조하는 스크립트 요소가 후행 /js 옵션과 함께 추가되어 클라이언트에 프록시가 생성됩니다. 예를 들어 앞서 필자가 작성한 주식 시세 페이지는 다음과 같은 스크립트 요소가 추가된 상태로 렌더링됩니다.

<script src="StockQuoteService.asmx/js" 
        type="text/javascript"></script>

물론 이 프록시와 상호 작용하는 데 필요한 클라이언트측 기능이 포함된 Microsoft AJAX 라이브러리에도 스크립트 참조가 추가됩니다. 이 끝점을 직접 탐색하려 하면 다음과 같은 JavaScript (일부 생략)가 나타납니다.

Type.registerNamespace('MsdnMagazine');
MsdnMagazine.StockQuoteService=function() {
  this._timeout = 0;
  this._userContext = null;
  this._succeeded = null;
  this._failed = null;
}
MsdnMagazine.StockQuoteService.prototype={
GetStockQuote:Sys.Net._WebMethod._createProxyMethod(this,
     "GetStockQuote", 
     "MsdnMagazine.StockQuoteService.GetStockQuote",
     "symbol"), ...
}

이 JavaScript는 ScriptManager 컨트롤이 포함된 모든 페이지에 추가되어 있는 Microsoft AJAX 라이브러리의 기능(네임스페이스, WebMethod 클래스 등)을 사용합니다. 이 JavaScript에 의해 생성된 프록시 메서드는 ?mn=GetStockQuote라는 쿼리 문자열을 사용하여 .asmx 끝점을 호출하도록 초기화되므로 클라이언트에서 MsdnMagazine.StockQuoteService.GetStockQuote를 호출할 때마다 동일한 .asmx 끝점에 대한 비동기 웹 요청으로 바뀝니다. 이렇게 클라이언트측 프록시 생성 기능과 서버측의 JavaScript로 시작되는 웹 서비스 호출 지원 기능이 결합됨으로써 직관적인 방식으로 .asmx 웹 서비스에 클라이언트측 호출을 포함할 수 있게 되었습니다.

Back to top

Serialization

AJAX 기반 웹 서비스는 기본적으로 JSON으로 serialize됩니다. 실행 시에 마지막 섹션의 페이지 추적 내용에는 웹 서비스 요청 및 응답의 본문이 다음과 같이 표시됩니다.

Request: {"symbol":"ABC"}
Response: 51

이는 기존에 .asmx 웹 서비스를 호출할 때 표시되었던 익숙한 표준 XML 형식이 아닙니다. .asmx 끝점이 XML로 serialize되도록 작성되었기 때문에 ASP.NET 2.0 AJAX Extensions에 JSON Serializer가 추가된 것입니다. JSON Serializer는 두 가지가 있습니다. 그 중 하나는 클라이언트용으로 JavaScript에 구현되어 있고 다른 하나는 서버용으로 .NET에 구현되어 있습니다. 이 서버용은 특히 AJAX 클라이언트가 .asmx 끝점을 호출하는 경우에 많이 사용됩니다. 서버측 Serializer는 Microsoft.Web.Script.Serialization.JavaScriptSerializer 클래스를 통해 사용할 수 있으며 클라이언트측 Serializer는 Sys.Serialization.JavaScriptSerializer를 통해 사용할 수 있습니다. XML 대신 JSON을 Serialization 형식으로 사용하는 데 따른 가장 큰 이점은 JSON 문자열을 평가하는 방법으로 간단히 JavaScript의 개체를 deserialize할 수 있다는 점입니다. 따라서 오류 검사가 제거되어 클라이언트 serializer 클래스의 deserialize 메서드가 매우 짧아집니다.

Sys.Serialization.JavaScriptSerializer.deserialize=
    function(){eval('('+data+')');}

반면 JavaScriptSerializer의 serialize 메서드는 상대적으로 사용 빈도가 높습니다. JSON 형식을 사용하는 데 따른 또 다른 이점으로는 XML 형식에 비해 상대적으로 간략하게 표현할 수 있다는 점입니다.

표준 웹 서비스에 XmlSerializer를 사용하여 다른 형식을 XML로 serialize하는 경우와 마찬가지로 JavaScriptSerializer를 사용하여 거의 모든 .NET 형식을 JSON으로 serialize할 수 있습니다. JavaScriptSerializer 클래스의 Serialize 메서드만 호출하면 손쉽게 사용해 볼 수 있습니다. 그림 4에는 그림 5의 복잡한 Person 형식을 serialize하는 샘플 콘솔 응용 프로그램이 나와 있습니다. 이 응용 프로그램의 경우 GAC(전역 어셈블리 캐시)에 ASP.NET AJAX Extensions과 함께 설치된 Microsoft.Web.Extensions.dll에 대한 참조를 포함해야 합니다.

이 콘솔 응용 프로그램의 출력은 JSON 형식의 Person 클래스 또는 다음이 됩니다.

{"Married":true,"Age":33,"FirstName":"Bob","LastName":"Smith"}

XmlSerializer와 마찬가지로 JavaScriptSerializer는 공개적으로 액세스할 수 있는 특정 형식의 데이터만 serialize하며, 순환 참조 확인 기능은 지원되지 않습니다. 그러나 DataSet를 비롯하여 표준 .asmx 웹 서비스로 serialize할 수 있는 모든 형식은 이 serializer에서도 문제 없이 serialize할 수 있습니다. 이 serializer를 사용하면 .asmx 파일에 정의된 SOAP 기반 웹 서비스와 마찬가지로 손쉽게 처리할 수 있으므로 복잡한 웹 서비스도 쉽게 작성할 수 있습니다.

그림 6의 예제는 앞에서 정의된 Person 개체의 특성을 적절히 수정하기 위한 Marry 메서드를 구현하는 MarriageService라는 웹 서비스를 보여 줍니다. 해당 ASP.NET 페이지는 이번 호의 코드 다운로드 파일에 포함되어 있습니다.

원한다면 클라이언트측 스크립트에 XML 형식을 사용할 수도 있습니다. 웹 서비스를 정의할 때 사용되는 WebMethod 특성 외에 Microsoft.Web.Script.Services 네임스페이스에 ScriptMethod라는 특성이 새로 추가되었습니다. 이 특성에는 Json(기본값) 또는 Xml로 설정할 수 있는 ResponseFormat 속성이 있습니다.

namespace PS
{
    [ScriptService] 
    [WebService(Namespace = "http://pluralsight.com/ws")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class StockQuoteService : WebService
    {
        [WebMethod]
        public int GetStockQuote(string symbol)
        {
            return (new Random()).Next(0, 120);
        }
    }
}
serialize된 응답은 다음과 같습니다.
<?xml version="1.0" encoding="utf-8"?><int>74</int>

클라이언트측 JavaScript에서 XML 응답을 처리하기 위해 이 메서드를 호출하는 시점은 개발자가 결정할 수 있습니다. 이는 XML 응답을 변환할 계획이거나 이미 MSXML을 사용하고 있는 경우에 유용합니다.

Back to top

결론

ASP.NET 2.0 AJAX Extensions가 클라이언트측 코드에서 특정 ASP.NET 2.0 서비스를 실행하는 미리 작성된 ProfileService 및 AuthenicationService 서비스를 제공한다는 점은 중요한 장점입니다. 이 두 가지 클라이언트측 프록시 클래스를 사용하면 개별 클라이언트의 프로필 값을 설정 및 검색하고 기본 구성원 자격 공급자를 통해 인증을 수행하고 전적으로 클라이언트 스크립트에서 인증 쿠키를 허용할 수 있습니다.

ASP.NET 2.0 AJAX Extensions에 대한 대부분의 논의나 예제가 응답성이 뛰어난 사용자 인터페이스를 구현하는 화려한 컨트롤에 중점을 두고 있지만 가장 인상적이고 유용한 기능은 클라이언트측 JavaScript에서 웹 서비스를 직접 호출하는 기능입니다. 정식 .NET Framework/JSON Serializer를 사용하는 경우 익숙한 .asmx 웹 서비스에 직접 통합될 뿐만 아니라 일괄 처리, 자동 생성된 외부 웹 서비스 브리지 등 광범위하고 심도 있는 웹 서비스 지원 기능이 제공되기 때문입니다..

 

템플릿 데이터 바인딩 컨트롤을 통해 페이지의 데이터를 융통성있게 렌더링할 수 있습니다. DataList와 Repeater 컨트롤과 같은 ASP.NET v1.x의 많은 템플릿 컨트롤은 ASP.NET 2.0에서도 계속해서 지원되지만 이번 릴리스에서는 템플릿 내부에서 컨트롤 데이터를 바인딩하는 방법이 단순화되고 향상되었습니다. 이 단원에서는 데이터 바인딩 컨트롤 템플릿 내부에서 데이터를 바인딩하는 여러 가지 방법에 대해 설명합니다.

ASP.NET 2.0에서는 데이터 바인딩 구문을 DataBinder.Eval(Container.DataItem, fieldname)의 전체 v1.x 구문에서 Eval(fieldname)로 단순화하여 템플릿에서의 데이터 바인딩 기능을 향상시켰습니다. DataBinder.Eval과 마찬가지로 Eval 메서드도 선택적

formatString 매개 변수를 사용합니다.

간단해진 Eval 구문은 DataBinder.Eval과 차이점이 있습니다.

즉, Eval은 가장 가까운 컨테이너 개체(위 예제에서는 DataListItem)의 DataItem 속성에 대해 필드를 자동으로 확인하지만 DataBinder.Eval은 컨테이너에 대한 인수를 사용합니다.

따라서 Eval은 데이터 바인딩 컨트롤의 템플릿 내부에서만 사용되며 페이지 수준에서는 사용할 수 없습니다.

물론 DataBinder.Eval도 ASP.NET 2.0 페이지에서 계속해서 지원되므로 단순화된 Eval 구문이 지원되지 않는 시나리오에서 대신 사용하면 됩니다.

<asp:DataList DataSourceID="ObjectDataSource1" runat="server">
  <ItemTemplate>
    <asp:Image ImageUrl='<%# Eval("FileName", "images/thumbs/{0}") %>' runat="server"/>
    <asp:Label Text='<%# Eval("Caption") %>' runat="server"/>
  </ItemTemplate>
</asp:DataList>

두개 인자값넘길때

<asp:HyperLink ID="HyperLink1" runat="server" Text='<%#Eval("m_id") %>' NavigateUrl='<%# "/main.aspx?m_id="+Eval("m_id")+"&idx="+Eval("idx")  %>'>

</asp:HyperLink>

테마와 CSS 스타일시트 비교

테마와 스타일시트는 둘 다 모든 페이지에 적용할 수 있는 공통 특성 집합을 정의한다는 점에서 비슷합니다. 하지만 테마와 스타일시트는 다음과 같은 점이 다릅니다.

  • 테마는 특정한 스타일 속성뿐만 아니라 컨트롤이나 페이지의 여러 속성을 정의할 수 있습니다. 예를 들어 테마를 사용하여 TreeView 컨트롤의 그래픽, GridView 컨트롤의 템플릿 레이아웃 등을 지정할 수 있습니다.

  • 테마에는 그래픽이 포함될 수 있습니다.

  • 테마는 스타일시트의 캐스케이드 방식을 사용하지 않습니다. 예를 들어, 사용자가 테마를 명시적으로 스타일시트 테마로 적용하지 않는 경우 기본적으로 속성 값이 로컬 속성 값을 재정의합니다.

  • 각 페이지에는 하나의 테마만 적용할 수 있습니다. 여러 스타일시트를 적용할 수 있는 스타일시트와 달리 한 페이지에 여러 테마를 적용할 수 없습니다.

테마 폴더에 .skin 파일을 만듭니다. .skin 파일에는 여러 컨트롤 형식에 대한 하나 이상의 컨트롤 스킨이 포함될 수 있습니다. 각 컨트롤에 대해 별도로 스킨 파일을 정의하거나 테마에 있는 모든 스킨을 단일 파일로 정의할 수 있습니다.

컨트롤 스킨에는 기본 스킨과 명명된 스킨의 두 가지 형식이 있습니다.

  • 테마를 페이지에 적용할 때 같은 형식의 모든 컨트롤에 기본 스킨이 자동으로 적용됩니다. SkinID 특성이 없는 컨트롤 스킨은 기본 스킨입니다. 예를 들어, Calendar 컨트롤에 대한 기본 스킨을 만들면, 테마를 사용하는 페이지의 모든 Calendar 컨트롤에 컨트롤 스킨이 적용됩니다. 기본 스킨은 컨트롤 형식과 정확히 일치하기 때문에 Button 컨트롤 스킨은 모든 Button 컨트롤에 적용되지만 LinkButton 컨트롤 또는 Button 개체에서 파생된 컨트롤에는 적용되지 않습니다.

  • 명명된 스킨은 SkinID 속성이 설정된 컨트롤 스킨입니다. 명명된 스킨은 형식별로 컨트롤에 자동으로 적용되지 않습니다. 그 대신 컨트롤의 SkinID 속성을 설정하여 명명된 스킨을 컨트롤에 명시적으로 적용할 수 있습니다. 명명된 스킨을 만들면 응용 프로그램에서 동일 컨트롤의 각 인스턴스에 대해 서로 다른 스킨을 설정할 수 있습니다.

페이지 테마를 만들려면

  1. 웹 사이트에 App_Themes라는 새 폴더를 만듭니다.

    참고

    폴더 이름은 App_Themes여야 합니다.

  2. 테마 파일을 저장하기 위해 App_Themes 폴더의 새 하위 폴더를 만듭니다.

  3. 이 하위 폴더의 이름은 테마의 이름입니다. 예를 들어 이름이 BlueTheme인 테마를 만들려면 \App_Themes\BlueTheme 폴더를 만듭니다.

  4. 테마를 구성하는 스킨, 스타일시트 및 이미지 관련 파일을 새 폴더에 추가합니다.

스킨을 만들려면

  1. 테마 하위 폴더에서 확장명이 .skin인 새 텍스트 파일을 만듭니다.

  2. 일반적으로는 Button.skin 또는 Calendar.skin처럼 각 컨트롤에 대해 .skin 파일을 하나씩 만들어야 합니다. 그러나 스킨 파일에는 스킨 정의를 여러 개 포함할 수 있으므로 필요에 따라 .skin 파일의 수를 조정할 수 있습니다.

  3. .skin 파일에서 선언적 구문을 사용하여 표준 컨트롤 정의를 추가합니다. 이 때 테마에 설정할 속성만 포함하고 ID 특성은 포함하지 않습니다. 컨트롤 정의에는 runat="server" 특성이 포함되어야 합니다.

    다음 예제에서는 테마에 있는 모든 Button 컨트롤의 색과 글꼴을 정의하여 Button 컨트롤에 대한 기본 컨트롤 스킨을 보여 줍니다.

예제코드

TestSkin.skin

<%--
기본 스킨 템플릿입니다. 다음 스킨은 예제로만 제공됩니다.

1. 명명된 컨트롤 스킨. 동일한 테마에는 각 컨트롤 형식에 SkinId가
   중복될 수 없으므로 SkinId는 고유하게 정의해야 합니다.

<asp:GridView runat="server" SkinId="gridviewSkin" BackColor="White" >
   <AlternatingRowStyle BackColor="Blue" />
</asp:GridView>

2. 기본 스킨. SkinId가 정의되어 있지 않습니다. 동일한 테마에서
   각 컨트롤 형식에는 기본 컨트롤 스킨을 하나만 사용할 수 있습니다.

<asp:Image runat="server" ImageUrl="~/images/image1.jpg" />

--%>

페이지나 웹 사이트에 또는 전체적으로 테마를 적용할 수 있습니다. 웹 사이트 수준에서 테마를 설정하면 개별 페이지에 대한 테마를 재정의하는 경우를 제외하고 사이트의 모든 페이지 및 컨트롤에 스타일과 스킨이 적용됩니다. 페이지 수준에서 테마를 설정하면 해당 페이지 및 페이지에 포함된 모든 컨트롤에 스타일과 스킨이 적용됩니다.

기본적으로 테마는 로컬 컨트롤 설정을 재정의합니다. 또는 컨트롤에 명시적으로 설정되지 않은 컨트롤 설정에만 테마가 적용되도록 테마를 스타일시트 테마로 설정할 수도 있습니다.

웹 사이트에 테마를 적용하려면

다음 예제와 같이 응용 프로그램의 Web.config 파일에서 <pages> 요소를 전역 테마 또는 페이지 테마의 이름으로 설정합니다.

<configuration>
    <system.web>
        <pages theme="ThemeName" />
    </system.web>
</configuration>

***** 응용 프로그램 테마와 전역 응용 프로그램 테마의 이름이 같으면 페이지 테마가 우선권을 가집니다.

테마를 스타일시트 테마로 설정하고 로컬 컨트롤 설정에 종속되게 하려면 StyleSheetTheme 특성을 대신 설정합니다.

<configuration>
    <system.web>
        <pages StyleSheetTheme="Themename" />
    </system.web>
</configuration>

Web.config 파일의 테마 설정은 해당 응용 프로그램의 모든 ASP.NET 웹 페이지에 적용됩니다. Web.config 파일의 테마 설정은 일반적인 구성 계층 구조 규칙을 따릅니다. 예를 들어 페이지의 하위 집합에만 테마를 적용하려면 Web.config 파일이 있는 폴더에 페이지를 넣거나 루트 Web.config 파일에 <location> 요소를 만들어 폴더를 지정하면 됩니다. 자세한 내용은 특정 파일 및 하위 디렉터리 구성을 참조하십시오.

********** <pages > 참고하세요~*****************************

<pages buffer="[True|False]" 
enableSessionState="[True|False|ReadOnly]" 
enableViewState="[True|False]" 
enableViewStateMac="[True|False]" 
smartNavigation="[True|False]" 
autoEventWireup="[True|False]" 
pageBaseType="typename, assembly" 
userControlBaseType="typename" 
validateRequest="[True|False]" 
masterPageFile="file path" 
theme="string" 
styleSheetTheme="string" 
maxPageStateFieldLength="number" 
compilationMode="[Always|Auto|Never]" 
pageParserFilterType="string" 
viewStateEncryptionMode="[Always|Auto|Never]" 
maintainScrollPositionOnPostBack="[True|False]" 
asyncTimeout="number" > 
<controls>...</controls> 
<namespaces>...</namespaces> 
<tagMapping>...</tagMapping> 
</pages>
만약특정디렉토리만 하고 싶다면 <location>  을 사용해서 지정하면됨
<configuration>
    <system.web>
        <pages StyleSheetTheme="Themename" />
    </system.web>
</configuration>

//ProductList 디렉토리 이름
      <location path="ProductList">
        <system.web>
          <pages theme="main" ></pages>
        </system.web>
      </location>
 
*********************************************
 
 

개별 페이지에 테마를 적용하려면

다음 예제와 같이 사용할 테마의 이름을 @ Page 지시문의 Theme 또는 StyleSheetTheme 특성에 설정합니다.

<%@ Page Theme="ThemeName" %>
<%@ Page StyleSheetTheme="ThemeName" %>

명명된 스킨을 컨트롤에 적용하려면
  • 다음 예제와 같이 컨트롤의 SkinID 속성을 설정합니다.

<asp:Calendar runat="server" ID="DatePicker" SkinID="SmallCalendar" />

예제 ))~~

App_Themes 폴더

  ㄴmain

          ㄴ SkinFile.skin

          ㄴ StyleSheet.css

소스

[ SkinFile.skin ]

<asp:Label  runat="server" BackColor="Silver" BorderColor="Gray" ForeColor="Black"
Height="91px" Text="Label" Width="321px"></asp:Label>

//Button 이 두개 인데 나중에 SkinID를 통해서 원하는것을 사용할수있따
만약 스킨아이디가 없다면 기본 스킨이 적용(스킨아이디가 지정안된 컨트롤) 된다.

<asp:Button runat="server"
  BackColor="Red"
  ForeColor="blue"
  Font-Name="Arial"
  Font-Size="9px"  SkinID="Test" />
<asp:Button runat="server"
  BackColor="white"
  ForeColor="blue"
  Font-Name="Arial"
  Font-Size="9px"  SkinID="Test2" />

/>

[StyleSheet.css]

body
{
background-color:Gray
}

요렇게 파일이 있따

Default.aspx 에 적용할꺼다

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication3._Default" StylesheetTheme="main" %>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>제목 없음</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

//아래의 컨트롤들은 테마와 스킨이 적용된 상태
        <asp:Label ID="Label1" runat="server" BackColor="Silver" BorderColor="Gray" ForeColor="Black"
            Height="19px" Text="Label" Width="321px"></asp:Label>
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        <asp:Button ID="Button1" runat="server" Text="Button" SkinID="Test" Height="23px" Width="95px" />&nbsp;
    </div>
    </form>
</body>
</html>

대따 편하다 ㅜ_ㅜ

마스터 페이지 TestMaster.MASTER

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class MasterPage_MasterPage : System.Web.UI.MasterPage
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    public void Test() {

        Response.Write("날 부른거냐?");
    }

}

TestMaster.MASTER로 생성된 default.aspx 컨텐츠 페이지

public partial class MasterPage_Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

MasterPage_MasterPage mc = (MasterPage_MasterPage )this.Page.Master;
        mc.Test();
    }
}

System.Web.UI.PostBackTrigger Sample

http://www.asp.net/AJAX/Documentation/Live/ViewSample.aspx?sref=System.Web.UI.PostBackTrigger/cs/PostBackTriggerCS.aspx

<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
    private string saveDir = @"Uploads\";
    protected void UploadButton_Click(object sender, EventArgs e)
    {
        if (FileUpload1.HasFile && FileUpload1.FileBytes.Length < 10000 &&
            !CheckForFileName())
        {
            string savePath = Request.PhysicalApplicationPath + saveDir +
                Server.HtmlEncode(FileName.Text);
            //Remove comment from the next line to upload file.
            //FileUpload1.SaveAs(savePath);
            UploadStatusLabel.Text = "The file was processed successfully.";
        }
        else
        {
            UploadStatusLabel.Text = "You did not specify a file to upload, or a file name, or the file was too large. Please try again.";
        }
    }
    protected void CheckButton_Click(object sender, EventArgs e)
    {
        if (FileName.Text.Length > 0)
        {
            string s = CheckForFileName() ? "exists already." : "does not exist.";
            UploadStatusLabel.Text = "The file name choosen " + s;
        }
        else
        {
            UploadStatusLabel.Text = "Specify a file name to check.";
        }
    }
    private Boolean CheckForFileName()
    {
        System.IO.FileInfo fi = new System.IO.FileInfo(Request.PhysicalApplicationPath +
            saveDir + Server.HtmlEncode(FileName.Text));
            return fi.Exists;
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>PostBackTrigger Example</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <asp:ScriptManager ID="ScriptManager1" runat="server" />
    The upload button is defined as a PostBackTrigger.<br/>
    <asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
    <ContentTemplate>
    <fieldset>
    <legend>FileUpload in an UpdatePanel</legend>
       First, enter a file name to upload your file to:
       <asp:TextBox ID="FileName" runat="server" />
       <asp:Button ID="CheckButton" Text="Check" runat="server" OnClick="CheckButton_Click" />
       <br />
       Then, browse and find the file to upload:
       <asp:FileUpload id="FileUpload1"                
           runat="server">
       </asp:FileUpload>
       <br />
       <asp:Button id="UploadButton"
           Text="Upload file"
           OnClick="UploadButton_Click"
           runat="server">
       </asp:Button>   
       <br />
       <asp:Label id="UploadStatusLabel"
           runat="server" style="color:red;">
       </asp:Label>          
    </fieldset>
    </ContentTemplate>
    <Triggers>
    <asp:PostBackTrigger ControlID="UploadButton" />
    </Triggers>
    </asp:UpdatePanel>
    </div>
    </form>
</body>
</html>

ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.ko/dv_aspnetconfig/html/4174fd13-a9c4-4ff6-baa5-3f7d7fc73ef3.htm

이 항목에서는 HttpModulesSection 클래스 및 관련된 형식을 사용하여 웹 응용 프로그램 구성의 httpModules 요소를 프로그래밍 방식으로 구성하는 방법을 설명합니다.

HTTP 모듈은 IHttpModule 인터페이스를 구현하고 응용 프로그램 이벤트를 전달하여 요청 처리를 제공하는 형식입니다. HTTP 모듈에 대한 자세한 내용은 HTTP 모듈 소개를 참조하십시오.

다음 표에는 ASP.NET 웹 응용 프로그램에서 HTTP 모듈을 프로그래밍 방식으로 추가 및 제거하는 예제 HTTP 모듈 코드와 예제 구성이 포함된 관련 항목이 나와 있습니다. 이 예제에 있는 HTTP 모듈은 RequestTimeIntervalModule.dll이라는 단순한 라이브러리 응용 프로그램입니다. RequestTimeIntervalModule 클래스의 멤버는 웹 요청 시작과 끝 사이의 시간 간격을 계산하고 보안 주체의 ID를 가져온 다음 마지막으로 정보를 응용 프로그램의 웹 페이지에 표시합니다.

방법: 사용자 지정 HTTP 모듈 만들기

ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.ko/dv_aspnetcon/html/7787d5be-40a4-4072-9075-c2b767428453.htm

사용자 지정 HTTP 모듈 클래스를 만들려면

public class HelloWorldModule : IHttpModule
{
    public HelloWorldModule()
    {
    }

    public String ModuleName
    {
        get { return "HelloWorldModule"; }
    }

    // In the Init function, register for HttpApplication 
    // events by adding your handlers.
    public void Init(HttpApplication application)
    {
        application.BeginRequest += 
            (new EventHandler(this.Application_BeginRequest));
        application.EndRequest += 
            (new EventHandler(this.Application_EndRequest));
    }

    private void Application_BeginRequest(Object source, 
         EventArgs e)
    {
    // Create HttpApplication and HttpContext objects to access
    // request and response properties.
        HttpApplication application = (HttpApplication)source;
        HttpContext context = application.Context;
        context.Response.Write("<h1><font color=red>
            HelloWorldModule: Beginning of Request
            </font></h1><hr>");
    }

    private void Application_EndRequest(Object source, EventArgs e)
    {
        HttpApplication application = (HttpApplication)source;
        HttpContext context = application.Context;
        context.Response.Write("<hr><h1><font color=red>
            HelloWorldModule: End of Request</font></h1>");
    }

    public void Dispose()
    {
    }
}

HTTP 모듈 등록

HelloWorldModule 클래스를 만든 후에는 Web.config 파일에서 항목을 만들어 모듈을 등록할 수 있습니다.

1.웹 사이트에 Web.config 파일이 없는 경우 사이트의 루트에 해당 파일을 만듭니다.

2.아래에 강조 표시된 코드를 Web.config 파일에 추가합니다

<configuration>
    <system.web>
        <httpModules>
           <add name="HelloWorldModule" type="HelloWorldModule"/>
        </httpModules>
    </system.web>
</configuration>

urlMappings 요소(ASP.NET 설정 스키마)

ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETDEVFX.v20.ko/dv_ASPNETgenref/html/96044a97-0541-4dfe-bfde-75ceee03b6ce.htm

<urlMappings enabled="true">
  <clear />
  <add url="~/Home.aspx" mappedUrl="~/Default.aspx?tab=home" />
  <remove url="~/Home2.aspx" />
</urlMappings>

+ Recent posts