336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

1. 개요

페이지 전체를 다시 요청 하지 않고, 클라이언트 스크립트를 이용하여 서버의 데이터를 가져와 이미 생성된 페이지에 사용 하는 방법

2. 특징

● 전체 포스트백 주기(postback cycle)을 모두 거치지 않고 페이지의 값을 변경 할 수 있음

● 필요한 부분만 갱신 하므로, 페이지의 깜빡임과 재배치 작업을 거치지 않음

3. Postback vs Callback

3.1 Postback

폼의 HTTP POST 요청이 전송 되면, 그 요청은 IPostbackEventHandler 인터페이스에서 처리된다.

즉, 페이지를 초기화 하고, 뷰 상태를 로드 하며, 데이터를 처리한 다음, 포스트 백 이벤트를 동작하고, 페이지를 브라우저 상에서 볼 수 있도록 랜더링 한다.

이 과정에서 브라우저를 페이지를 다시 로드 하고, 깜박임과 동시에 페이지를 재배치한다.

3.2 Callback

폼의 Click 이벤트가 발생 되면, 이벤트 처리기(자바스크립트 함수)에 전달하여 비동기 요청을 서버에 전송한다.

ICallbackEventHandler 인터페이스는 앞서 포스트백을 처리 하기 위해서 IPostbackEventHandler 인터페이스처럼 해당 비동기 요청을 HTTP 파이프라인에 전달한다.

하지만 여기서 일반적인 이벤트 처리와는 다르게 몇가지 단계를 제외 하고 있다.

이벤트 정보가 로드되면 그 결과는 스크립트 콜백 개체로 반환되고, 클라이언트 스크립트에서는 페이지를 다시 갱신하지 않고도 기존 페이지에 정보를 반영 할 수 있게 된다.


4. 콜백 사용하기

예제를 통해 ASP.NET 2.0에서 콜백 이벤트를 어떻게 사용 하는지 알아 보도록 하자.

먼저 아래와 같은 화면 구성을 하도록 한다.


시나리오는 다음과 같다.

텍스트 박스에 고객의 고객코드를 넣고 버튼을 클릭 하면, 미리 정의된 클라이언트 스크립트가 호출 되게 된다.

클라이언트 스크립트에서는 서버 쪽에 CallbackEvent를 호출하고, 서버에서 처리가 완료되어 콜백 객체를 클라이언트가 받아 이를 처리 하도록 하는 것이다.

그럼 코드를 보도록하자.

4.1 .aspx page

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

