ASP.NET AJAX UpdatePanel 트리거 이해

작성 자: Scott Cate

Visual Studio의 태그 편집기에서 작업하는 경우 IntelliSense에서 UpdatePanel 컨트롤의 두 자식 요소가 있음을 알 수 있습니다. 그 중 하나는 요소가 있는 UpdatePanel 컨트롤의 부분 렌더링을 트리거하는 페이지의 컨트롤(또는 사용 중인 경우 사용자 컨트롤)을 지정하는 Triggers 요소입니다.

소개

Microsoft의 ASP.NET 기술은 개체 지향적이고 이벤트 기반 프로그래밍 모델을 제공하며 컴파일된 코드의 이점과 결합합니다. 그러나 서버 쪽 처리 모델에는 기술에 내재된 몇 가지 단점이 있으며, 그 중 상당수는 Microsoft ASP.NET 3.5 AJAX 확장에 포함된 새로운 기능으로 해결할 수 있습니다. 이러한 확장을 사용하면 전체 페이지 새로 고침 없이 페이지의 부분 렌더링, 클라이언트 스크립트를 통해 웹 서비스에 액세스할 수 있는 기능(ASP.NET 프로파일링 API 포함) 및 ASP.NET 서버 쪽 컨트롤 집합에 표시된 많은 제어 체계를 미러 수 있도록 설계된 광범위한 클라이언트 쪽 API 등 다양한 새로운 클라이언트 기능을 사용할 수 있습니다.

이 백서에서는 ASP.NET AJAX UpdatePanel 구성 요소의 XML 트리거 기능을 살펴봅니다. XML 트리거는 특정 UpdatePanel 컨트롤에 대해 부분 렌더링을 일으킬 수 있는 구성 요소를 세부적으로 제어합니다.

이 백서는 .NET Framework 3.5 및 Visual Studio 2008의 베타 2 릴리스를 기반으로 합니다. 이전에는 ASP.NET 2.0을 대상으로 하는 추가 기능 어셈블리였던 ASP.NET AJAX 확장이 이제 .NET Framework 기본 클래스 라이브러리에 통합됩니다. 또한 이 백서는 Visual Web Developer Express가 아닌 Visual Studio 2008로 작업한다고 가정하고 Visual Studio의 사용자 인터페이스에 따라 연습을 제공합니다(코드 목록은 개발 환경에 관계없이 완전히 호환됨).

트리거

기본적으로 지정된 UpdatePanel에 대한 트리거에는 속성이 true로 설정된 TextBox 컨트롤을 포함하여 포스트백을 호출하는 모든 자식 컨트롤이 AutoPostBack 자동으로 포함됩니다. 그러나 태그를 사용하여 트리거를 선언적으로 포함할 수도 있습니다. UpdatePanel 컨트롤 선언의 섹션 내에서 <triggers> 수행됩니다. 컬렉션 속성을 통해 Triggers 트리거에 액세스할 수 있지만 이벤트 내에서 Page_Load 페이지에 대한 ScriptManager 개체의 메서드를 사용하여 RegisterAsyncPostBackControl(Control) 런타임에 부분 렌더링 트리거를 등록하는 것이 좋습니다(디자인 타임에 컨트롤을 사용할 수 없는 경우 instance). Pages는 상태 비 상태이므로 이러한 컨트롤을 만들 때마다 다시 등록해야 합니다.

속성을 false로 설정하여 자동 자식 트리거 포함을 사용하지 않도록 설정할 ChildrenAsTriggers 수도 있습니다(포스트백을 만드는 자식 컨트롤이 부분 렌더링을 자동으로 트리거하지 않도록 함). 이를 통해 페이지 렌더링을 호출할 수 있는 특정 컨트롤을 할당할 수 있는 유연성을 극대화할 수 있으며, 개발자가 발생할 수 있는 이벤트를 처리하는 대신 이벤트에 응답하도록 옵트인하는 것이 좋습니다.

