비동기 포스트백 취소
업데이트: 2007년 11월
비동기 포스트백은 페이지에서 NET UpdatePanel 웹 서버 컨트롤을 사용하여 ASP.NET에서 구현됩니다. UpdatePanel 컨트롤을 사용하면 각 포스트백마다 전체 페이지를 새로 고쳐야 할 필요가 없으므로 사용자 경험이 향상됩니다. 브라우저에서 Microsoft AJAX 라이브러리의 Sys.WebForms.PageRequestManager 클래스는 비동기 포스트백을 위한 클라이언트 페이지 수명 주기의 이벤트를 관리합니다. PageRequestManager 클래스에 의해 노출되는 이벤트를 처리하여 비동기 포스트백이 발생하는 방식을 사용자 지정할 수 있습니다.
이 자습서에서는 PageRequestManager 클래스의 initializeRequest 이벤트를 사용하여 현재 실행 중인 비동기 포스트백을 취소합니다.
PageRequestManager 클래스에서 발생하는 이벤트 시퀀스에 대한 자세한 내용은 PageRequestManager 이벤트 작업을 참조하십시오.
사전 요구 사항
고유한 개발 환경에서 절차를 구현하려면 다음이 필요합니다.
Microsoft Visual Studio 2005 또는 Microsoft Visual Web Developer Express Edition
AJAX 사용 ASP.NET 웹 사이트
포스트백을 취소하는 스크립트 만들기
먼저 브라우저에서 비동기 포스트백을 관리하는 ECMAScript(JavaScript) 코드를 만듭니다.
JavaScript 코드를 만들어 포스트백을 취소하려면
ASP.NET 웹 사이트에서 새 JScript 파일을 추가하고 이름을 CancelPostback.js로 지정합니다.
이 파일에 다음 스크립트를 추가합니다.
var divElem = 'AlertDiv'; var messageElem = 'AlertMessage'; Sys.Application.add_load(ApplicationLoadHandler) function ApplicationLoadHandler(sender, args) { Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(CheckStatus); } function CheckStatus(sender, args) { var prm = Sys.WebForms.PageRequestManager.getInstance(); if (prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'CancelRefresh') { prm.abortPostBack(); } else if (prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'RefreshButton') { args.set_cancel(true); ActivateAlertDiv('visible', 'Still working on previous request.'); } else if (!prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'RefreshButton') { ActivateAlertDiv('visible', 'Retrieving headlines.'); } } function ActivateAlertDiv(visString, msg) { var adiv = $get(divElem); var aspan = $get(messageElem); adiv.style.visibility = visString; aspan.innerHTML = msg; } if(typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();
var divElem = 'AlertDiv'; var messageElem = 'AlertMessage'; Sys.Application.add_load(ApplicationLoadHandler) function ApplicationLoadHandler(sender, args) { Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(CheckStatus); } function CheckStatus(sender, args) { var prm = Sys.WebForms.PageRequestManager.getInstance(); if (prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'CancelRefresh') { prm.abortPostBack(); } else if (prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'RefreshButton') { args.set_cancel(true); ActivateAlertDiv('visible', 'Still working on previous request.'); } else if (!prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'RefreshButton') { ActivateAlertDiv('visible', 'Retrieving headlines.'); } } function ActivateAlertDiv(visString, msg) { var adiv = $get(divElem); var aspan = $get(messageElem); adiv.style.visibility = visString; aspan.innerHTML = msg; } if(typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();
이 스크립트는 다음 작업을 수행합니다.
Sys.Application 클래스의 load 이벤트에 대한 처리기를 정의합니다. 이 처리기는 PageRequestManager 클래스의 initializeRequest 이벤트에 대한 CheckStatus라는 처리기를 등록합니다.
비동기 포스트백이 현재 실행 중인지 확인하고 포스트백을 일으킨 요소의 이름을 확인하기 위해 CheckStatus 처리기를 정의합니다.
메시지를 표시하는 데 사용되는 <div> 요소의 표시를 설정/해제하는 ActivateAlertDiv 함수를 정의합니다.
UpdatePanel 컨트롤에서 스크립트 사용
이 절차에서는 UpdatePanel 컨트롤을 포함하는 페이지에서 만든 스크립트를 사용합니다. 비동기 포스트백이 진행되는 동안 사용자가 링크를 클릭할 경우 스크립트는 포스트백을 취소합니다.
사용자가 포스트백을 취소할 수 있는 페이지를 만들려면
Default.aspx라는 새로운 단일 파일 ASP.NET 웹 페이지를 만들고 디자인 뷰로 전환합니다.
도구 상자의 AJAX 확장 탭에서 ScriptManager 컨트롤을 두 번 클릭하여 페이지에 추가합니다.
도구 상자에서 UpdatePanel 컨트롤을 두 번 클릭하여 페이지에 추가합니다.
소스 뷰로 전환하여 페이지의 <head> 요소에 있는 <style> 블록에 다음 스타일 규칙을 추가합니다.
<style type="text/css"> body { font-family: Tahoma; } #UpdatePanel1{ width: 400px; height: 200px; border: solid 1px gray; } div.AlertStyle { font-size: smaller; background-color: #FFC080; width: 400px; height: 20px; visibility: hidden; } </style>
<style type="text/css"> body { font-family: Tahoma; } #UpdatePanel1{ width: 400px; height: 200px; border: solid 1px gray; } div.AlertStyle { font-size: smaller; background-color: #FFC080; width: 400px; height: 20px; visibility: hidden; } </style>
이러한 스타일 규칙은 UpdatePanel 컨트롤에 의해 렌더링되는 <div> 요소의 높이와 너비를 정의합니다. 또한 진행 메시지를 표시하는 중첩된 <div> 요소의 모양을 정의합니다.
<asp:UpdatePanel> 요소의 <ContentTemplate> 요소 안에 다음 태그를 추가합니다.
<asp:DataList ID="HeadlineList" > <HeaderTemplate> <strong>Headlines</strong> </HeaderTemplate> <ItemTemplate> <%# Eval("Value") %> </ItemTemplate> <FooterTemplate> </FooterTemplate> <FooterStyle HorizontalAlign="right" /> </asp:DataList> <p style="text-align:right"> <asp:Button ID="RefreshButton" Text="Refresh" OnClick="NewsClick_Handler" /> </p> <div id="AlertDiv" class="AlertStyle"> <span id="AlertMessage"></span> <asp:LinkButton ID="CancelRefresh" > Cancel</asp:LinkButton>
<asp:DataList ID="HeadlineList" > <HeaderTemplate> <strong>Headlines</strong> </HeaderTemplate> <ItemTemplate> <%# Eval("Value") %> </ItemTemplate> <FooterTemplate> </FooterTemplate> <FooterStyle HorizontalAlign="right" /> </asp:DataList> <p style="text-align:right"> <asp:Button ID="RefreshButton" Text="Refresh" OnClick="NewsClick_Handler" /> </p> <div id="AlertDiv" class="AlertStyle"> <span id="AlertMessage"></span> <asp:LinkButton ID="CancelRefresh" > Cancel</asp:LinkButton>
이 태그는 다음 작업을 수행합니다.
나중에 이 절차에서 SortedList 개체로 정의되는 Value 필드에 바인딩되는 항목을 가진 DataList 컨트롤을 정의합니다.
비동기 포스트백을 일으키는 Button 컨트롤을 정의합니다.
비동기 포스트백 중 메시지를 표시하는 데 사용되는 <div> 요소를 정의합니다. 또한 <div> 요소는 포스트백을 취소할 수 있게 하는 LinkButton 컨트롤을 포함합니다.
<script > 요소에서 UpdatePanel 컨트롤의 새로 고침 단추에 사용되는 Click 이벤트 처리기로서 다음 서버 코드를 추가합니다.
Protected Sub NewsClick_Handler(ByVal sender As Object, ByVal e As EventArgs) System.Threading.Thread.Sleep(2000) HeadlineList.DataSource = GetHeadlines() HeadlineList.DataBind() End Sub
protected void NewsClick_Handler(object sender, EventArgs e) { System.Threading.Thread.Sleep(2000); HeadlineList.DataSource = GetHeadlines(); HeadlineList.DataBind(); }
이 코드는 데이터 바인딩을 사용하여 DataList 컨트롤에서 헤드라인 목록을 읽고 표시합니다.
참고: Click 이벤트에 대한 처리기는 이 자습서용 지연을 인위적으로 적용합니다. 실제로는 지연을 적용하지 않습니다. 대신 서버 트래픽이나, 실행 시간이 긴 데이터베이스 쿼리 같이 처리 시간이 오래 걸리는 서버 코드로 인해 시간 지연이 발생합니다.
<script> 요소 안에서 페이지의 Load 이벤트에 대한 다음 코드를 추가합니다.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) If Not (IsPostBack) Then HeadlineList.DataSource = GetHeadlines() HeadlineList.DataBind() End If End Sub
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { HeadlineList.DataSource = GetHeadlines(); HeadlineList.DataBind(); } }
이 코드는 현재 요청이 포스트백인지 여부를 검사합니다. 요청이 포스트백이 아닌 경우 DataList 컨트롤은 헤드라인 목록에 바인딩됩니다. 비동기 포스트백 중 데이터 바인딩은 이전 단계에서 만든 NewClick_Handler 메서드에서 발생합니다.
<script> 요소 안에 다음 코드를 추가하여 헤드라인을 생성합니다.
' Helper method to simulate news headline fetch. Private Function GetHeadlines() As SortedList Dim headlines As New SortedList() headlines.Add(1, "This is headline 1.") headlines.Add(2, "This is headline 2.") headlines.Add(3, "This is headline 3.") headlines.Add(4, "This is headline 4.") headlines.Add(5, "This is headline 5.") headlines.Add(6, "(Last updated on " & DateTime.Now.ToString() & ")") Return headlines End Function
// Helper method to simulate news headline fetch. private SortedList GetHeadlines() { SortedList headlines = new SortedList(); headlines.Add(1, "This is headline 1."); headlines.Add(2, "This is headline 2."); headlines.Add(3, "This is headline 3."); headlines.Add(4, "This is headline 4."); headlines.Add(5, "This is headline 5."); headlines.Add(6, "(Last updated on " + DateTime.Now.ToString() + ")"); return headlines; }
이 자습서의 헤드라인은 정적 목록으로 만들어집니다. 실제 응용 프로그램에서는 동적으로 생성됩니다.
디자인 뷰로 전환하여 페이지가 다음 그림과 유사한지 확인합니다.
ScriptManager 컨트롤을 선택합니다.
속성 창에서 스크립트 속성을 선택하고 줄임표(…) 단추를 클릭하여 ScriptReference 컬렉션 편집기 대화 상자를 표시합니다.
추가를 클릭하여 스크립트 참조를 추가합니다.
스크립트 참조의 경로 속성을 이전에 만든 JavaScript 파일인 CancelPostback.js로 설정합니다.
ScriptManager의 Scripts 컬렉션을 사용하여 스크립트 참조를 추가하면 Microsoft AJAX 라이브러리가 로드된 후에 스크립트가 로드됩니다.
확인을 클릭하여 ScriptReference 컬렉션 편집기 대화 상자를 닫습니다.
변경 내용을 저장하고 Ctrl+F5를 눌러 브라우저에서 페이지를 봅니다.
새로 고침 단추를 클릭하고 패널이 새로 고쳐지기를 기다립니다.
포스트백을 취소할 수 있는 옵션이 있는 메시지가 표시됩니다.
새로 고침 단추를 다시 클릭하고 메시지가 표시된 후 새로 고침 단추를 다시 클릭하여 패널이 새로 고쳐지기를 기다립니다.
이전 새로 고침이 여전히 진행 중이라는 것을 나타내도록 메시지의 텍스트가 변경됩니다. 두 번째 새로 고침이 무시됩니다.
새로 고침 단추를 다시 클릭하고 메시지가 표시되면 취소 링크를 클릭하여 포스트백을 취소합니다.
이 경우에는 비동기 포스트백이 취소되었기 때문에 UpdatePanel 컨트롤에 표시된 시간이 변경되지 않습니다.
<%@ Page Language="VB" %> <%@ Import Namespace="System.Collections.Generic" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > Protected Sub NewsClick_Handler(ByVal sender As Object, ByVal e As EventArgs) System.Threading.Thread.Sleep(2000) HeadlineList.DataSource = GetHeadlines() HeadlineList.DataBind() End Sub Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) If Not (IsPostBack) Then HeadlineList.DataSource = GetHeadlines() HeadlineList.DataBind() End If End Sub ' Helper method to simulate news headline fetch. Private Function GetHeadlines() As SortedList Dim headlines As New SortedList() headlines.Add(1, "This is headline 1.") headlines.Add(2, "This is headline 2.") headlines.Add(3, "This is headline 3.") headlines.Add(4, "This is headline 4.") headlines.Add(5, "This is headline 5.") headlines.Add(6, "(Last updated on " & DateTime.Now.ToString() & ")") Return headlines End Function </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" > <title>Canceling Postback Example</title> <style type="text/css"> body { font-family: Tahoma; } #UpdatePanel1{ width: 400px; height: 200px; border: solid 1px gray; } div.AlertStyle { font-size: smaller; background-color: #FFC080; width: 400px; height: 20px; visibility: hidden; } </style> </head> <body> <form id="form1" > <div > <asp:ScriptManager ID="ScriptManager1" > <Scripts> <asp:ScriptReference Path="CancelPostback.js" /> </Scripts> </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" runat="Server" > <ContentTemplate> <asp:DataList ID="HeadlineList" > <HeaderTemplate> <strong>Headlines</strong> </HeaderTemplate> <ItemTemplate> <%# Eval("Value") %> </ItemTemplate> <FooterTemplate> </FooterTemplate> <FooterStyle HorizontalAlign="right" /> </asp:DataList> <p style="text-align:right"> <asp:Button ID="RefreshButton" Text="Refresh" OnClick="NewsClick_Handler" /> </p> <div id="AlertDiv" class="AlertStyle"> <span id="AlertMessage"></span> <asp:LinkButton ID="CancelRefresh" > Cancel</asp:LinkButton> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body> </html>
<%@ Page Language="C#" %> <%@ Import Namespace="System.Collections.Generic" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > protected void NewsClick_Handler(object sender, EventArgs e) { System.Threading.Thread.Sleep(2000); HeadlineList.DataSource = GetHeadlines(); HeadlineList.DataBind(); } protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { HeadlineList.DataSource = GetHeadlines(); HeadlineList.DataBind(); } } // Helper method to simulate news headline fetch. private SortedList GetHeadlines() { SortedList headlines = new SortedList(); headlines.Add(1, "This is headline 1."); headlines.Add(2, "This is headline 2."); headlines.Add(3, "This is headline 3."); headlines.Add(4, "This is headline 4."); headlines.Add(5, "This is headline 5."); headlines.Add(6, "(Last updated on " + DateTime.Now.ToString() + ")"); return headlines; } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head > <title>Canceling Postback Example</title> <style type="text/css"> body { font-family: Tahoma; } #UpdatePanel1{ width: 400px; height: 200px; border: solid 1px gray; } div.AlertStyle { font-size: smaller; background-color: #FFC080; width: 400px; height: 20px; visibility: hidden; } </style> </head> <body> <form id="form1" > <div > <asp:ScriptManager ID="ScriptManager1" > <Scripts> <asp:ScriptReference Path="CancelPostback.js" /> </Scripts> </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" runat="Server" > <ContentTemplate> <asp:DataList ID="HeadlineList" > <HeaderTemplate> <strong>Headlines</strong> </HeaderTemplate> <ItemTemplate> <%# Eval("Value") %> </ItemTemplate> <FooterTemplate> </FooterTemplate> <FooterStyle HorizontalAlign="right" /> </asp:DataList> <p style="text-align:right"> <asp:Button ID="RefreshButton" Text="Refresh" OnClick="NewsClick_Handler" /> </p> <div id="AlertDiv" class="AlertStyle"> <span id="AlertMessage"></span> <asp:LinkButton ID="CancelRefresh" > Cancel</asp:LinkButton> </ContentTemplate> </asp:UpdatePanel> </div> </form> </body> </html>
검토
이 자습서에서는 비동기 포스트백을 취소하는 JavaScript 코드를 작성하는 방법을 설명했습니다. 이 스크립트는 PageRequestManager 클래스의 initializeRequest 이벤트에 대한 처리기를 제공합니다. initializeRequest 이벤트에서 포스트백을 일으킨 요소와 포스트백이 이미 진행 중인지 여부를 확인할 수 있습니다. 그런 다음 적절한 작업을 수행할 수 있습니다. 이 자습서의 코드에서는 취소 단추가 포함된 <div> 요소를 표시합니다.
UpdatePanel 컨트롤 상태를 자동으로 표시하려면 UpdateProgress 컨트롤을 사용하면 됩니다. 자세한 내용은 UpdateProgress 컨트롤 소개를 참조하십시오.
참고 항목
작업
클라이언트 스크립트에서 UpdateProgress 컨트롤 프로그래밍