<!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>
    <script type="text/javascript">
        function GetCustomer()
        {
            var customerCode = document.forms[0].TextBox1.value;
            UseCallback(customerCode, "");
        }
        function GetCustDetailsFromServer(result, context)
        {
            var i = result.split("|");
            document.getElementById('customerID').innerHTML    = i[0];
            document.getElementById('companyName').innerHTML   = i[1];
            document.getElementById('contactName').innerHTML   = i[2];
            document.getElementById('contactTitle').innerHTML  = i[3];
            document.getElementById('address').innerHTML       = i[4];
            document.getElementById('city').innerHTML          = i[5];
            document.getElementById('region').innerHTML        = i[6];
            document.getElementById('postalCode').innerHTML    = i[7];
            document.getElementById('country').innerHTML       = i[8];
            document.getElementById('phone').innerHTML         = i[9];
            document.getElementById('fax').innerHTML           = i[10];
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> 
        <input id="Button1" type="button" value="고객의 상세정보 보기" onclick="GetCustomer()" /><br />
        <br />
        <table>
            <tr>
                <td style="width: 100px">
                    고객ID</td>
                <td style="width: 100px"><span id="customerID" />
                </td>
            </tr>
            <tr>
                <td style="width: 100px">
                    회사명</td>
                <td style="width: 100px"><span id="companyName" />
                </td>
            </tr>
            <tr>
                <td style="width: 100px">
                    연락처</td>
                <td style="width: 100px"><span id="contactName" />
                </td>
            </tr>
            <tr>
                <td style="width: 100px">
                    계약명</td>
                <td style="width: 100px"><span id="contactTitle" />
                </td>
            </tr>
            <tr>
                <td style="width: 100px">
                    주소</td>
                <td style="width: 100px"><span id="address" />
                </td>
            </tr>
            <tr>
                <td style="width: 100px">
                    도시</td>
                <td style="width: 100px"><span id="city" />
                </td>
            </tr>
            <tr>
                <td style="width: 100px">
                    지역</td>
                <td style="width: 100px"><span id="region" /> 
                </td>
            </tr>
            <tr>
                <td style="width: 100px">
                    우편번호</td>
                <td style="width: 100px"><span id="postalCode" />
                </td>
            </tr>
            <tr>
                <td style="width: 100px">
                    국가</td>
                <td style="width: 100px"><span id="country" />
                </td>
            </tr>
            <tr>
                <td style="width: 100px">
                    전화번호</td>
                <td style="width: 100px"><span id="phone" />
                </td>
            </tr>
            <tr>
                <td style="width: 100px">
                    팩스</td>
                <td style="width: 100px"><span id="fax" />
                </td>
            </tr>
        </table>
    </div>
    </form>
</body>
</html>

4.2 C#(Code behind)

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;
using System.Data.SqlClient;

public partial class Callback2 : System.Web.UI.Page, ICallbackEventHandler
{
    private string _callbackResult = null;
    protected void Page_Load(object sender, EventArgs e)
    {
        if(!Page.IsPostBack)
        {
            string cbReference = Page.ClientScript.GetCallbackEventReference( this, "arg", "GetCustDetailsFromServer", "context");
            string cbScript = "function UseCallback(arg, context)" + "{" + cbReference + "; }";
            Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "UseCallback", cbScript, true);
        }
    }

    #region ICallbackEventHandler 멤버

    public string  GetCallbackResult()
    {
        return _callbackResult;
 	    //throw new Exception("The method or operation is not implemented.");
    }

    public void  RaiseCallbackEvent(string eventArgument)
    {
        SqlConnection conn = new SqlConnection("Data Source=10.1.14.114;Initial Catalog=Northwind;User ID=sa;Password=1234;");
        SqlCommand cmd = new SqlCommand("Select * From Customers Where CustomerID = '" + eventArgument + "' ", conn);
        conn.Open();
        SqlDataReader MyReader;
        MyReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);

        string[] MyValues = new string[11];
        while(MyReader.Read())
        {
            MyValues[0]  = MyReader["CustomerID"].ToString();
            MyValues[1]  = MyReader["CompanyName"].ToString();
            MyValues[2]  = MyReader["ContactName"].ToString();
            MyValues[3]  = MyReader["ContactTitle"].ToString();
            MyValues[4]  = MyReader["Address"].ToString();
            MyValues[5]  = MyReader["City"].ToString();
            MyValues[6]  = MyReader["Region"].ToString();
            MyValues[7]  = MyReader["PostalCode"].ToString();
            MyValues[8]  = MyReader["Country"].ToString();
            MyValues[9]  = MyReader["Phone"].ToString();
            MyValues[10] = MyReader["Fax"].ToString();
        }
        _callbackResult = String.Join("|", MyValues);

    }

    #endregion
}

4.3 소스 분석

4.3.1 Server Side

Page 로드 시의 클라이언트 스크립트를 등록 하는 부분이다.

string cbReference = Page.ClientScript.GetCallbackEventReference( this, "arg", "GetCustDetailsFromServer", "context");
string cbScript = "function UseCallback(arg, context)" + "{" + cbReference + "; }";
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "UseCallback", cbScript, true);

이 문맥은 거꾸로 보는게 오히려 편한 듯 하다.

3번째 줄의 문맥을 살펴보면 [클라이언트 -> 서버 CallbackEvent]를 호출 할 함수를 지정 하는 부분인데, 2번째 인자인 "UseCallback" 함수가 이 역할을 하게 된다.

그리고 2번째 줄은 [클라이언트 -> 서버 CallbackEvent]를 호출 하고, [처리된 서버 데이터 -> 클라이언트]로 처리 하는 일련의 내용들을 정의 하는 부분이다.

마지막으로 1번째 줄의 문맥의 내용은 서버측에서 처리된 콜백 객체를 받을 클라이언트 측 처리 함수를 지정 하는 부분인데, 3번째 인자의 값이 클라이언트 처리 함수의 이름이 된다. 이 코드에서는 GetCusDetailsFromServer가 되겠다.