UpdatePanel 컨트롤이 중첩될 때 UpdateMode가 조건부로 설정된 경우 자식 UpdatePanel이 트리거되지만 부모가 트리거되지 않으면 자식 UpdatePanel만 새로 고쳐집니다. 그러나 부모 UpdatePanel이 새로 고쳐지면 자식 UpdatePanel도 새로 고쳐집니다.

<Triggers> 요소

Visual Studio의 태그 편집기에서 작업하는 경우(IntelliSense에서) 컨트롤의 UpdatePanel 두 자식 요소가 있음을 알 수 있습니다. 가장 자주 표시되는 요소는 기본적으로 업데이트 패널(부분 렌더링을 사용하도록 설정하는 콘텐츠)에서 보유할 콘텐츠를 캡슐화하는 요소 <ContentTemplate> 입니다. 다른 요소는 Triggers> 요소가 <Triggers> 있는 UpdatePanel 컨트롤의 부분 렌더링을 트리거하는 페이지의 컨트롤(또는 사용자 컨트롤을 사용하는 경우)을 지정하는 <요소입니다.

요소에는 <Triggers> 각각 두 개의 자식 노드( 및 <asp:PostBackTrigger>)가 포함될 수 있습니다<asp:AsyncPostBackTrigger>. 두 특성 ControlID 모두 및 를 EventName허용하며 현재 캡슐화 단위 내에서 Control을 지정할 수 있습니다(instance 경우 UpdatePanel 컨트롤이 웹 사용자 컨트롤 내에 있는 경우 사용자 컨트롤이 상주할 페이지의 컨트롤을 참조하려고 시도해서는 안 됩니다).

요소는 <asp:AsyncPostBackTrigger> 이 트리거가 자식인 UpdatePanel뿐만 아니라 캡슐화 단위의 UpdatePanel 컨트롤의 자식으로 존재하는 Control의 모든 이벤트를 대상으로 지정할 수 있다는 점에서 특히 유용합니다. 따라서 부분 페이지 업데이트를 트리거하기 위해 모든 컨트롤을 만들 수 있습니다.

마찬가지로 요소는 <asp:PostBackTrigger> 부분 페이지 렌더링을 트리거하는 데 사용할 수 있지만 서버에 대한 전체 왕복이 필요한 요소입니다. 이 트리거 요소는 컨트롤이 일반적으로 부분 페이지 렌더링을 트리거할 때 전체 페이지 렌더링을 강제하는 데 사용할 수도 있습니다(instance 경우 UpdatePanel 컨트롤의 요소에 <ContentTemplate> 컨트롤이 있는 경우Button). 다시 PostBackTrigger 요소는 현재 캡슐화 단위에서 UpdatePanel 컨트롤의 자식인 모든 컨트롤을 지정할 수 있습니다.

<Triggers> 요소 참조

태그 하위 항목:

Tag 설명
<asp:AsyncPostBackTrigger> 이 트리거 참조를 포함하는 UpdatePanel에 대한 부분 페이지 업데이트를 발생시키는 컨트롤 및 이벤트를 지정합니다.
<asp:PostBackTrigger> 전체 페이지 업데이트(전체 페이지 새로 고침)를 발생시키는 컨트롤 및 이벤트를 지정합니다. 이 태그는 컨트롤이 부분 렌더링을 트리거할 때 전체 새로 고침을 강제로 적용하는 데 사용할 수 있습니다.

연습: 교차 UpdatePanel 트리거

  1. 부분 렌더링을 사용하도록 ScriptManager 개체가 설정된 새 ASP.NET 페이지를 만듭니다. 이 페이지에 두 개의 UpdatePanels를 추가합니다. 첫 번째 페이지에는 레이블 컨트롤( Label1 ) 및 단추 컨트롤 2개(Button1 및 Button2 )가 포함됩니다. Button1은 모두 업데이트하려면 클릭이라고 말하고 Button2는 이 항목을 업데이트하려면 클릭 또는 해당 줄을 따라 무언가를 말해야 합니다. 두 번째 UpdatePanel에서 Label 컨트롤(Label2)만 포함하지만 ForeColor 속성을 기본값 이외의 값으로 설정하여 구분합니다.
  2. 두 UpdatePanel 태그의 UpdateMode 속성을 조건부로 설정합니다.

