삭제할 때 클라이언트 쪽 확인 추가(C#)

작성자 : Scott Mitchell

PDF 다운로드

지금까지 만든 인터페이스에서 사용자가 편집 단추를 클릭할 때 삭제 단추를 클릭하여 실수로 데이터를 삭제할 수 있습니다. 이 자습서에서는 삭제 단추를 클릭할 때 표시되는 클라이언트 쪽 확인 대화 상자를 추가합니다.

소개

지난 몇 가지 자습서에서는 애플리케이션 아키텍처, ObjectDataSource 및 데이터 웹 컨트롤을 함께 사용하여 삽입, 편집 및 삭제 기능을 제공하는 방법을 살펴보았습니다. 지금까지 살펴본 삭제 인터페이스는 클릭 시 포스트백을 발생시키고 ObjectDataSource의 Delete() 메서드를 호출하는 삭제 단추로 구성되었습니다. 그런 다음, 메서드는 Delete() 비즈니스 논리 계층에서 구성된 메서드를 호출하여 호출을 데이터 액세스 계층으로 전파하고 실제 DELETE 문을 데이터베이스에 실행합니다.

이 사용자 인터페이스를 사용하면 방문자가 GridView, DetailsView 또는 FormView 컨트롤을 통해 레코드를 삭제할 수 있지만 사용자가 삭제 단추를 클릭할 때 어떤 종류의 확인도 수행되지 않습니다. 사용자가 편집을 클릭할 때 실수로 삭제 단추를 클릭하면 업데이트하려는 레코드가 대신 삭제됩니다. 이를 방지하기 위해 이 자습서에서는 삭제 단추를 클릭할 때 표시되는 클라이언트 쪽 확인 대화 상자를 추가합니다.

JavaScript confirm(string) 함수는 문자열 입력 매개 변수를 두 개의 단추(확인 및 취소)가 있는 모달 대화 상자 내의 텍스트로 표시합니다(그림 1 참조). 함수는 confirm(string) 클릭한true 단추(사용자가 확인을 false 클릭하고 취소를 클릭하는 경우)에 따라 부울 값을 반환합니다.

JavaScript confirm(string) 메서드 모달 Client-Side Messagebox를 표시합니다.

그림 1: JavaScript confirm(string) 메서드가 모달 Client-Side 메시지 상자를 표시합니다.

양식 제출 중에 클라이언트 쪽 이벤트 처리기에서 값 false 이 반환되면 양식 제출이 취소됩니다. 이 기능을 사용하면 삭제 단추의 클라이언트 쪽 onclick 이벤트 처리기가 에 대한 호출 값을 반환하도록 할 confirm("Are you sure you want to delete this product?")수 있습니다. 사용자가 취소를 클릭하면 가 confirm(string) false를 반환하므로 양식 제출이 취소됩니다. 포스트백이 없으면 삭제 단추를 클릭한 제품은 삭제되지 않습니다. 그러나 사용자가 확인 대화 상자에서 확인을 클릭하면 포스트백이 계속 비활성화되고 제품이 삭제됩니다. 이 기술에 대한 자세한 내용은 JavaScript 메서드 confirm() 를 사용하여 양식 제출 제어 를 참조하세요.

필요한 클라이언트 쪽 스크립트를 추가하는 것은 CommandField를 사용하는 경우와 템플릿을 사용하는 경우 약간 다릅니다. 따라서 이 자습서에서는 FormView 및 GridView 예제를 모두 살펴보겠습니다.

참고

이 자습서에서 설명한 것과 같이 클라이언트 쪽 확인 기술을 사용하면 사용자가 JavaScript를 지원하는 브라우저를 방문하며 JavaScript를 사용하도록 설정된 것으로 가정합니다. 특정 사용자에 대해 이러한 가정 중 하나가 true가 아닌 경우 삭제 단추를 클릭하면 즉시 포스트백이 발생합니다(확인 메시지 상자를 표시하지 않음).

1단계: 삭제를 지원하는 FormView 만들기

먼저 폴더의 ConfirmationOnDelete.aspx 페이지에 EditInsertDelete FormView를 추가하여 클래스의 GetProducts() 메서드를 통해 제품 정보를 다시 가져오는 새 ObjectDataSource에 ProductsBLL 바인딩합니다. 또한 클래스의 메서드가 ProductsBLL ObjectDataSource의 DeleteProduct(productID)Delete() 메서드에 매핑되도록 ObjectDataSource를 구성합니다. INSERT 및 UPDATE 탭 드롭다운 목록이 (없음)으로 설정되어 있는지 확인합니다. 마지막으로 FormView의 스마트 태그에서 페이징 사용 확인란을 검사.

이러한 단계가 끝나면 새 ObjectDataSource의 선언적 태그는 다음과 같이 표시됩니다.

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    DeleteMethod="DeleteProduct" OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetProducts" TypeName="ProductsBLL">
    <DeleteParameters>
        <asp:Parameter Name="productID" Type="Int32" />
    </DeleteParameters>
</asp:ObjectDataSource>

낙관적 동시성을 사용하지 않은 이전 예제와 마찬가지로 잠시 시간을 내어 ObjectDataSource의 OldValuesParameterFormatString 속성을 지웁니다.

삭제만 지원하는 ObjectDataSource 컨트롤에 바인딩되었으므로 FormView는 ItemTemplate 새로 만들기 및 업데이트 단추가 없는 삭제 단추만 제공합니다. 그러나 FormView의 선언적 태그에는 제거할 수 있는 불필요한 EditItemTemplateInsertItemTemplate가 포함됩니다. 잠시 시간을 내어 제품 데이터 필드의 하위 집합만 표시되도록 을 사용자 지정 ItemTemplate 합니다. 공급자 및 범주 이름 위에 있는 제목에 <h3> 제품 이름을 표시하도록 광산을 구성했습니다(삭제 단추와 함께).

<asp:FormView ID="FormView1" AllowPaging="True" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" runat="server">
    <ItemTemplate>
        <h3><i><%# Eval("ProductName") %></i></h3>
        <b>Category:</b>
        <asp:Label ID="CategoryNameLabel" runat="server"
            Text='<%# Eval("CategoryName") %>'>
        </asp:Label><br />
        <b>Supplier:</b>
        <asp:Label ID="SupplierNameLabel" runat="server"
            Text='<%# Eval("SupplierName") %>'>
        </asp:Label><br />
        <asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False"
            CommandName="Delete" Text="Delete">
        </asp:LinkButton>
    </ItemTemplate>
</asp:FormView>

이러한 변경 내용으로 사용자가 한 번에 하나씩 제품을 전환할 수 있는 완전한 기능의 웹 페이지가 있으며, 삭제 단추를 클릭하기만 하면 제품을 삭제할 수 있습니다. 그림 2는 브라우저를 통해 볼 때 지금까지 진행 상황의 스크린샷을 보여줍니다.

FormView는 단일 제품에 대한 정보를 표시합니다.

그림 2: FormView는 단일 제품에 대한 정보를 표시합니다(전체 크기 이미지를 보려면 클릭).

2단계: 삭제 단추 Client-Side onclick 이벤트에서 confirm(string) 함수 호출

FormView를 만든 후 마지막 단계는 방문자가 클릭할 때 JavaScript confirm(string) 함수가 호출되도록 삭제 단추를 구성하는 것입니다. Button, LinkButton 또는 ImageButton의 클라이언트 쪽 이벤트에 클라이언트 쪽 onclick 스크립트를 추가하는 작업은 ASP.NET 2.0의 새로운 를 사용하여 OnClientClick property수행할 수 있습니다. 함수의 confirm(string) 값을 반환하려고 하므로 이 속성을 다음으로 설정하기만 하면됩니다. return confirm('Are you certain that you want to delete this product?');

이 변경 후 LinkButton 삭제 선언적 구문은 다음과 같이 표시됩니다.

<asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False"
    CommandName="Delete" Text="Delete"
    OnClientClick="return confirm('Are you certain you want to delete this product?');">
</asp:LinkButton>

그게 전부입니다! 그림 3은 이 확인의 스크린샷을 보여줍니다. 삭제 단추를 클릭하면 확인 대화 상자가 나타납니다. 사용자가 취소를 클릭하면 포스트백이 취소되고 제품이 삭제되지 않습니다. 그러나 사용자가 확인을 클릭하면 포스트백이 계속되고 ObjectDataSource의 Delete() 메서드가 호출되어 데이터베이스 레코드가 삭제됩니다.

참고

JavaScript 함수에 confirm(string) 전달된 문자열은 따옴표가 아닌 아포스트로피로 구분됩니다. JavaScript에서 문자열은 두 문자 중 하나를 사용하여 구분할 수 있습니다. 여기에 아포스트로피를 사용하여 전달된 문자열의 구분 기호가 속성 값에 confirm(string) 사용되는 OnClientClick 구분 기호와 모호성을 도입하지 않도록 합니다.

삭제 단추를 클릭하면 확인이 표시됩니다.

그림 3: 삭제 단추를 클릭하면 확인이 표시됩니다(전체 크기 이미지를 보려면 클릭).

3단계: CommandField에서 삭제 단추에 대한 OnClientClick 속성 구성

템플릿에서 Button, LinkButton 또는 ImageButton으로 직접 작업하는 경우 JavaScript confirm(string) 함수의 결과를 반환하도록 속성을 OnClientClick 구성하기만 하면 확인 대화 상자를 연결할 수 있습니다. 그러나 GridView 또는 DetailsView에 삭제 단추 필드를 추가하는 CommandField에는 OnClientClick 선언적으로 설정할 수 있는 속성이 없습니다. 대신 GridView 또는 DetailsView의 적절한 DataBound 이벤트 처리기에서 삭제 단추를 프로그래밍 방식으로 참조한 다음 해당 속성을 설정 OnClientClick 해야 합니다.

참고

적절한 DataBound 이벤트 처리기에서 삭제 단추의 OnClientClick 속성을 설정할 때 데이터에 대한 액세스 권한이 현재 레코드에 바인딩되었습니다. 즉, "Chai 제품을 삭제하시겠습니까?"와 같은 특정 레코드에 대한 세부 정보를 포함하도록 확인 메시지를 확장할 수 있습니다. 데이터 바인딩 구문을 사용하는 템플릿에서도 이러한 사용자 지정이 가능합니다.

CommandField에서 삭제 단추의 속성을 설정하는 OnClientClick 방법을 연습하려면 페이지에 GridView를 추가해 보겠습니다. FormView에서 사용하는 것과 동일한 ObjectDataSource 컨트롤을 사용하도록 이 GridView를 구성합니다. 또한 GridView의 BoundFields는 제품 이름, 범주 및 공급자만 포함하도록 제한합니다. 마지막으로 GridView의 스마트 태그에서 삭제 사용 확인란을 검사. 그러면 속성이 로 설정된 GridView 컬렉션 Columns 에 CommandField가 ShowDeleteButtontrue추가됩니다.

이러한 변경을 수행한 후 GridView의 선언적 태그는 다음과 같이 표시됩니다.

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:CommandField ShowDeleteButton="True" />
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="CategoryName" HeaderText="Category" ReadOnly="True"
            SortExpression="CategoryName" />
        <asp:BoundField DataField="SupplierName" HeaderText="Supplier" ReadOnly="True"
            SortExpression="SupplierName" />
    </Columns>
</asp:GridView>

CommandField에는 GridView의 RowDataBound 이벤트 처리기에서 프로그래밍 방식으로 액세스할 수 있는 단일 Delete LinkButton instance 포함되어 있습니다. 참조되면 그에 따라 해당 OnClientClick 속성을 설정할 수 있습니다. 다음 코드를 사용하여 이벤트에 대한 RowDataBound 이벤트 처리기를 만듭니다.

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // reference the Delete LinkButton
        LinkButton db = (LinkButton)e.Row.Cells[0].Controls[0];

        // Get information about the product bound to the row
        Northwind.ProductsRow product =
            (Northwind.ProductsRow) ((System.Data.DataRowView) e.Row.DataItem).Row;

        db.OnClientClick = string.Format(
            "return confirm('Are you certain you want to delete the {0} product?');",
            product.ProductName.Replace("'", @"\'"));
    }
}

