Freigeben über


Verarbeiten von Ausnahmen auf BLL- und DAL-Ebene (VB)

von Scott Mitchell

PDF herunterladen

In diesem Tutorial wird gezeigt, wie Sie Ausnahmen, die während des Aktualisierungsworkflows einer bearbeitbaren DataList ausgelöst werden, taktvoll behandeln.

Einführung

In der Übersicht über das Bearbeiten und Löschen von Daten im DataList-Lernprogramm haben wir eine DataList erstellt, die einfache Bearbeitungs- und Löschfunktionen bietet. Während voll funktionsfähig, war es kaum benutzerfreundlich, da ein Fehler, der während des Bearbeitungs- oder Löschvorgangs aufgetreten ist, zu einer unbehandelten Ausnahme führte. Wenn Sie z. B. den Produktnamen weglassen oder beim Bearbeiten eines Produkts einen Preiswert von "Sehr erschwinglich" eingeben, wird eine Ausnahme ausgelöst. Da diese Ausnahme nicht im Code erfasst wird, wird sie bis zur ASP.NET Laufzeit eingeblasen, wodurch dann die Details der Ausnahme auf der Webseite angezeigt werden.

Wie wir im Tutorial für eine ASP.NET-Seite zur Behandlung von BLL- und DAL-Level-Ausnahmen gesehen haben, werden die Einzelheiten der Ausnahme an die ObjectDataSource und dann an das GridView zurückübermittelt, wenn eine Ausnahme in den Tiefen der Geschäftslogik- oder Datenzugriffsebenen ausgelöst wird. Wir haben gesehen, wie diese Ausnahmen elegant gehandhabt werden, indem wir Ereignishandler für ObjectDataSource oder GridView wie Updated oder RowUpdated erstellen, eine Ausnahme erkennen und dann angeben, dass die Ausnahme behandelt wurde.

Unsere DataList-Lernprogramme verwenden jedoch nicht die ObjectDataSource zum Aktualisieren und Löschen von Daten. Stattdessen arbeiten wir direkt gegen die BLL. Um Ausnahmen zu erkennen, die von der BLL oder DAL stammen, müssen wir code für die Ausnahmebehandlung innerhalb des CodeBehind unserer ASP.NET-Seite implementieren. In diesem Kurs werden wir sehen, wie Sie Ausnahmen, die während des Aktualisierungsworkflows einer bearbeitbaren DataList ausgelöst wurden, taktvoller behandeln können.

Hinweis

In dem Tutorial Ein Überblick über das Bearbeiten und Löschen von Daten in der DataList haben wir verschiedene Techniken zum Bearbeiten und Löschen von Daten aus der DataList besprochen. Einige Techniken beinhalteten die Verwendung einer ObjectDataSource zum Aktualisieren und Löschen. Wenn Sie diese Techniken verwenden, können Sie Ausnahmen von der BLL oder DAL über die ObjectDataSource s Updated oder Deleted Ereignishandler behandeln.

Schritt 1: Erstellen einer bearbeitbaren DataList

Bevor wir uns gedanken über die Behandlung von Ausnahmen machen, die während des Aktualisierungsworkflows auftreten, erstellen wir zunächst eine bearbeitbare DataList. Öffnen Sie die ErrorHandling.aspx Seite im EditDeleteDataList Ordner, fügen Sie dem Designer eine DataList hinzu, legen Sie dessen ID Eigenschaft zu Products fest, und fügen Sie eine neue ObjectDataSource mit dem Namen ProductsDataSource hinzu. Konfigurieren Sie objectDataSource so, dass die ProductsBLL Klassenmethode GetProducts() zum Auswählen von Datensätzen verwendet wird. Legen Sie die Dropdownlisten in den Registerkarten INSERT, UPDATE und DELETE auf (Keine) fest.

Zurückgeben der Produktinformationen mithilfe der GetProducts() -Methode

Abbildung 1: Zurückgeben der Produktinformationen mithilfe der GetProducts() Methode (Klicken, um das Bild in voller Größe anzuzeigen)

Nach Abschluss des ObjectDataSource-Assistenten erstellt Visual Studio automatisch eine ItemTemplate für die DataList. Ersetzen Sie dies durch eine ItemTemplate , die jeden Produktnamen und -preis anzeigt und eine Schaltfläche "Bearbeiten" enthält. Erstellen Sie als Nächstes ein EditItemTemplate TextBox-Websteuerelement für Namen und Preis sowie Schaltflächen "Aktualisieren" und "Abbrechen". Legen Sie schließlich die DataList-Eigenschaft RepeatColumns auf 2 fest.

Nach diesen Änderungen sollte das deklarative Markup der Seite wie folgt aussehen. Überprüfen Sie, ob für die Schaltflächen "Bearbeiten", "Abbrechen" und "Aktualisieren" die Eigenschaften CommandName entsprechend "Bearbeiten", "Abbrechen" und "Aktualisieren" festgelegt sind.

<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>

Hinweis

Für dieses Lernprogramm muss der Ansichtszustand von DataList aktiviert sein.

Nehmen Sie sich einen Moment Zeit, um unseren Fortschritt in einem Browser anzusehen (siehe Abbildung 2).

Jedes Produkt enthält eine Schaltfläche

Abbildung 2: Jedes Produkt enthält eine Schaltfläche "Bearbeiten" (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Derzeit bewirkt die Schaltfläche "Bearbeiten" nur einen Postback, der das Produkt noch nicht bearbeitbar macht. Um die Bearbeitung zu aktivieren, müssen wir Ereignishandler für die DataList-Ereignisse EditCommand, CancelCommand und UpdateCommand erstellen. Die EditCommand und CancelCommand Ereignisse aktualisieren einfach die Eigenschaft der DataList EditItemIndex und binden die Daten erneut an die 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

Der UpdateCommand Ereignishandler ist etwas komplexer. Die Produktinformationen müssen aus dem bearbeiteten Produkt ProductID der DataKeys-Sammlung zusammen mit dem Produktnamen und -preis, die aus den Textboxen im EditItemTemplate stammen, eingelesen werden. Anschließend sollte die Methode UpdateProduct der Klasse ProductsBLL aufgerufen werden, bevor die DataList in ihren Zustand vor der Bearbeitung zurückversetzt wird.

Lassen Sie uns jetzt einfach den genauen Code aus dem Ereignishandler in der UpdateCommandÜbersicht über das Bearbeiten und Löschen von Daten im DataList-Lernprogramm verwenden. Wir fügen den Code hinzu, um Ausnahmen in Schritt 2 ordnungsgemäß zu behandeln.

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

Bei ungültiger Eingabe, die sich in Form eines nicht ordnungsgemäß formatierten Einzelpreises, eines unzulässigen Einzelpreiswerts wie -5,00 $ oder des Auslassens des Produktnamens äußern kann, wird eine Ausnahme ausgelöst. Da der UpdateCommand Ereignishandler an diesem Punkt keinen Ausnahmebehandlungscode enthält, wird die Ausnahme an die ASP.NET-Laufzeitumgebung weitergereicht, wo sie dem Endbenutzer angezeigt wird (siehe Abbildung 3).

Wenn eine unbehandelte Ausnahme auftritt, sieht der Endbenutzer eine Fehlerseite.

Abbildung 3: Wenn eine unbehandelte Ausnahme auftritt, sieht der Endbenutzer eine Fehlerseite.

Schritt 2: Ordnungsgemäße Behandlung von Ausnahmen im UpdateCommand-Ereignishandler

Während des Aktualisierungsworkflows können Ausnahmen im Ereignishandler, in der UpdateCommand BLL oder im DAL auftreten. Wenn ein Benutzer beispielsweise einen Preis für zu teuer eingibt, löst die Decimal.Parse Anweisung im UpdateCommand Ereignishandler eine FormatException Ausnahme aus. Wenn der Benutzer den Produktnamen ausgelassen oder der Preis einen negativen Wert aufweist, löst die DAL eine Ausnahme aus.

Wenn eine Ausnahme auftritt, möchten wir eine informative Meldung innerhalb der Seite selbst anzeigen. Fügen Sie der Seite ein Bezeichnungs-Websteuerelement hinzu, dessen ID auf ExceptionDetails eingestellt ist. Konfigurieren Sie den Text der Bezeichnung so, dass er in einer roten, extra großen, fett und kursiv formatierten Schriftart angezeigt wird, indem Sie der CssClass CSS-Klasse, die in der Warning Datei definiert ist, seine Styles.css Eigenschaft zuweisen.

Wenn ein Fehler auftritt, soll das Label nur einmal angezeigt werden. Das heißt, bei nachfolgenden Postbacks sollte die Warnmeldung des Labels verschwinden. Dies kann erreicht werden, indem entweder die Eigenschaft des Labels Text gelöscht oder seine Visible Eigenschaft False in dem Page_Load-Ereignishandler festgelegt wird (wie wir es in Behandlung von BLL- und DAL-Level-Ausnahmen auf einer ASP.NET-Seite getan haben) oder durch Deaktivieren der ViewState-Unterstützung des Labels. Lassen Sie uns die letztere Option verwenden.

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

Wenn eine Ausnahme ausgelöst wird, weisen wir die Details der Ausnahme der Eigenschaft des ExceptionDetails Bezeichnungssteuerelements Text zu. Da der Ansichtszustand deaktiviert ist, gehen bei nachfolgenden Postbacks die programmgesteuerten Änderungen der Text Eigenschaft verloren, und sie werden wieder auf den Standardtext zurückgesetzt (eine leere Zeichenfolge), wodurch die Warnmeldung ausgeblendet wird.

Um festzustellen, wann ein Fehler ausgelöst wurde, um eine hilfreiche Meldung auf der Seite anzuzeigen, müssen wir dem Try ... Catch Ereignishandler einen UpdateCommand Block hinzufügen. Der Try Teil enthält Code, der zu einer Ausnahme führen kann, während der Catch Block Code enthält, der im Gesicht einer Ausnahme ausgeführt wird. Sehen Sie sich den Abschnitt Grundlagen der Fehlerbehandlung in der .NET Framework-Dokumentation an, um weitere Informationen zum Try ... Catch Block zu erhalten.

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

Wenn eine Ausnahme eines beliebigen Typs vom Code innerhalb des Try-Blocks ausgelöst wird, beginnt der Code im Catch-Block auszuführen. Die Art der Ausnahme, die ausgelöst DbExceptionwird, NoNullAllowedException, ArgumentException, usw. hängt davon ab, was genau, den Fehler an erster Stelle ausgelöst hat. Wenn auf Datenbankebene ein Problem auftritt, wird ein DbException Fehler ausgelöst. Wenn ein ungültiger Wert für die Felder UnitPrice, UnitsInStock, UnitsOnOrder oder ReorderLevel eingegeben wird, wird eine ArgumentException ausgelöst, da wir Code zum Überprüfen dieser Feldwerte in der ProductsDataTable-Klasse hinzugefügt haben (siehe das Creating a Business Logic Layer Tutorial).

Wir können dem Endbenutzer eine hilfreichere Erklärung bereitstellen, indem wir den Nachrichtentext auf dem Typ der erfassten Ausnahme basieren. Der folgende Code, der in nahezu identischer Form im Tutorial Behandlung von BLL- und DAL-Level-Ausnahmen in einer ASP.NET-Seite verwendet wurde, enthält diese Detailebene.

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

Um dieses Lernprogramm abzuschließen, rufen Sie einfach die DisplayExceptionDetails-Methode aus dem Catch-Block auf und übergeben Sie dabei die abgefangene Exception-Instanz (ex).

Wenn der Try ... Catch Block vorhanden ist, wird den Benutzern eine informativere Fehlermeldung angezeigt, wie abbildung 4 und 5 zeigen. Beachten Sie, dass die DataList angesichts einer Ausnahme im Bearbeitungsmodus verbleibt. Dies liegt daran, dass, sobald die Ausnahme auftritt, der Steuerfluss sofort an den Catch-Block umgeleitet wird und dabei den Code umgeht, der die DataList in ihren Zustand vor der Bearbeitung zurückversetzt.

Eine Fehlermeldung wird angezeigt, wenn ein Benutzer ein Pflichtfeld ausgelassen.

Abbildung 4: Eine Fehlermeldung wird angezeigt, wenn ein Benutzer ein erforderliches Feld ausgelassen (Klicken, um das Bild in voller Größe anzuzeigen)

Beim Eingeben eines negativen Preises wird eine Fehlermeldung angezeigt.

Abbildung 5: Beim Eingeben eines negativen Preises wird eine Fehlermeldung angezeigt (Zum Anzeigen des Bilds mit voller Größe klicken)

Zusammenfassung

GridView und ObjectDataSource stellen Ereignishandler auf Postebene bereit, die Informationen zu Ausnahmen enthalten, die während des Aktualisierungs- und Löschworkflows aufgetreten sind, sowie Eigenschaften, die festgelegt werden können, um anzugeben, ob die Ausnahme behandelt wurde. Diese Features sind jedoch nicht verfügbar, wenn Sie mit der DataList arbeiten und die BLL direkt verwenden. Stattdessen sind wir für die Implementierung der Ausnahmebehandlung verantwortlich.

In diesem Tutorial haben wir gesehen, wie wir einem Aktualisierungsworkflow einer bearbeitbaren DataList eine Ausnahmebehandlung hinzufügen, indem wir dem Try ... Catch-Ereignishandler einen UpdateCommand-Block hinzufügen. Wenn während des Aktualisierungsworkflows eine Ausnahme ausgelöst wird, wird der Catch Code des Blocks ausgeführt, um hilfreiche Informationen im ExceptionDetails Label anzuzeigen.

An diesem Punkt unternimmt DataList keine Anstrengungen, Ausnahmen von vornherein zu verhindern. Obwohl wir wissen, dass ein negativer Preis zu einer Ausnahme führt, haben wir noch keine Funktionalität hinzugefügt, um proaktiv zu verhindern, dass ein Benutzer eine solche ungültige Eingabe eingibt. In unserem nächsten Lernprogramm erfahren Sie, wie Sie die Ausnahmen verringern können, die durch ungültige Benutzereingaben verursacht werden, indem Sie Überprüfungssteuerelemente in der EditItemTemplateDatei hinzufügen.

Glückliche Programmierung!

Weitere Lektüre

Weitere Informationen zu den in diesem Lernprogramm erläuterten Themen finden Sie in den folgenden Ressourcen:

Zum Autor

Scott Mitchell, Autor von sieben ASP/ASP.NET Büchern und Gründer von 4GuysFromRolla.com, arbeitet seit 1998 mit Microsoft Web Technologies zusammen. Scott arbeitet als unabhängiger Berater, Trainer und Schriftsteller. Sein neuestes Buch ist Sams Teach Yourself ASP.NET 2.0 in 24 Stunden. Er kann bei mitchell@4GuysFromRolla.comerreicht werden.

Besonderer Dank an

Diese Lernprogrammreihe wurde von vielen hilfreichen Prüfern überprüft. Leitender Prüfer für dieses Lernprogramm war Ken Pespisa. Möchten Sie meine bevorstehenden MSDN-Artikel überprüfen? Wenn ja, schicken Sie mir eine Nachricht an mitchell@4GuysFromRolla.com.