목록 1: default.aspx에 대한 태그:



<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!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>Untitled Page</title>
   </head>
   <body>
      <form id="form1" runat="server">
         <asp:ScriptManager EnablePartialRendering="true"
            ID="ScriptManager1" runat="server"></asp:ScriptManager>
         <div>
            <asp:UpdatePanel ID="UpdatePanel1" runat="server"
               UpdateMode="Conditional">
               <ContentTemplate>
                  <asp:Label ID="Label1" runat="server" />
                  <br />
                  <asp:Button ID="Button1" runat="server"
                     Text="Update Both Panels" OnClick="Button1_Click" />
                  <asp:Button ID="Button2" runat="server"
                     Text="Update This Panel" OnClick="Button2_Click" />
               </ContentTemplate>
            </asp:UpdatePanel>
            <asp:UpdatePanel ID="UpdatePanel2" runat="server"
               UpdateMode="Conditional">
               <ContentTemplate>
                  <asp:Label ID="Label2" runat="server" ForeColor="red" />
               </ContentTemplate>
               <Triggers>
                  <asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
               </Triggers>
            </asp:UpdatePanel>
         </div>
      </form>
   </body>
</html>

  1. Button1에 대한 Click 이벤트 처리기에서 Label1.Text 및 Label2.Text를 시간 종속 항목(예: DateTime.Now.ToLongTimeString())으로 설정합니다. Button2에 대한 Click 이벤트 처리기의 경우 Label1.Text만 시간 종속 값으로 설정합니다.

목록 2: default.aspx.cs의 Codebehind(트리밍됨):

public partial class _Default : System.Web.UI.Page
{
    protected void Button1_Click(object sender, EventArgs e)
    {
        Label1.Text = DateTime.Now.ToLongTimeString();
        Label2.Text = DateTime.Now.ToLongTimeString();
    }
    protected void Button2_Click(object sender, EventArgs e)
    {
        Label1.Text = DateTime.Now.ToLongTimeString();
    }
}
  1. F5를 눌러 프로젝트를 빌드하고 실행합니다. 두 패널 업데이트를 클릭하면 두 레이블 모두 텍스트가 변경됩니다. 그러나 이 패널 업데이트를 클릭하면 Label1만 업데이트됩니다.

두 패널 모두 업데이트라는 첫 번째 단추와 이 패널 업데이트가 표시된 두 번째 단추를 보여 주는 스크린샷.

(전체 크기 이미지를 보려면 클릭)

내부

방금 생성한 예제를 활용하여 AJAX가 수행하는 ASP.NET 및 UpdatePanel 패널 간 트리거의 작동 방식을 살펴볼 수 있습니다. 이를 위해 생성된 페이지 원본 HTML과 FireBug라는 Mozilla Firefox 확장을 사용하여 AJAX 포스트백을 쉽게 검사할 수 있습니다. Lutz Roeder의 .NET 리플렉터 도구도 사용합니다. 이러한 두 도구는 모두 온라인에서 자유롭게 사용할 수 있으며 인터넷 검색을 통해 찾을 수 있습니다.

페이지 소스 코드를 검사하면 일반 코드에서 거의 아무것도 표시되지 않습니다. UpdatePanel 컨트롤은 컨테이너로 <div> 렌더링되며 에서 제공하는 스크립트 리소스가 포함되는 <asp:ScriptManager>것을 볼 수 있습니다. AJAX 클라이언트 스크립트 라이브러리 내부인 PageRequestManager에 대한 몇 가지 새로운 AJAX 관련 호출도 있습니다. 마지막으로 두 개의 UpdatePanel 컨테이너가 표시됩니다. 하나는 두 개의 컨트롤이 컨테이너로 <span> 렌더링된 렌더링된 <input> 단추 <asp:Label> 가 있는 컨테이너입니다. FireBug에서 DOM 트리를 검사하는 경우 레이블이 흐리게 표시되어 표시되는 콘텐츠를 생성하지 않음을 나타냅니다.