이 이벤트 처리기는 데이터 행(삭제 단추가 있는 행)에서 작동하고 삭제 단추를 프로그래밍 방식으로 참조하여 시작합니다. 일반적으로 다음 패턴을 사용합니다.

ButtonType obj = (ButtonType) e.Row.Cells[commandFieldIndex].Controls[controlIndex];

ButtonType 은 CommandField - Button, LinkButton 또는 ImageButton에서 사용하는 단추의 유형입니다. 기본적으로 CommandField는 LinkButtons를 사용하지만 CommandField의 ButtonType property를 통해 사용자 지정할 수 있습니다. commandFieldIndex는 GridView Columns 컬렉션 내의 CommandField 서수 인덱스인 반면 controlIndex는 CommandField 컬렉션 Controls 내의 삭제 단추의 인덱스입니다. controlIndex 값은 CommandField의 다른 단추에 상대적인 단추 위치에 따라 달라집니다. 예를 들어 CommandField에 표시되는 유일한 단추가 삭제 단추인 경우 인덱스 0을 사용합니다. 그러나 삭제 단추 앞에 편집 단추가 있는 경우 인덱스 2를 사용합니다. 인덱스가 2인 이유는 삭제 단추 앞에 CommandField에서 편집 단추와 편집 단추와 삭제 단추 사이에 공간을 추가하는 데 사용되는 LiteralControl이라는 두 개의 컨트롤이 추가되기 때문입니다.

