Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
von Scott Mitchell
In dieser Anleitung wird gezeigt, wie Sie Ausnahmen, die während des Aktualisierungsvorgangs einer bearbeitbaren DataList ausgelöst werden, geschickt behandeln.
Einleitung
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 Handling von BLL- und DAL-Level-Ausnahmen in einem ASP.NET-Tutorial 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 Updated- oder RowUpdated-Ereignishandler für die ObjectDataSource oder GridView erstellen, eine Ausnahme überprüfen und dann angeben, dass die Ausnahme abgefangen 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 Tutorial erfahren Sie, wie Sie Ausnahmen, die während eines Aktualisierungsworkflows für eine bearbeitbare DataList ausgelöst wurden, taktvoller behandeln.
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 auf 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.
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" ihre Eigenschaften auf CommandName "Bearbeiten", "Abbrechen" bzw. "Aktualisieren" festgelegt haben.
<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 im Browser anzusehen (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 erstellen. Die EditCommand- und CancelCommand-Ereignisse aktualisieren die Eigenschaft EditItemIndex der DataList und binden die Daten einfach neu 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 komplexer. Sie muss das bearbeitete Produkt ProductID aus der DataKeys Sammlung zusammen mit dem Produktnamen und dem Preis aus den Textfeldern in EditItemTemplate lesen und dann die Methode ProductsBLL der UpdateProduct Klasse aufrufen, bevor sie die DataList in den Zustand vor der Bearbeitung 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 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 einer ungültigen Eingabe, die in Form eines nicht ordnungsgemäß formatierten Einzelpreises, eines unzulässigen Einzelpreiswerts wie -5,00 $, oder dem Fehlen des Produktnamens auftreten kann, wird eine Ausnahme ausgelöst. Da der UpdateCommand Ereignishandler an diesem Punkt keinen Ausnahmebehandlungscode enthält, wird die Ausnahme bis zur ASP.NET-Laufzeit durchgereicht, 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 UpdateCommand Ereignishandler, in der 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 Bezeichnungssteuerelement hinzu, dessen ID auf ExceptionDetails gesetzt 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 ausgeblendet werden. Dies kann erreicht werden, indem entweder die Text-Eigenschaft des Labels gelöscht oder ihre Visible-Eigenschaft im False-Ereignishandler auf Page_Load festgelegt wird (wie wir es im Tutorial Behandlung von BLL- und DAL-Level-Ausnahmen auf einer ASP.NET-Seite getan haben) oder durch Deaktivieren der Unterstützung des Ansichtszustands 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 ExceptionDetails Label-Steuerelements Text Eigenschaft 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. Weitere Informationen zum Block finden Sie im Abschnitt "Grundlagen zur Ausnahmebehandlung" in der Try ... Catch .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 vom Code innerhalb des Try Blocks ausgelöst wird, beginnt der Code im Catch Block mit der Ausführung. 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 UnitPriceFelder , UnitsInStock, oder UnitsOnOrderReorderLevel 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).
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 bereits im Tutorial Behandlung von BLL- und DAL-Level-Ausnahmen auf einer ASP.NET-Seite verwendet wurde, bietet dieses Detailniveau:
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 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 Kontrollfluss sofort an den Catch Block umgeleitet wird und den Code umgeht, der die DataList in ihren Zustand vor der Bearbeitung zurückversetzt.
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 Ereignisebene 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 zu bestimmen, ob die Ausnahme behandelt wurde oder nicht. 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 gelernt, wie Sie einem aktualisierbaren Workflow einer DataList-Ausnahmebehandlung hinzufügen, indem Sie einen Try ... Catch-Block dem UpdateCommand-Ereignishandler hinzufügen. Wenn während des Aktualisierungsworkflows eine Ausnahme auftritt, wird der Codeblock Catch ausgeführt und gibt nützliche Informationen in der ExceptionDetails Beschriftung aus.
Zu diesem Zeitpunkt bemüht sich DataList nicht, 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 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 (enthält den 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 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.