BLL 및 DAL 수준의 예외 처리(VB)

작성자 : Scott Mitchell

PDF 다운로드

이 자습서에서는 편집 가능한 DataList의 업데이트 워크플로 중에 발생한 예외를 재치 있게 처리하는 방법을 알아봅니다.

소개

DataList 자습서의 데이터 편집 및 삭제 개요 자습서에서는 간단한 편집 및 삭제 기능을 제공하는 DataList를 만들었습니다. 완벽하게 작동하는 동안 편집 또는 삭제 프로세스 중에 발생한 오류로 인해 처리되지 않은 예외가 발생했기 때문에 사용자에게 친숙하지는 않았습니다. 예를 들어 제품 이름을 생략하거나 제품을 편집할 때 매우 저렴한 가격 값을 입력하면 예외가 발생합니다. 이 예외는 코드에서 catch되지 않으므로 ASP.NET 런타임까지 버블을 생성한 다음, 웹 페이지에 예외의 세부 정보를 표시합니다.

ASP.NET 페이지의 BLL 및 DAL-Level 예외 처리 자습서에서 살본 것처럼 비즈니스 논리 또는 데이터 액세스 계층의 깊이에서 예외가 발생하면 예외 세부 정보가 ObjectDataSource로 반환된 다음 GridView로 반환됩니다. ObjectDataSource 또는 GridView에 대한 또는 RowUpdated 이벤트 처리기를 만들고Updated, 예외를 확인한 다음, 예외가 처리되었음을 표시하여 이러한 예외를 정상적으로 처리하는 방법을 알아보았습니다.

그러나 DataList 자습서에서는 데이터를 업데이트하고 삭제하는 데 ObjectDataSource를 사용하지 않습니다. 대신 BLL에 대해 직접 작업하고 있습니다. BLL 또는 DAL에서 발생하는 예외를 검색하려면 ASP.NET 페이지의 코드 숨김 내에서 예외 처리 코드를 구현해야 합니다. 이 자습서에서는 편집 가능한 DataList의 업데이트 워크플로 중에 발생한 예외를 보다 정확하게 처리하는 방법을 알아봅니다.

참고

DataList 자습서의 데이터 편집 및 삭제 개요 자습서에서는 업데이트 및 삭제를 위해 ObjectDataSource를 사용하는 데 관련된 몇 가지 기술인 DataList에서 데이터를 편집하고 삭제하는 다양한 기술에 대해 설명했습니다. 이러한 기술을 사용하는 경우 ObjectDataSource 또는 이벤트 처리기를 통해 BLL 또는 DAL의 Updated 예외를 처리할 Deleted 수 있습니다.

1단계: 편집 가능한 데이터 목록 만들기

업데이트 워크플로 중에 발생하는 예외 처리에 대해 걱정하기 전에 먼저 편집 가능한 DataList를 만들어 보겠습니다. ErrorHandling.aspx 폴더에서 EditDeleteDataList 페이지를 열고, Designer DataList를 추가하고, 속성을 ProductsID 로 설정하고, 라는 ProductsDataSource새 ObjectDataSource를 추가합니다. 레코드를 선택하는 데 클래스의 GetProducts() 메서드를 사용하도록 ProductsBLL ObjectDataSource를 구성하고 INSERT, UPDATE 및 DELETE 탭의 드롭다운 목록을 (없음)으로 설정합니다.

GetProducts() 메서드를 사용하여 제품 정보 반환

그림 1: 메서드를 사용하여 GetProducts() 제품 정보 반환(전체 크기 이미지를 보려면 클릭)

ObjectDataSource 마법사를 완료하면 Visual Studio에서 DataList에 대한 를 ItemTemplate 자동으로 만듭니다. 이를 ItemTemplate 각 제품의 이름과 가격을 표시하고 편집 단추를 포함하는 으로 대체합니다. 다음으로, 이름 및 가격에 대한 TextBox 웹 컨트롤과 업데이트 및 취소 단추를 사용하여 을 만듭니 EditItemTemplate 다. 마지막으로 DataList의 RepeatColumns 속성을 2로 설정합니다.

이러한 변경 후 페이지의 선언적 태그는 다음과 유사하게 표시됩니다. 편집, 취소 및 업데이트 단추 CommandName 의 속성이 각각 편집, 취소 및 업데이트로 설정되어 있는지 확인하기 위해 두 번 검사.