특정 예제의 경우 CommandField는 LinkButtons를 사용하며 가장 왼쪽 필드인 commandFieldIndex 는 0입니다. CommandField에는 다른 단추가 없지만 삭제 단추는 0인 controlIndex 를 사용합니다.

CommandField에서 삭제 단추를 참조한 후 다음으로 현재 GridView 행에 바인딩된 제품에 대한 정보를 가져옵니다. 마지막으로 삭제 단추의 OnClientClick 속성을 제품 이름을 포함하는 적절한 JavaScript로 설정합니다. 함수에 confirm(string) 전달된 JavaScript 문자열은 아포스트로피를 사용하여 구분되므로 제품 이름 내에 표시되는 아포스트로피를 이스케이프해야 합니다. 특히 제품 이름에 있는 아포스트로피는 "\'"로 이스케이프됩니다.

이러한 변경이 완료되면 GridView에서 삭제 단추를 클릭하면 사용자 지정된 확인 대화 상자가 표시됩니다(그림 4 참조). FormView의 확인 메시지 상자와 마찬가지로 사용자가 취소를 클릭하면 포스트백이 취소되므로 삭제가 발생하지 않습니다.

참고

이 기술을 사용하여 DetailsView의 CommandField에서 삭제 단추에 프로그래밍 방식으로 액세스할 수도 있습니다. 그러나 DetailsView의 경우 DetailsView에 이벤트가 없으므로 이벤트에 대한 DataBound 이벤트 처리기를 만듭니다 RowDataBound .