이 패널 업데이트 단추를 클릭하면 위쪽 UpdatePanel이 현재 서버 시간으로 업데이트됩니다. FireBug에서 요청을 검사할 수 있도록 콘솔 탭을 선택합니다. 먼저 POST 요청 매개 변수를 검사합니다.

콘솔이 선택된 Firebug 대화 상자를 보여 주는 스크린샷

(전체 크기 이미지를 보려면 클릭)

UpdatePanel은 컨트롤의 ScriptManager1 매개 변수를 Button1 통해 발생한 제어 트리를 서버 쪽 AJAX 코드에 UpdatePanel1 정확하게 표시했습니다. 이제 두 패널 업데이트 단추를 클릭합니다. 그런 다음 응답을 검사하면 문자열에 파이프로 구분된 일련의 변수가 설정됩니다. 특히 상위 UpdatePanel, UpdatePanel1에는 브라우저로 전송된 HTML 전체가 있습니다. AJAX 클라이언트 스크립트 라이브러리는 UpdatePanel의 원래 HTML 콘텐츠를 속성을 통해 .innerHTML 새 콘텐츠로 대체하므로 서버는 서버에서 변경된 콘텐츠를 HTML로 보냅니다.

이제 두 패널 업데이트 단추를 클릭하고 서버의 결과를 검사합니다. 결과는 매우 유사합니다. 두 UpdatePanels 모두 서버에서 새 HTML을 받습니다. 이전 콜백과 마찬가지로 추가 페이지 상태가 전송됩니다.

알 수 있듯이 AJAX 포스트백을 수행하는 데 특수 코드가 활용되지 않으므로 AJAX 클라이언트 스크립트 라이브러리는 추가 코드 없이 양식 포스트백을 가로챌 수 있습니다. 서버 컨트롤은 양식을 자동으로 제출하지 않도록 JavaScript를 자동으로 활용합니다. ASP.NET 자동 스크립트 리소스 포함, PostBackOptions 클래스 및 ClientScriptManager 클래스를 통해 이미 이미 구현된 양식 유효성 검사 및 상태에 대한 코드를 자동으로 삽입합니다.

instance 경우 CheckBox 컨트롤을 고려합니다. .NET 리플렉터에서 클래스 디스어셈블리를 검사합니다. 이렇게 하려면 System.Web 어셈블리가 열려 있는지 확인하고 클래스로 이동하여 System.Web.UI.WebControls.CheckBox 메서드를 RenderInputTag 엽니다. 속성을 확인하는 조건을 찾습니다.AutoPostBack

클릭 등호에서 로 시작하는 코드를 보여 주는 스크린샷

(전체 크기 이미지를 보려면 클릭)

자동 포스트백이 컨트롤에서 CheckBox 사용하도록 설정된 경우(AutoPostBack 속성이 true인 경우) 결과 <input> 태그는 특성의 ASP.NET 이벤트 처리 스크립트 onclick 를 사용하여 렌더링됩니다. 양식의 제출을 가로차면 ASP.NET AJAX를 비침입적으로 페이지에 삽입할 수 있으므로 부정확한 문자열 대체를 활용하여 발생할 수 있는 잠재적인 호환성이 손상되는 변경을 방지할 수 있습니다. 또한 이를 통해 모든 사용자 지정 ASP.NET 컨트롤이 UpdatePanel 컨테이너 내에서 사용할 수 있도록 추가 코드 없이 ASP.NET AJAX의 기능을 활용할 수 있습니다.

<triggers> 기능은 _updateControls PageRequestManager 호출에서 초기화된 값에 해당합니다(ASP.NET AJAX 클라이언트 스크립트 라이브러리는 밑줄로 시작하는 메서드, 이벤트 및 필드 이름이 내부로 표시되고 라이브러리 자체 외부에서 사용할 수 없다는 규칙을 활용합니다.) 이를 통해 AJAX 포스트백을 유발하기 위한 컨트롤을 관찰할 수 있습니다.