<asp:DataList ID="Products" runat="server" DataKeyField="ProductID"
    DataSourceID="ProductsDataSource" RepeatColumns="2">
    <ItemTemplate>
        <h5>
            <asp:Label runat="server" ID="ProductNameLabel"
                Text='<%# Eval("ProductName") %>' />
        </h5>
        Price:
            <asp:Label runat="server" ID="Label1"
                Text='<%# Eval("UnitPrice", "{0:C}") %>' />
        <br />
            <asp:Button runat="server" id="EditProduct" CommandName="Edit"
                Text="Edit" />
        <br />
        <br />
    </ItemTemplate>
    <EditItemTemplate>
        Product name:
            <asp:TextBox ID="ProductName" runat="server"
                Text='<%# Eval("ProductName") %>' />
        <br />
        Price:
            <asp:TextBox ID="UnitPrice" runat="server"
                Text='<%# Eval("UnitPrice", "{0:C}") %>' />
        <br />
        <br />
            <asp:Button ID="UpdateProduct" runat="server" CommandName="Update"
                Text="Update" /> 
            <asp:Button ID="CancelUpdate" runat="server" CommandName="Cancel"
                Text="Cancel" />
    </EditItemTemplate>
</asp:DataList>
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
    SelectMethod="GetProducts" TypeName="ProductsBLL"
    OldValuesParameterFormatString="original_{0}">
</asp:ObjectDataSource>

참고

이 자습서에서는 DataList의 뷰 상태를 사용하도록 설정해야 합니다.

잠시 시간을 내어 브라우저를 통해 진행 상황을 확인합니다(그림 2 참조).

각 제품에는 편집 단추가 포함됩니다.

그림 2: 각 제품에 편집 단추가 포함되어 있습니다(전체 크기 이미지를 보려면 클릭).

현재 편집 단추는 아직 제품을 편집할 수 없게 만드는 포스트백만 발생합니다. 편집을 사용하도록 설정하려면 DataList의 EditCommand, CancelCommandUpdateCommand 이벤트에 대한 이벤트 처리기를 만들어야 합니다. EditCommandCancelCommand 이벤트는 DataList의 EditItemIndex 속성을 업데이트하고 데이터를 DataList에 다시 바인딩합니다.

Protected Sub Products_EditCommand(source As Object, e As DataListCommandEventArgs) _
    Handles Products.EditCommand
    ' Set the DataList's EditItemIndex property to the
    ' index of the DataListItem that was clicked
    Products.EditItemIndex = e.Item.ItemIndex
    ' Rebind the data to the DataList
    Products.DataBind()
End Sub
Protected Sub Products_CancelCommand(source As Object, e As DataListCommandEventArgs) _
    Handles Products.CancelCommand
    ' Set the DataList's EditItemIndex property to -1
    Products.EditItemIndex = -1
    ' Rebind the data to the DataList
    Products.DataBind()
End Sub

UpdateCommand 이벤트 처리기는 좀 더 관련이 있습니다. 컬렉션의 편집된 제품 ProductID s에서 DataKeys 에 있는 TextBoxesEditItemTemplate의 제품 이름 및 가격과 함께 읽은 다음, DataList를 사전 편집 상태로 되돌리기 전에 클래스의 UpdateProduct 메서드를 호출 ProductsBLL 해야 합니다.

지금은 DataList 자습서의 UpdateCommand데이터 편집 및 삭제 개요 에서 이벤트 처리기의 정확히 동일한 코드를 사용하겠습니다. 2단계에서 예외를 정상적으로 처리하는 코드를 추가합니다.

Protected Sub Products_UpdateCommand(source As Object, e As DataListCommandEventArgs) _
    Handles Products.UpdateCommand
    ' Read in the ProductID from the DataKeys collection
    Dim productID As Integer = Convert.ToInt32(Products.DataKeys(e.Item.ItemIndex))
    ' Read in the product name and price values
    Dim productName As TextBox = CType(e.Item.FindControl("ProductName"), TextBox)
    Dim unitPrice As TextBox = CType(e.Item.FindControl("UnitPrice"), TextBox)
    Dim productNameValue As String = Nothing
    If productName.Text.Trim().Length > 0 Then
        productNameValue = productName.Text.Trim()
    End If
    Dim unitPriceValue As Nullable(Of Decimal) = Nothing
    If unitPrice.Text.Trim().Length > 0 Then
        unitPriceValue = Decimal.Parse(unitPrice.Text.Trim(), _
                         System.Globalization.NumberStyles.Currency)
    End If
    ' Call the ProductsBLL's UpdateProduct method...
    Dim productsAPI As New ProductsBLL()
    productsAPI.UpdateProduct(productNameValue, unitPriceValue, productID)
    ' Revert the DataList back to its pre-editing state
    Products.EditItemIndex = -1
    Products.DataBind()
