Obsługa wyjątków na poziomie warstwy logiki biznesowej i warstwy dostępu do danych (VB)
Autor : Scott Mitchell
W tym samouczku zobaczymy, jak tactfully obsługiwać wyjątki zgłaszane podczas aktualizowania przepływu pracy edytowalnego elementu DataList.
Wprowadzenie
W samouczku Omówienie edytowania i usuwania danych w usłudze DataList utworzyliśmy element DataList, który oferował proste możliwości edytowania i usuwania. Chociaż w pełni funkcjonalna, nie była przyjazna dla użytkownika, ponieważ każdy błąd, który wystąpił podczas procesu edytowania lub usuwania, spowodował nieobsługiwany wyjątek. Na przykład pominięcie nazwy produktu lub, podczas edytowania produktu, wprowadzenie wartości ceny o bardzo przystępnej cenie!, zgłasza wyjątek. Ponieważ ten wyjątek nie jest przechwytywane w kodzie, jest on bąbelkowy do środowiska uruchomieniowego ASP.NET, który następnie wyświetla szczegóły wyjątku na stronie internetowej.
Jak pokazano w samouczku Obsługa wyjątków BLL i DAL-Level na stronie ASP.NET , jeśli wyjątek zostanie zgłoszony z głębi warstwy logiki biznesowej lub dostępu do danych, szczegóły wyjątku są zwracane do obiektu ObjectDataSource, a następnie do kontrolki GridView. Zobaczyliśmy, jak bezpiecznie obsługiwać te wyjątki, tworząc Updated
programy RowUpdated
obsługi zdarzeń dla obiektu ObjectDataSource lub GridView, sprawdzając wyjątek, a następnie wskazując, że wyjątek został obsłużony.
Nasze samouczki DataList nie używają jednak obiektu ObjectDataSource do aktualizowania i usuwania danych. Zamiast tego pracujemy bezpośrednio nad BLL. Aby wykryć wyjątki pochodzące z biblioteki BLL lub DAL, musimy zaimplementować kod obsługi wyjątków w obrębie kodu strony ASP.NET. W tym samouczku zobaczymy, jak bardziej tactfully obsługiwać wyjątki zgłaszane podczas edytowalnego przepływu pracy aktualizacji elementu DataList.
Uwaga
W samouczku Omówienie edytowania i usuwania danych w usłudze DataList omówiliśmy różne techniki edytowania i usuwania danych z listy DataList, niektóre techniki związane z aktualizowaniem i usuwaniem przy użyciu obiektu ObjectDataSource. Jeśli zastosujesz te techniki, możesz obsługiwać wyjątki z biblioteki BLL lub DAL za pośrednictwem procedur obsługi zdarzeń lub Deleted
obiektów ObjectDataSourceUpdated
.
Krok 1. Tworzenie edytowalnej listy danych
Zanim będziemy się martwić o obsługę wyjątków występujących podczas aktualizowania przepływu pracy, najpierw utwórzmy edytowalną listę danych. ErrorHandling.aspx
Otwórz stronę w folderzeEditDeleteDataList
, dodaj element DataList do Projektant, ustaw jej ID
właściwość na Products
, a następnie dodaj nową właściwość ObjectDataSource o nazwie ProductsDataSource
. Skonfiguruj obiekt ObjectDataSource do używania ProductsBLL
metody s GetProducts()
klasy do wybierania rekordów. Ustaw listy rozwijane na kartach INSERT, UPDATE i DELETE na wartość (Brak).
Rysunek 1. Zwracanie informacji o produkcie GetProducts()
przy użyciu metody (kliknij, aby wyświetlić obraz pełnowymiarowy)
Po ukończeniu pracy kreatora ObjectDataSource program Visual Studio automatycznie utworzy ItemTemplate
obiekt dla elementu DataList. Zastąp go wartością ItemTemplate
, która wyświetla nazwę i cenę każdego produktu i zawiera przycisk Edytuj. Następnie utwórz element EditItemTemplate
z kontrolką internetową TextBox dla nazw i cen oraz przycisków Aktualizuj i Anuluj. Na koniec ustaw właściwość DataList na RepeatColumns
2.
Po tych zmianach znaczniki deklaratywne strony powinny wyglądać podobnie do poniższych. Sprawdź dwukrotnie, aby upewnić się, że przyciski Edytuj, Anuluj i Aktualizuj mają właściwości CommandName
ustawione odpowiednio na Edytuj, Anuluj i Aktualizuj.
<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>
Uwaga
W tym samouczku należy włączyć stan widoku datalist.
Poświęć chwilę, aby wyświetlić postęp w przeglądarce (zobacz Rysunek 2).
Rysunek 2. Każdy produkt zawiera przycisk Edycji (kliknij, aby wyświetlić obraz pełnowymiarowy)
Obecnie przycisk Edytuj powoduje tylko ogłaszanie zwrotne, które nie powoduje jeszcze edytowania produktu. Aby włączyć edytowanie, musimy utworzyć programy obsługi zdarzeń dla zdarzeń datalist s EditCommand
, CancelCommand
i UpdateCommand
zdarzeń. Zdarzenia EditCommand
i CancelCommand
po prostu aktualizują właściwość DataList i EditItemIndex
ponownie pobinowane dane do listy 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
Procedura UpdateCommand
obsługi zdarzeń jest nieco bardziej zaangażowana. Musi on odczytać w edytowanych produktach ProductID
z DataKeys
kolekcji wraz z nazwą i ceną produktu z textBoxes w elemecie EditItemTemplate
, a następnie wywołać ProductsBLL
metodę klasy s UpdateProduct
przed zwróceniem elementu DataList do stanu przed edycją.
Na razie użyjemy dokładnie tego samego kodu z UpdateCommand
programu obsługi zdarzeń w samouczku Omówienie edytowania i usuwania danych w samouczku DataList . Dodamy kod, aby bezpiecznie obsługiwać wyjątki w kroku 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
W obliczu nieprawidłowych danych wejściowych, które mogą być w postaci nieprawidłowo sformatowanej ceny jednostkowej, zostanie podniesiona nieprawidłowa wartość ceny jednostkowej, na przykład -$5.00 lub pominięcie nazwy produktu. UpdateCommand
Ponieważ program obsługi zdarzeń nie zawiera w tym momencie żadnego kodu obsługi wyjątków, wyjątek będzie bąbelkować do środowiska uruchomieniowego ASP.NET, gdzie będzie on wyświetlany użytkownikowi końcowemu (zobacz Rysunek 3).
Rysunek 3. Gdy wystąpi nieobsługiwany wyjątek, użytkownik końcowy zobaczy stronę błędu
Krok 2. Bezproblemowa obsługa wyjątków w programie obsługi zdarzeń UpdateCommand
Podczas aktualizowania przepływu pracy wyjątki mogą wystąpić w procedurze UpdateCommand
obsługi zdarzeń, BLL lub DAL. Jeśli na przykład użytkownik wprowadzi cenę za zbyt drogie, Decimal.Parse
instrukcja w procedurze UpdateCommand
obsługi zdarzeń zgłosi FormatException
wyjątek. Jeśli użytkownik pomija nazwę produktu lub jeśli cena ma wartość ujemną, dal zgłosi wyjątek.
Gdy wystąpi wyjątek, chcemy wyświetlić komunikat informacyjny na samej stronie. Dodaj kontrolkę Etykieta sieci Web do strony, której ID
ustawiono wartość ExceptionDetails
. Skonfiguruj tekst Etykiety tak, aby był wyświetlany w kolorze czerwonym, bardzo dużym, pogrubionym i kursywym, przypisując jego CssClass
właściwość do Warning
klasy CSS zdefiniowanej Styles.css
w pliku.
Gdy wystąpi błąd, chcemy, aby etykieta był wyświetlana tylko raz. Oznacza to, że po kolejnych ogłaszaniu zwrotnym powinien zniknąć komunikat ostrzegawczy Etykieta. Można to osiągnąć przez wyczyszczenie właściwości Etykieta lub jej Visible
właściwości do False
w Page_Load
programie obsługi zdarzeń (tak jak w przypadku obsługi BLL i DAL-Level Wyjątki w samouczku dotyczącym strony ASP.NET) lub przez wyłączenie obsługi stanu widoku Text
etykiet. Użyjmy tej drugiej opcji.
<asp:Label ID="ExceptionDetails" EnableViewState="False" CssClass="Warning"
runat="server" />
Po wystąpieniu wyjątku przypiszemy szczegóły wyjątku do ExceptionDetails
właściwości kontrolki Etykieta Text
. Ponieważ stan widoku jest wyłączony, po kolejnych ogłaszaniu Text
zwrotnym zmiany programowe właściwości zostaną utracone, cofając się do domyślnego tekstu (pustego ciągu), co spowoduje ukrycie komunikatu ostrzegawczego.
Aby określić, kiedy został zgłoszony błąd, aby wyświetlić pomocny komunikat na stronie, musimy dodać Try ... Catch
blok do UpdateCommand
programu obsługi zdarzeń. Część Try
zawiera kod, który może prowadzić do wyjątku, podczas gdy Catch
blok zawiera kod wykonywany w obliczu wyjątku. Zapoznaj się z sekcją Podstawy obsługi wyjątków w dokumentacji .NET Framework, aby uzyskać więcej informacji na Try ... Catch
temat bloku.
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
Gdy wyjątek dowolnego typu jest zgłaszany przez kod w Try
bloku, Catch
kod bloku rozpocznie wykonywanie. Typ wyjątku, który jest zgłaszany DbException
, NoNullAllowedException
, ArgumentException
i tak dalej zależy od tego, co dokładnie, wytrąciło błąd w pierwszej kolejności. Jeśli wystąpi problem na poziomie bazy danych, DbException
zostanie zgłoszony błąd. Jeśli dla pól , , UnitsInStock
, UnitsOnOrder
lub ReorderLevel
zostanie wprowadzona UnitPrice
niedozwolona wartość, ArgumentException
zostanie zgłoszony kod, ponieważ dodaliśmy kod umożliwiający zweryfikowanie tych wartości pól w ProductsDataTable
klasie (zobacz samouczek Tworzenie warstwy logiki biznesowej).
Możemy udostępnić użytkownikowi końcowemu bardziej przydatne wyjaśnienie, opierając tekst komunikatu na typie przechwyconego wyjątku. Poniższy kod, który został użyty w niemal identycznym formularzu w samouczku Obsługa BLL- i DAL-Level Wyjątki na stronie ASP.NET , zapewnia ten poziom szczegółowości:
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
Aby ukończyć ten samouczek, po prostu wywołaj metodę DisplayExceptionDetails
z Catch
bloku przekazującego w przechwyconym Exception
wystąpieniu (ex
).
Po utworzeniu Try ... Catch
bloku użytkownicy otrzymują bardziej informacyjny komunikat o błędzie, jak pokazano na rysunkach 4 i 5. Należy pamiętać, że w obliczu wyjątku lista danych pozostaje w trybie edycji. Jest to spowodowane tym, że po wystąpieniu wyjątku przepływ sterowania jest natychmiast przekierowywany do Catch
bloku, pomijając kod, który zwraca element DataList do stanu przed edycją.
Rysunek 4. Komunikat o błędzie jest wyświetlany, jeśli użytkownik pomija wymagane pole (kliknij, aby wyświetlić obraz pełnowymiarowy)
Rysunek 5. Podczas wprowadzania ceny ujemnej jest wyświetlany komunikat o błędzie (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Podsumowanie
Kontrolki GridView i ObjectDataSource udostępniają procedury obsługi zdarzeń na poziomie po poziomie, które zawierają informacje o wszelkich wyjątkach zgłoszonych podczas aktualizowania i usuwania przepływu pracy, a także właściwości, które można ustawić, aby wskazać, czy wyjątek został obsłużony. Te funkcje są jednak niedostępne podczas pracy z listą DataList i bezpośrednio przy użyciu biblioteki BLL. Zamiast tego jesteśmy odpowiedzialni za implementowanie obsługi wyjątków.
W tym samouczku pokazano, jak dodać obsługę wyjątków do edytowalnego przepływu pracy aktualizacji elementu DataList przez dodanie Try ... Catch
bloku do UpdateCommand
procedury obsługi zdarzeń. Jeśli podczas aktualizowania przepływu pracy jest zgłaszany wyjątek, Catch
kod bloku jest wykonywany, wyświetlając przydatne informacje w etykiecie ExceptionDetails
.
W tym momencie lista DataList nie podejmuje starań, aby zapobiec występowaniu wyjątków w pierwszej kolejności. Mimo że wiemy, że ujemna cena spowoduje wyjątek, nie dodaliśmy jeszcze żadnych funkcji, aby aktywnie uniemożliwić użytkownikowi wprowadzanie takich nieprawidłowych danych wejściowych. W następnym samouczku zobaczymy, jak zmniejszyć liczbę wyjątków spowodowanych nieprawidłowymi danymi wejściowymi użytkownika przez dodanie kontrolek weryfikacji w elemecie EditItemTemplate
.
Szczęśliwe programowanie!
Dalsze informacje
Aby uzyskać więcej informacji na temat tematów omówionych w tym samouczku, zapoznaj się z następującymi zasobami:
- Wyjątki — zalecenia dotyczące projektowania
- Moduły rejestrowania błędów i programy obsługi (ELMAH) ( biblioteka open source do rejestrowania błędów)
- Biblioteka przedsiębiorstwa dla .NET Framework 2.0 (obejmuje blok aplikacji zarządzania wyjątkami)
Informacje o autorze
Scott Mitchell, autor siedmiu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w ciągu 24 godzin. Można do niego dotrzeć pod adresem mitchell@4GuysFromRolla.com. Lub za pośrednictwem swojego bloga, który można znaleźć na stronie http://ScottOnWriting.NET.
Specjalne podziękowania
Ta seria samouczków została przejrzyona przez wielu przydatnych recenzentów. Głównym recenzentem tego samouczka był Ken Pespisa. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresemmitchell@4GuysFromRolla.com .
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla