Share via


Verarbeiten von Ausnahmen auf BLL- und DAL-Ebene (C#)

von Scott Mitchell

PDF herunterladen

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

Einführung

Im Tutorial Übersicht über das Bearbeiten und Löschen von Daten im DataList-Tutorial haben wir eine DataList erstellt, die einfache Bearbeitungs- und Löschfunktionen bietet. Obwohl es voll funktionsfähig ist, war es kaum benutzerfreundlich, da jeder Fehler, der während des Bearbeitungs- oder Löschvorgangs aufgetreten ist, zu einer nicht behandelten Ausnahme führte. Wenn Sie z. B. den Namen des Produkts weglassen oder beim Bearbeiten eines Produkts einen Preiswert von Very affordable! eingeben, wird eine Ausnahme ausgelöst. Da diese Ausnahme nicht im Code erfasst wird, wird sie bis zur ASP.NET Runtime angezeigt, die dann die Details der Ausnahme auf der Webseite anzeigt.

Wie wir im Tutorial Behandeln von BLL- und DAL-Level-Ausnahmen in einer ASP.NET Seite gezeigt haben, werden die Ausnahmedetails an die ObjectDataSource und dann an die 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 können, indem Sie Ereignishandler für objectDataSource oder GridView erstellen UpdatedRowUpdated , auf eine Ausnahme überprüfen und dann angeben, dass die Ausnahme behandelt wurde.

In unseren DataList-Tutorials wird objectDataSource jedoch nicht zum Aktualisieren und Löschen von Daten verwendet. Stattdessen arbeiten wir direkt gegen die BLL. Um Ausnahmen zu erkennen, die von der BLL oder DAL stammen, müssen wir Ausnahmebehandlungscode im CodeBehind unserer ASP.NET-Seite implementieren. In diesem Tutorial erfahren Sie, wie Sie Ausnahmen, die während eines bearbeitbaren DataList-Aktualisierungsworkflows ausgelöst werden, taktvoller behandeln.

Hinweis

Im Tutorial Eine Übersicht über das Bearbeiten und Löschen von Daten im DataList-Tutorial haben wir verschiedene Techniken zum Bearbeiten und Löschen von Daten aus der DataList erläutert. Einige Techniken, die bei der Verwendung einer ObjectDataSource zum Aktualisieren und Löschen erforderlich sind. Wenn Sie diese Techniken verwenden, können Sie Ausnahmen von der BLL oder DAL über die ObjectDataSource- Updated oder Deleted -Ereignishandler behandeln.

Schritt 1: Erstellen einer bearbeitbaren DataList

Bevor wir uns um die Behandlung von Ausnahmen kümmern, 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 die ID -Eigenschaft auf Productsfest, und fügen Sie eine neue ObjectDataSource mit dem Namen hinzuProductsDataSource. Konfigurieren Sie objectDataSource so, dass die Methode der ProductsBLL Klasse s 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 Sie hier, 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 diese durch einen ItemTemplate , der den Namen und den Preis jedes Produkts anzeigt und eine Schaltfläche Bearbeiten enthält. Erstellen Sie als Nächstes ein EditItemTemplate mit einem TextBox-Websteuerelement für Name und Preis sowie die Schaltflächen Aktualisieren und Abbrechen. Legen Sie schließlich die DataList-Eigenschaft RepeatColumns auf 2 fest.

Nach diesen Änderungen sollte das deklarative Markup Ihrer Seite wie folgt aussehen. Überprüfen Sie, ob die Eigenschaften der Schaltflächen Bearbeiten, Abbrechen und Aktualisieren auf Bearbeiten, Abbrechen und Aktualisieren festgelegt sind 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>

Hinweis

Für dieses Tutorial muss der Ansichtsstatus der DataList aktiviert sein.

Nehmen Sie sich einen Moment Zeit, um unseren Fortschritt über einen Browser anzuzeigen (siehe Abbildung 2).

Jedes Produkt enthält eine Schaltfläche

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

Derzeit bewirkt die Schaltfläche Bearbeiten nur ein Postback, da das Produkt noch nicht bearbeitbar ist. Um die Bearbeitung zu aktivieren, müssen wir Ereignishandler für die DataList-Ereignisse EditCommand, CancelCommandund UpdateCommand erstellen. Die EditCommand Ereignisse und CancelCommand aktualisieren einfach die DataList-Eigenschaft und EditItemIndex binden die Daten erneut an die DataList:

protected void Products_EditCommand(object source, DataListCommandEventArgs e)
{
    // 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();
}
protected void Products_CancelCommand(object source, DataListCommandEventArgs e)
{
    // Set the DataList's EditItemIndex property to -1
    Products.EditItemIndex = -1;
    // Rebind the data to the DataList
    Products.DataBind();
}

Der UpdateCommand Ereignishandler ist etwas stärker involviert. Es muss die bearbeiteten Product s ProductID aus der DataKeys Auflistung zusammen mit dem Namen des Produkts und dem Preis aus den TextBoxes in der EditItemTemplatelesen und dann die Methode s UpdateProduct der ProductsBLL Klasse aufrufen, bevor die DataList in den Zustand vor der Bearbeitung zurückgegeben wird.

Verwenden Sie vorerst nur den genau gleichen Code aus dem UpdateCommand Ereignishandler im Tutorial Übersicht über das Bearbeiten und Löschen von Daten im DataList-Tutorial . Wir fügen den Code hinzu, um Ausnahmen in Schritt 2 ordnungsgemäß zu behandeln.

protected void Products_UpdateCommand(object source, DataListCommandEventArgs e)
{
    // Read in the ProductID from the DataKeys collection
    int productID = Convert.ToInt32(Products.DataKeys[e.Item.ItemIndex]);
    // Read in the product name and price values
    TextBox productName = (TextBox)e.Item.FindControl("ProductName");
    TextBox unitPrice = (TextBox)e.Item.FindControl("UnitPrice");
    string productNameValue = null;
    if (productName.Text.Trim().Length > 0)
        productNameValue = productName.Text.Trim();
    decimal? unitPriceValue = null;
    if (unitPrice.Text.Trim().Length > 0)
        unitPriceValue = Decimal.Parse(unitPrice.Text.Trim(),
            System.Globalization.NumberStyles.Currency);
    // Call the ProductsBLL's UpdateProduct method...
    ProductsBLL productsAPI = new ProductsBLL();
    productsAPI.UpdateProduct(productNameValue, unitPriceValue, productID);
    // Revert the DataList back to its pre-editing state
    Products.EditItemIndex = -1;
    Products.DataBind();
}

Angesichts ungültiger Eingaben, die in Form eines nicht ordnungsgemäß formatierten Einzelpreises, eines unzulässigen Einzelpreiswerts wie -5,00 USD oder des Weglassens des Produktnamens sein können, wird eine Ausnahme ausgelöst. Da der UpdateCommand Ereignishandler an diesem Punkt keinen Ausnahmebehandlungscode enthält, wird die Ausnahme bis zur ASP.NET Runtime angezeigt, wo sie dem Endbenutzer angezeigt wird (siehe Abbildung 3).

Wenn eine nicht behandelte Ausnahme auftritt, wird dem Endbenutzer eine Fehlerseite angezeigt.

Abbildung 3: Wenn eine nicht behandelte Ausnahme auftritt, wird dem Endbenutzer eine Fehlerseite angezeigt.

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

Während des Aktualisierungsworkflows können Ausnahmen im UpdateCommand Ereignishandler, der BLL oder der DAL auftreten. Wenn ein Benutzer beispielsweise den Preis "Zu teuer" eingibt, löst die Decimal.Parse Anweisung im UpdateCommand Ereignishandler eine Ausnahme aus FormatException . Wenn der Benutzer den Namen des Produkts auslässt oder der Preis einen negativen Wert aufweist, löst die DAL eine Ausnahme aus.

Wenn eine Ausnahme auftritt, möchten wir eine informative Nachricht auf der Seite selbst anzeigen. Fügen Sie der Seite, deren ID Einstellung auf ExceptionDetailsfestgelegt ist, ein Label-Websteuerelement hinzu. Konfigurieren Sie den Text der Bezeichnung so, dass er in einer roten, extra großen, fetten und kursiven Schriftart angezeigt wird, indem Sie die CssClass -Eigenschaft der Warning CSS-Klasse zuweisen, die in der Styles.css Datei definiert ist.

Wenn ein Fehler auftritt, soll die Bezeichnung nur einmal angezeigt werden. Das heißt, bei nachfolgenden Postbacks sollte die Warnmeldung der Bezeichnung ausgeblendet werden. Dies kann erreicht werden, indem sie entweder die Eigenschaft der Bezeichnung auslöscht oder deren Eigenschaft im Page_Load Ereignishandler auf False festgelegt wird (wie im Tutorial Behandeln von BLL- und DAL-Level Ausnahmen in einer ASP.NET Seite) oder durch Deaktivieren der Unterstützung für den Ansichtsstatus der Bezeichnung.VisibleText Lassen Sie uns die letzte 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 Label-Steuerelements Text zu. Da der Ansichtszustand deaktiviert ist, gehen bei nachfolgenden Postbacks die programmgesteuerten Änderungen der Text Eigenschaft verloren, wodurch der Standardtext (eine leere Zeichenfolge) zurückgesetzt wird, wodurch die Warnmeldung ausgeblendet wird.

Um festzustellen, wann ein Fehler ausgelöst wurde, um eine hilfreiche Nachricht 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 Angesicht einer Ausnahme ausgeführt wird. Weitere Informationen Try ... Catch zum Block finden Sie im Abschnitt Grundlagen der Ausnahmebehandlung in der .NET Framework-Dokumentation.

protected void Products_UpdateCommand(object source, DataListCommandEventArgs e)
{
    // Handle any exceptions raised during the editing process
    try
    {
        // Read in the ProductID from the DataKeys collection
        int productID = Convert.ToInt32(Products.DataKeys[e.Item.ItemIndex]);
        ... Some code omitted for brevity ...
    }
    catch (Exception ex)
    {
        // TODO: Display information about the exception in ExceptionDetails
    }
}

Wenn eine Ausnahme eines beliebigen Typs durch Code innerhalb des Try Blocks ausgelöst wird, beginnt der Code des Blocks mit der Catch Ausführung. Die Art der Ausnahme, die ausgelöst DbExceptionNoNullAllowedExceptionwird, , , ArgumentExceptionusw. hängt davon ab, was genau den Fehler ausgelöst hat. Wenn auf Datenbankebene ein Problem auftritt, wird ein DbException ausgelöst. Wenn ein ungültiger Wert für die UnitPriceFelder , UnitsInStock, UnitsOnOrderoder ReorderLevel eingegeben wird, wird ein ArgumentException ausgelöst, während wir Code hinzugefügt haben, um diese Feldwerte in der ProductsDataTable Klasse zu überprüfen (siehe Tutorial Erstellen einer Geschäftslogikebene ).

Wir können dem Endbenutzer eine hilfreichere Erklärung bieten, indem wir den Nachrichtentext auf dem Typ der abgefangenen Ausnahme stützen. Der folgende Code, der in nahezu identischer Form im Tutorial Behandeln von BLL- und DAL-Level-Ausnahmen in einer ASP.NET Page verwendet wurde, bietet diese Detailebene:

private void DisplayExceptionDetails(Exception ex)
{
    // Display a user-friendly message
    ExceptionDetails.Text = "There was a problem updating the product. ";
    if (ex is System.Data.Common.DbException)
        ExceptionDetails.Text += "Our database is currently experiencing problems.
            Please try again later.";
    else if (ex is NoNullAllowedException)
        ExceptionDetails.Text += "There are one or more required fields that are
            missing.";
    else if (ex is ArgumentException)
    {
        string paramName = ((ArgumentException)ex).ParamName;
        ExceptionDetails.Text +=
            string.Concat("The ", paramName, " value is illegal.");
    }
    else if (ex is ApplicationException)
        ExceptionDetails.Text += ex.Message;
}

Um dieses Tutorial abzuschließen, rufen Sie einfach die DisplayExceptionDetails -Methode aus dem Block auf, der Catch den abgefangenen Exception instance (ex) übergibt.

Wenn der Try ... Catch Block vorhanden ist, wird den Benutzern eine informativere Fehlermeldung angezeigt, wie Abbildungen 4 und 5 zeigen. Beachten Sie, dass die DataList angesichts einer Ausnahme im Bearbeitungsmodus verbleibt. Dies liegt daran, dass der Ablauf der Steuerung sofort an den Catch Block weitergeleitet wird, nachdem die Ausnahme auftritt. Dabei wird der Code umgangen, der die DataList in den Zustand vor der Bearbeitung zurückgibt.

Eine Fehlermeldung wird angezeigt, wenn ein Benutzer ein erforderliches Feld auslässt.

Abbildung 4: Eine Fehlermeldung wird angezeigt, wenn ein Benutzer ein erforderliches Feld auslässt (Klicken Sie, 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 (Klicken Sie, um das bild in voller Größe anzuzeigen)

Zusammenfassung

GridView und ObjectDataSource stellen Post-Level-Ereignishandler bereit, die Informationen zu allen 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 oder nicht. Diese Features sind jedoch nicht verfügbar, wenn Sie mit dataList arbeiten und die BLL direkt verwenden. Stattdessen sind wir für die Implementierung der Ausnahmebehandlung verantwortlich.

In diesem Tutorial haben wir erfahren, wie Sie einem bearbeitbaren DataList-Aktualisierungsworkflow 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 unternimmt die DataList keine Anstrengungen, um Ausnahmen überhaupt 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 Tutorial erfahren Sie, wie Sie die Durch ungültige Benutzereingaben verursachten Ausnahmen reduzieren können, indem Sie Validierungssteuerelemente in hinzufügen EditItemTemplate.

Viel Spaß beim Programmieren!

Weitere Informationen

Weitere Informationen zu den in diesem Tutorial 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-Webtechnologien. Scott arbeitet als unabhängiger Berater, Trainer und Autor. Sein neuestes Buch ist Sams Teach Yourself ASP.NET 2.0 in 24 Stunden. Er kann unter mitchell@4GuysFromRolla.comoder über seinen Blog erreicht werden, der unter http://ScottOnWriting.NETzu finden ist.

Besonderer Dank an

Diese Tutorialreihe wurde von vielen hilfreichen Prüfern überprüft. Lead Reviewer für dieses Tutorial war Ken Pespisa. Möchten Sie meine bevorstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie eine Zeile unter abmitchell@4GuysFromRolla.com.