End Sub

잘못된 형식의 단가 형식일 수 있는 잘못된 입력에 직면하여 -$5.00과 같은 잘못된 단가 값 또는 제품 이름을 생략하면 예외가 발생합니다. UpdateCommand 이벤트 처리기에는 이 시점에서 예외 처리 코드가 포함되지 않으므로 예외가 ASP.NET 런타임까지 버블링됩니다. 그러면 최종 사용자에게 표시됩니다(그림 3 참조).

처리되지 않은 예외가 발생하면 최종 사용자에게 오류 페이지가 표시됩니다.

그림 3: 처리되지 않은 예외가 발생하면 최종 사용자에게 오류 페이지가 표시됩니다.

2단계: UpdateCommand 이벤트 처리기에서 예외를 정상적으로 처리

워크플로를 업데이트하는 동안 이벤트 처리기, BLL 또는 DAL에서 UpdateCommand 예외가 발생할 수 있습니다. 예를 들어 사용자가 너무 비싼 Decimal.Parse 가격을 입력하면 이벤트 처리기의 문에서 UpdateCommand 예외가 FormatException throw됩니다. 사용자가 제품 이름을 생략하거나 가격에 음수 값이 있는 경우 DAL에서 예외가 발생합니다.

예외가 발생하면 페이지 자체 내에 정보 메시지를 표시하려고 합니다. 로 설정된 페이지에 ID 레이블 웹 컨트롤을 추가합니다 ExceptionDetails. 파일에 정의된 CSS 클래스에 속성을 CssClass 할당하여 레이블 텍스트를 빨강, 초대형, 굵게 및 기울임꼴 글꼴로 Styles.css 표시하도록 Warning 구성합니다.

오류가 발생하면 레이블을 한 번만 표시하려고 합니다. 즉, 후속 포스트백에서 레이블의 경고 메시지가 사라집니다. 이 작업은 레이블의 Text 속성을 지우거나 해당 속성을 False 이벤트 처리기에서 Page_Load 로 설정 Visible 하거나(ASP.NET 페이지 자습서에서 BLL 처리 및 DAL-Level 예외 처리에서 했던 것처럼) 또는 레이블 뷰 상태 지원을 사용하지 않도록 설정하여 수행할 수 있습니다. 후자 옵션을 사용하겠습니다.

<asp:Label ID="ExceptionDetails" EnableViewState="False" CssClass="Warning"
    runat="server" />

예외가 발생하면 예외의 세부 정보를 Label 컨트롤의 Text 속성에 ExceptionDetails 할당합니다. 뷰 상태가 비활성화되므로 후속 포스트백 Text 에서 속성의 프로그래밍 방식 변경 내용이 손실되어 기본 텍스트(빈 문자열)로 되돌아가 경고 메시지를 숨깁니다.

페이지에 유용한 메시지를 표시하기 위해 오류가 발생한 시기를 확인하려면 이벤트 처리기에 블록을 UpdateCommand 추가 Try ... Catch 해야 합니다. 부분에는 Try 예외가 발생할 수 있는 코드가 포함되어 있지만 Catch 블록에는 예외가 발생할 때 실행되는 코드가 포함됩니다. 블록에 대한 자세한 내용은 .NET Framework 설명서의 예외 처리 기본 사항 섹션을 Try ... Catch 참조하세요.

Protected Sub Products_UpdateCommand(source As Object, e As DataListCommandEventArgs) _
    Handles Products.UpdateCommand
    ' Handle any exceptions raised during the editing process
    Try
        ' Read in the ProductID from the DataKeys collection
        Dim productID As Integer = _
            Convert.ToInt32(Products.DataKeys(e.Item.ItemIndex))
        ... Some code omitted for brevity ...
    Catch ex As Exception
        ' TODO: Display information about the exception in ExceptionDetails
    End Try
End Sub

블록 Catch 내의 코드에서 모든 형식의 예외가 Try throw되면 블록의 코드가 실행되기 시작합니다. , , NoNullAllowedExceptionArgumentException등에서 throwDbException되는 예외 유형은 처음에 오류를 정확히 침전시킨 내용에 따라 달라집니다. 데이터베이스 수준에서 문제가 발생하면 가 DbException throw됩니다. , , UnitsInStockUnitsOnOrder또는 ReorderLevel 필드에 ArgumentException 대해 UnitPrice잘못된 값을 입력하면 클래스에서 ProductsDataTable 이러한 필드 값의 유효성을 검사하는 코드를 추가했기 때문에 이 throw됩니다(비즈니스 논리 계층 만들기 자습서 참조).

