Verarbeiten von Ausnahmen auf BLL- und DAL-Ebene (VB)
von Scott Mitchell
In diesem Lernprogramm wird gezeigt, wie Sie ausnahmen, die während des Aktualisierungsworkflows eines bearbeitbaren DataList-Elements 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 in der Behandlung von BLL- und DAL-Level-Ausnahmen in einem lernprogramm für ASP.NET Seite gesehen haben, werden die Ausnahmedetails an die ObjectDataSource und dann an das GridView zurückgegeben, wenn eine Ausnahme aus den Tiefen der Geschäftslogik- oder Datenzugriffsebenen ausgelöst wird. Wir haben gesehen, wie diese Ausnahmen ordnungsgemäß behandelt werden, indem wir Handler für ObjectDataSource oder GridView erstellen Updated
oder RowUpdated
Ereignishandler erstellen, eine Ausnahme überprüfen 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 Lernprogramm erfahren Sie, wie Sie ausnahmen, die während eines Aktualisierungsworkflows für bearbeitbare DataList ausgelöst wurden, taktvoller behandeln.
Hinweis
In the An Overview of Editing and Deleting Data in the DataList tutorial we discussed different techniques for editing and deleting data from the DataList, Some techniques involved using an ObjectDataSource for updating and deleting. 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 fest Products
, 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.
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 die Schaltflächen "Bearbeiten", "Abbrechen" und "Aktualisieren" auf CommandName
"Bearbeiten", "Abbrechen" bzw. "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 über einen Browser anzuzeigen (siehe Abbildung 2).
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
Ereignisse erstellen. Die EditCommand
Daten und CancelCommand
Ereignisse aktualisieren einfach die DataList-Eigenschaft EditItemIndex
und binden die Daten an die DataList neu:
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 mehr beteiligt. Sie muss in den bearbeiteten Produktangaben ProductID
aus der DataKeys
Sammlung zusammen mit dem Produktnamen und -preis aus den TextBoxes im TextBoxes lesen EditItemTemplate
und dann die Methode der ProductsBLL
Klasse UpdateProduct
aufrufen, bevor sie die DataList in den Vorbearbeitungszustand zurückgibt.
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
Angesichts einer ungültigen Eingabe, die sich in Form eines nicht ordnungsgemäß formatierten Einzelpreiss ergeben kann, wird ein unzulässiger Einzelpreiswert wie -5,00 $ oder das Auslassen des Produktnamens ausgelöst. Da der UpdateCommand
Ereignishandler an diesem Punkt keinen Ausnahmebehandlungscode enthält, wird die Ausnahme bis zur ASP.NET Laufzeit eingeblendet, wo sie dem Endbenutzer angezeigt wird (siehe Abbildung 3).
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 Bezeichnungswebsteuerelement hinzu, dessen ID
Einstellung auf " ExceptionDetails
. 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 Warning
CSS-Klasse, die in der Styles.css
Datei definiert ist, seine CssClass
Eigenschaft zuweisen.
Wenn ein Fehler auftritt, soll die Bezeichnung nur einmal angezeigt werden. Das heißt, bei nachfolgenden Postbacks sollte die Warnmeldung "Bezeichnung" ausgeblendet werden. Dies kann erreicht werden, indem entweder die Eigenschaft der Bezeichnung Text
gelöscht oder ihre Visible
Eigenschaft False
im Page_Load
Ereignishandler festgelegt wird (wie wir es in der Behandlung von BLL- und DAL-Level-Ausnahmen in einem Lernprogramm für ASP.NET Seite getan haben) oder durch Deaktivieren der Unterstützung des Ansichtszustands von Bezeichnungen. 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 UpdateCommand
Ereignishandler einen Try ... Catch
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. Weitere Informationen zum Block finden Sie im Abschnitt "Grundlagen zur Ausnahmebehandlung" in der Try ... Catch
.NET Framework-Dokumentation.
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 Blockcode mit der Catch
Ausführung. Die Art der Ausnahme, die ausgelöst DbException
wird, 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 , UnitsInStock
, oder UnitsOnOrder
ReorderLevel
Felder eingegeben wird, wird eine ArgumentException
ausgelöst, da wir Code zum Überprüfen dieser Feldwerte in der ProductsDataTable
Klasse hinzugefügt haben (siehe Lernprogramm zum Erstellen einer Geschäftslogikebene).UnitPrice
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 wieder in der Behandlung von BLL- und DAL-Level-Ausnahmen in einem lernprogramm für 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 vom Catch
Block auf, der die abgefangene Exception
Instanz (ex
) übergibt.
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 der Ablauf des Steuerelements sofort an den Catch
Block umgeleitet wird und den Code, der die DataList zurückgibt, in den Zustand vor der Bearbeitung umgeleitet wird.
Abbildung 4: Eine Fehlermeldung wird angezeigt, wenn ein Benutzer ein erforderliches Feld ausgelassen (Klicken, um das Bild in voller Größe anzuzeigen)
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 Ebene der Ebene bereit, die Informationen zu ausnahmen enthalten, die während des Aktualisierungs- und Löschworkflows ausgelöst wurden, 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 Lernprogramm haben wir erfahren, wie Sie einem Aktualisierungsworkflow einer bearbeitbaren DataList-Liste Eine Ausnahmebehandlung hinzufügen, indem Sie dem UpdateCommand
Ereignishandler einen Try ... Catch
Block hinzufügen. Wenn während des Aktualisierungsworkflows eine Ausnahme ausgelöst wird, wird der Catch
Code des Blocks ausgeführt und zeigt hilfreiche Informationen in der ExceptionDetails
Bezeichnung an.
An diesem Punkt bemüht sich DataList nicht, ausnahmen an erster Stelle 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 EditItemTemplate
Datei hinzufügen.
Glückliche Programmierung!
Weitere nützliche Informationen
Weitere Informationen zu den in diesem Lernprogramm erläuterten Themen finden Sie in den folgenden Ressourcen:
- Entwurfsrichtlinien für Ausnahmen
- Fehlerprotokollierungsmodule und -Handler (ELMAH) (eine Open-Source-Bibliothek für Protokollierungsfehler)
- Enterprise Library for .NET Framework 2.0 (includes the Exception Management Application Block)
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 über mitchell@4GuysFromRolla.com seinen Blog erreicht werden, der unter .http://ScottOnWriting.NET
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 dies der Fall ist, legen Sie mir eine Zeile bei mitchell@4GuysFromRolla.com.