GridView의 삭제 단추를 클릭하면 사용자 지정된 확인 대화 상자가 표시됩니다.

그림 4: GridView의 삭제 단추를 클릭하면 사용자 지정된 확인 대화 상자가 표시됩니다(전체 크기 이미지를 보려면 클릭).

TemplateFields 사용

CommandField의 단점 중 하나는 인덱싱을 통해 단추에 액세스해야 하며 결과 개체를 적절한 단추 유형(Button, LinkButton 또는 ImageButton)으로 캐스팅해야 한다는 것입니다. "매직 넘버" 및 하드 코딩된 형식을 사용하면 런타임까지 검색할 수 없는 문제가 발생합니다. 예를 들어 사용자 또는 다른 개발자가 나중에 편집 단추와 같은 특정 시점에 CommandField에 새 단추를 추가하거나 속성을 변경하는 ButtonType 경우 기존 코드는 오류 없이 컴파일되지만 페이지를 방문하면 코드 작성 방법 및 변경 내용에 따라 예외 또는 예기치 않은 동작이 발생할 수 있습니다.

또 다른 방법은 GridView 및 DetailsView의 CommandFields를 TemplateFields로 변환하는 것입니다. 이렇게 하면 CommandField ItemTemplate 의 각 단추에 대해 LinkButton(또는 Button 또는 ImageButton)이 있는 이 있는 TemplateField가 생성됩니다. FormView에서 OnClientClick 확인한 것처럼 이러한 단추 속성을 선언적으로 할당하거나 다음 패턴을 사용하여 적절한 DataBound 이벤트 처리기에서 프로그래밍 방식으로 액세스할 수 있습니다.

ButtonType obj = (ButtonType) e.Row.FindControl("controlID");

여기서 controlID 는 단추 속성의 값입니다 ID . 이 패턴에는 캐스트에 하드 코딩된 형식이 필요하지만 인덱싱이 필요하지 않으므로 런타임 오류가 발생하지 않고 레이아웃을 변경할 수 있습니다.

요약

JavaScript confirm(string) 함수는 양식 제출 워크플로를 제어하는 데 일반적으로 사용되는 기술입니다. 실행되면 함수는 확인 및 취소라는 두 개의 단추가 포함된 모달 클라이언트 쪽 대화 상자를 표시합니다. 사용자가 확인을 클릭하면 함수가 confirm(string) 를 반환 true하고 취소를 클릭하면 가 반환됩니다 false. 제출 프로세스 중에 이벤트 처리기가 를 반환 false하는 경우 양식 제출을 취소하는 브라우저 동작과 결합된 이 기능을 사용하여 레코드를 삭제할 때 확인 메시지 상자를 표시할 수 있습니다.

함수는 confirm(string) 컨트롤의 OnClientClick 속성을 통해 Button Web 컨트롤의 클라이언트 쪽 onclick 이벤트 처리기와 연결할 수 있습니다. FormView 템플릿 중 하나 또는 DetailsView 또는 GridView의 TemplateField에서 템플릿의 삭제 단추를 사용하는 경우 이 자습서에서 살 수 있듯이 이 속성을 선언적으로 또는 프로그래밍 방식으로 설정할 수 있습니다.

행복한 프로그래밍!

저자 정보

7개의 ASP/ASP.NET 책의 저자이자 4GuysFromRolla.com 창립자인 Scott Mitchell은 1998년부터 Microsoft 웹 기술로 작업해 왔습니다. Scott은 독립 컨설턴트, 트레이너 및 작가로 일합니다. 그의 최신 책은 샘스 티치 유어셀프 ASP.NET 24시간 만에 2.0입니다. 그는 에서mitchell@4GuysFromRolla.com 또는 에서 찾을 http://ScottOnWriting.NET수있는 자신의 블로그를 통해 도달 할 수 있습니다.