예를 들어 한 컨트롤을 UpdatePanels 외부에 두고 한 컨트롤을 UpdatePanel 내에 두는 두 개의 추가 컨트롤을 페이지에 추가해 보겠습니다. 위쪽 UpdatePanel 내에 CheckBox 컨트롤을 추가하고 목록 내에 여러 색이 정의된 DropDownList를 삭제합니다. 새 태그는 다음과 같습니다.

목록 3: 새 태그

<%@ Page Language="C#" AutoEventWireup="true"
 CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!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 id="Head1" runat="server">
 <title>Untitled Page</title>
 </head>
 <body>
 <form id="form1" runat="server">
 <asp:ScriptManager EnablePartialRendering="true"
 ID="ScriptManager1" runat="server"></asp:ScriptManager>
 <div>
 <asp:UpdatePanel ID="UpdatePanel1" runat="server"
 UpdateMode="Conditional">
 <ContentTemplate>
 <asp:Label ID="Label1" runat="server" /><br />
 <asp:Button ID="Button1" runat="server"
 Text="Update Both Panels" OnClick="Button1_Click" />
 <asp:Button ID="Button2" runat="server"
 Text="Update This Panel" OnClick="Button2_Click" />
 <asp:CheckBox ID="cbDate" runat="server"
 Text="Include Date" AutoPostBack="false"
 OnCheckedChanged="cbDate_CheckedChanged" />
 </ContentTemplate>
 </asp:UpdatePanel>
 <asp:UpdatePanel ID="UpdatePanel2" runat="server"
 UpdateMode="Conditional">
 <ContentTemplate>
 <asp:Label ID="Label2" runat="server"
 ForeColor="red" />
 </ContentTemplate>
 <Triggers>
 <asp:AsyncPostBackTrigger ControlID="Button1" 
 EventName="Click" />
 <asp:AsyncPostBackTrigger ControlID="ddlColor" 
 EventName="SelectedIndexChanged" />
 </Triggers>
 </asp:UpdatePanel>
 <asp:DropDownList ID="ddlColor" runat="server"
 AutoPostBack="true"
 OnSelectedIndexChanged="ddlColor_SelectedIndexChanged">
 <asp:ListItem Selected="true" Value="Red" />
 <asp:ListItem Value="Blue" />
 <asp:ListItem Value="Green" />
 </asp:DropDownList>
 </div>
 </form>
 </body>
</html>

새로운 코드 숨김은 다음과 같습니다.

목록 4: Codebehind

public partial class _Default : System.Web.UI.Page
{
    protected void Button1_Click(object sender, EventArgs e)
    {
        if (cbDate.Checked)
        {
            Label1.Text = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss");
            Label2.Text = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss");
        }
        else
        {
            Label1.Text = DateTime.Now.ToLongTimeString();
            Label2.Text = DateTime.Now.ToLongTimeString();
        }
    }
    protected void Button2_Click(object sender, EventArgs e)
    {
        if (cbDate.Checked)
        {
            Label1.Text = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss");
        }
        else
        {
            Label1.Text = DateTime.Now.ToLongTimeString();
        }
    }
    protected void cbDate_CheckedChanged(object sender, EventArgs e)
    {
        cbDate.Font.Bold = cbDate.Checked;
    }
    protected void ddlColor_SelectedIndexChanged(object sender, EventArgs e)
    {
        Color c = Color.FromName(ddlColor.SelectedValue);
        Label2.ForeColor = c;
    }
}

이 페이지의 개념은 드롭다운 목록에서 세 가지 색 중 하나를 선택하여 두 번째 레이블을 표시하고, 검사 상자가 굵게 표시되는지 여부와 레이블에 날짜와 시간을 표시하는지 여부를 모두 결정한다는 것입니다. 검사 상자는 AJAX 업데이트를 발생시키지 않아야 하지만 드롭다운 목록은 UpdatePanel 내에 포함되지 않더라도 해야 합니다.