public string  GetCallbackResult()
    {
        return _callbackResult;
 	    //throw new Exception("The method or operation is not implemented.");
    }

    public void  RaiseCallbackEvent(string eventArgument)
    {
        SqlConnection conn = new SqlConnection("Data Source=10.1.14.114;Initial Catalog=Northwind;User ID=sa;Password=1234;");
        SqlCommand cmd = new SqlCommand("Select * From Customers Where CustomerID = '" + eventArgument + "' ", conn);
        conn.Open();
        SqlDataReader MyReader;
        MyReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);

        string[] MyValues = new string[11];
        while(MyReader.Read())
        {
            MyValues[0]  = MyReader["CustomerID"].ToString();
            MyValues[1]  = MyReader["CompanyName"].ToString();
            MyValues[2]  = MyReader["ContactName"].ToString();
            MyValues[3]  = MyReader["ContactTitle"].ToString();
            MyValues[4]  = MyReader["Address"].ToString();
            MyValues[5]  = MyReader["City"].ToString();
            MyValues[6]  = MyReader["Region"].ToString();
            MyValues[7]  = MyReader["PostalCode"].ToString();
            MyValues[8]  = MyReader["Country"].ToString();
            MyValues[9]  = MyReader["Phone"].ToString();
            MyValues[10] = MyReader["Fax"].ToString();
        }
        _callbackResult = String.Join("|", MyValues);

    }

ICallbackEventHandler 인터페이스를 상속 받게 되면 GetCallbackResult, RaiseCallbackEvent 함수를 구현 해야 되는데, RaiseCallbackEvent 함수는 클라이언트 측에서 CallbackEvent를 호출 하면 불리는 함수가 된다. 보통 RaiseCallbackEvent 함수는 클라이언트의 요청을 처리하는 기능으로 사용 되게 된다.

그리고 GetCallbackResult는 CallbackEvent가 처리된 객체를 클라이언트에 반환 할 때 불리는 함수이다.

4.3.2 Client Side

             버튼의 onclick 이벤트에 GetCustomer 함수를 호출하고 있다.

function GetCustomer()
{
    var customerCode = document.forms[0].TextBox1.value;
    UseCallback(customerCode, "");
}
function GetCustDetailsFromServer(result, context)
{
    var i = result.split("|");
    document.getElementById('customerID').innerHTML    = i[0];
    document.getElementById('companyName').innerHTML   = i[1];
    document.getElementById('contactName').innerHTML   = i[2];
    document.getElementById('contactTitle').innerHTML  = i[3];
    document.getElementById('address').innerHTML       = i[4];
    document.getElementById('city').innerHTML          = i[5];
    document.getElementById('region').innerHTML        = i[6];
    document.getElementById('postalCode').innerHTML    = i[7];
    document.getElementById('country').innerHTML       = i[8];
    document.getElementById('phone').innerHTML         = i[9];
    document.getElementById('fax').innerHTML           = i[10];
}

GetCustomer 함수를 호출 하게 되면, 텍스트 박스의 데이터를 가져와 서버쪽 CallbackEvent를 호출 할 함수를 UseCallback 함수를 호출 하게 된다.

이 함수는 클라이언트 콜백 처리기를 생성하여, 서버 측 콜백 이벤트 함수를 호출 한다.

4.4 이벤트 처리 정리

위의 내용을 바탕으로 콜백 이벤트의 처리 절차를 정리 해 보자.

4.4.1 등록

Page Load에서 다음의 함수를 지정한다.

  • UseCallback : 서버 CallbackEvent 호출 할 클라이언트 측 함수
  • GetCustDetailsFromServer : 서버 CallbackEvent 반환 객체를 처리 클라이언트 함수

4.4.2 처리

버튼 이벤트가 발생되면 다음과 같이 수행 된다.

  1. GetCustomer : 클라이언트
  2. UseCallback : 클라이언트
  3. RaiseCallbackEvent : 서버
  4. GetCallbackResult : 서버
  5. GetCustDetailsFromServer : 클라이언트

5. 참고

http://resources.esri.com/help/9.3/arcgisserver/adf/dotnet/developer/ADF/ajax_aspnet.htm
Professional ASP.NET 2.0

+ Recent posts