적발된 예외 유형에 대한 메시지 텍스트를 기반으로 최종 사용자에게 더 유용한 설명을 제공할 수 있습니다. ASP.NET 페이지의 BLL 처리 및 DAL-Level 예외 자습서에서 거의 동일한 형식으로 사용된 다음 코드는 이 수준의 세부 정보를 제공합니다.

Private Sub DisplayExceptionDetails(ByVal ex As Exception)
    ' Display a user-friendly message
    ExceptionDetails.Text = "There was a problem updating the product. "
    If TypeOf ex Is System.Data.Common.DbException Then
        ExceptionDetails.Text += "Our database is currently experiencing problems." + _
                                 "Please try again later."
    ElseIf TypeOf ex Is System.Data.NoNullAllowedException Then
        ExceptionDetails.Text+="There are one or more required fields that are missing."
    ElseIf TypeOf ex Is ArgumentException Then
        Dim paramName As String = CType(ex, ArgumentException).ParamName
        ExceptionDetails.Text+=String.Concat("The ", paramName, " value is illegal.")
    ElseIf TypeOf ex Is ApplicationException Then
        ExceptionDetails.Text += ex.Message
    End If
End Sub

이 자습서를 완료하려면 catch ExceptionDisplayExceptionDetails instance(ex)를 전달하는 블록에서 Catch 메서드를 호출하면 됩니다.

블록이 Try ... Catch 있으면 그림 4와 5에서 보여 주는 것처럼 사용자에게 더 유익한 오류 메시지가 표시됩니다. 예외가 발생할 경우 DataList는 편집 모드로 유지됩니다. 이는 예외가 발생하면 제어 흐름이 즉시 블록으로 리디렉션되어 DataList를 Catch 사전 편집 상태로 반환하는 코드를 무시하기 때문입니다.

사용자가 필수 필드를 생략하면 오류 메시지가 표시됩니다.

그림 4: 사용자가 필수 필드를 생략하면 오류 메시지가 표시됩니다(전체 크기 이미지를 보려면 클릭).

음수 가격을 입력할 때 오류 메시지가 표시됩니다.

그림 5: 음수 가격을 입력할 때 오류 메시지가 표시됩니다(전체 크기 이미지를 보려면 클릭).

요약

GridView 및 ObjectDataSource는 워크플로 업데이트 및 삭제 중에 발생한 예외에 대한 정보와 예외 처리 여부를 나타내도록 설정할 수 있는 속성을 포함하는 사후 수준 이벤트 처리기를 제공합니다. 그러나 이러한 기능은 DataList로 작업하고 BLL을 직접 사용할 때 사용할 수 없습니다. 대신 예외 처리를 구현해야 합니다.

이 자습서에서는 이벤트 처리기에 블록을 UpdateCommand 추가하여 편집 가능한 DataList의 업데이트 워크플로에 예외 처리를 추가하는 Try ... Catch 방법을 알아보았습니다. 워크플로 업데이트 중에 예외가 발생하면 블록 코드가 Catch 실행되어 레이블에 ExceptionDetails 유용한 정보가 표시됩니다.

이 시점에서 DataList는 예외가 발생하는 것을 방지하기 위해 애초에 노력하지 않습니다. 부정적인 가격으로 인해 예외가 발생한다는 것을 알고 있지만 사용자가 잘못된 입력을 입력하지 못하도록 사전에 방지하는 기능은 아직 추가되지 않았습니다. 다음 자습서에서는 에 유효성 검사 컨트롤을 추가하여 잘못된 사용자 입력으로 인한 예외를 EditItemTemplate줄이는 방법을 살펴보겠습니다.

행복한 프로그래밍!

추가 정보

이 자습서에서 설명하는 topics 대한 자세한 내용은 다음 리소스를 참조하세요.

저자 정보

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

특별 감사

이 자습서 시리즈는 많은 유용한 검토자가 검토했습니다. 이 자습서의 수석 검토자는 Ken Pespisa였습니다. 예정된 MSDN 문서를 검토하시겠습니까? 그렇다면 에 줄을 놓습니다 mitchell@4GuysFromRolla.com.