제목 없는 페이지라는 웹 브라우저와 단추 아래에 두 패널 업데이트라는 파란색이 선택된 드롭다운 목록을 보여 주는 스크린샷.

(전체 크기 이미지를 보려면 클릭)

위의 스크린샷에서 알 수 있듯이 클릭할 가장 최근 단추는 오른쪽 단추인 이 패널 업데이트입니다. 이 단추는 맨 아래 시간과 관계없이 상위 시간을 업데이트했습니다. 날짜가 아래쪽 레이블에 표시되므로 클릭 사이에 날짜도 꺼져 있습니다. 마지막으로 관심 있는 것은 아래쪽 레이블의 색입니다. 레이블의 텍스트보다 최근에 업데이트되었습니다. 이는 컨트롤 상태가 중요하다는 것을 보여 줍니다. 사용자는 AJAX 포스트백을 통해 보존될 것으로 예상합니다. 그러나 시간이 업데이트되지 않았습니다. 서버에서 컨트롤을 다시 렌더링할 때 ASP.NET 런타임에서 해석되는 페이지의 __VIEWSTATE 필드의 지속성을 통해 시간이 자동으로 다시 채워질 수 있습니다. ASP.NET AJAX 서버 코드는 컨트롤이 상태를 변경하는 메서드를 인식하지 못합니다. 보기 상태에서 다시 채우면 적절한 이벤트를 실행하기만 하면 됩니다.

그러나 Page_Load 이벤트 내에서 시간을 초기화했다면 시간이 올바르게 증가했을 것이라는 점을 지적해야 합니다. 따라서 개발자는 적절한 이벤트 처리기 중에 적절한 코드가 실행되고 있는지 주의해야 하며 제어 이벤트 처리기가 적절한 경우 Page_Load 사용하지 않도록 해야 합니다.

요약

ASP.NET AJAX 확장 UpdatePanel 컨트롤은 다양하며 업데이트해야 하는 컨트롤 이벤트를 식별하는 다양한 메서드를 활용할 수 있습니다. 자식 컨트롤에 의해 자동으로 업데이트되도록 지원하지만 페이지의 다른 곳에서 컨트롤 이벤트에 응답할 수도 있습니다.

서버 처리 부하의 가능성을 줄이려면 UpdatePanel의 속성을 로 설정하고 false기본적으로 포함되지 않고 이벤트를 옵트인(opt-into)하는 것이 좋습니다ChildrenAsTriggers. 또한 유효성 검사 및 입력 필드 변경을 포함하여 불필요한 이벤트가 잠재적으로 원치 않는 영향을 주지 않도록 방지합니다. 페이지가 사용자에게 투명하게 업데이트되므로 이러한 유형의 버그를 격리하기 어려울 수 있으므로 원인은 즉시 명확하지 않을 수 있습니다.

가로채기 후 ASP.NET AJAX 양식의 내부 작동을 검사하여 ASP.NET 이미 제공한 프레임워크를 활용하는지 확인할 수 있었습니다. 이렇게 하면 동일한 프레임워크를 사용하여 디자인된 컨트롤과의 최대 호환성을 유지하고 페이지에 대해 작성된 추가 JavaScript를 최소한으로 침입합니다.

사용자 정보

Rob Paveza는 AZ 템피의 선도적인 대화형 마케팅 회사인 Terralever(www.terralever.com)의 선임 .NET 애플리케이션 개발자입니다. 그는 에 robpaveza@gmail.com도달 할 수 있으며 그의 블로그는 에 http://geekswithblogs.net/robp/있습니다.

Scott Cate은 1997년부터 Microsoft 웹 기술과 함께 일해 왔으며 myKB.com(www.myKB.com)의 사장으로 기술 자료 소프트웨어 솔루션에 중점을 둔 ASP.NET 기반 애플리케이션을 작성하는 일을 전문으로 합니다. Scott은 이메일 scott.cate@myKB.com 또는 ScottCate.com 블로그를 통해 연락할 수 있습니다.