Zpracování výjimek na úrovni knihoven BLL a DAL (VB)
Scott Mitchell
V tomto kurzu se dozvíte, jak taktně zpracovat výjimky vyvolané během upravitelného pracovního postupu aktualizace dataListu.
Úvod
V přehledu úprav a odstraňování dat v kurzu DataList jsme vytvořili Seznam dat, který nabízel jednoduché možnosti úprav a odstraňování. I když je plně funkční, bylo to těžko uživatelsky přívětivé, protože jakákoli chyba, ke které došlo během úprav nebo odstranění procesu, způsobila neošetřenou výjimku. Například vynechání názvu produktu nebo při úpravě produktu zadáním cenové hodnoty Velmi cenově dostupné!, vyvolá výjimku. Vzhledem k tomu, že tato výjimka není zachycena v kódu, bubliny až do modulu runtime ASP.NET, který pak zobrazí podrobnosti o výjimce na webové stránce.
Jak jsme viděli v kurzu zpracování výjimek na úrovni BLL a DAL na stránce ASP.NET, pokud je výjimka vyvolána z hloubky obchodní logiky nebo datové vrstvy přístupu, podrobnosti o výjimce se vrátí do ObjectDataSource a pak do GridView. Viděli jsme, jak tyto výjimky elegantně zpracovat vytvořením Updated
obslužných RowUpdated
rutin událostí pro ObjectDataSource nebo GridView, kontrolou výjimky a následným indikací, že výjimka byla zpracována.
Naše kurzy DataList však nepoužívají ObjectDataSource k aktualizaci a odstraňování dat. Místo toho pracujeme přímo proti BLL. Abychom mohli detekovat výjimky pocházející z BLL nebo DAL, musíme implementovat kód zpracování výjimek v rámci kódu na naší stránce ASP.NET. V tomto kurzu se dozvíte, jak lépe zpracovat výjimky vyvolané během upravitelného pracovního postupu aktualizace DataListu.
Poznámka:
V přehledu úprav a odstraňování dat v kurzu DataList jsme probrali různé techniky pro úpravy a odstraňování dat ze seznamu DataList, některé techniky, které se týkají použití ObjectDataSource pro aktualizaci a odstranění. Pokud tyto techniky používáte, můžete zpracovávat výjimky z BLL nebo DAL prostřednictvím objectDataSource s Updated
nebo Deleted
obslužných rutin událostí.
Krok 1: Vytvoření upravitelného datového seznamu
Než se budeme starat o zpracování výjimek, ke kterým dochází během pracovního postupu aktualizace, nejprve vytvoříme upravitelný datový seznam. ErrorHandling.aspx
Otevřete stránku ve EditDeleteDataList
složce, přidejte DataList do Návrháře, nastavte jeho ID
vlastnost na Products
a přidejte nový ObjectDataSource s názvem ProductsDataSource
. Nakonfigurujte ObjectDataSource tak, aby používal metodu ProductsBLL
třídy pro GetProducts()
výběr záznamů; nastavte rozevírací seznamy na kartách INSERT, UPDATE a DELETE na (None).
Obrázek 1: Vrácení informací o produktu pomocí GetProducts()
metody (kliknutím zobrazíte obrázek s plnou velikostí)
Po dokončení průvodce ObjectDataSource sada Visual Studio automaticky vytvoří ItemTemplate
pro DataList. Nahraďte ho ItemTemplate
názvem a cenou jednotlivých produktů a včetně tlačítka Upravit. Dále vytvořte ovládací prvek EditItemTemplate
TextBox Web pro názvy a ceny a tlačítka Aktualizovat a Zrušit. Nakonec nastavte vlastnost DataList na RepeatColumns
hodnotu 2.
Po těchto změnách by deklarativní značky stránky měly vypadat podobně jako v následujícím příkladu. Pečlivě zaškrtněte, abyste měli jistotu, že tlačítka Upravit, Zrušit a Aktualizovat mají své CommandName
vlastnosti nastavené na Možnost Upravit, Zrušit a Aktualizovat.
<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>
Poznámka:
Pro účely tohoto kurzu musí být povolen stav zobrazení DataList s.
Chvilku si prohlédněte průběh v prohlížeči (viz obrázek 2).
Obrázek 2: Každý produkt obsahuje tlačítko Upravit (kliknutím zobrazíte obrázek v plné velikosti).
Tlačítko Upravit v současné době způsobí, že postback ještě neupravuje produkt. Abychom mohli povolit úpravy, musíme vytvořit obslužné rutiny událostí pro DataList s EditCommand
, CancelCommand
a UpdateCommand
události. CancelCommand
Události EditCommand
jednoduše aktualizují vlastnost DataList s EditItemIndex
a znovu propojují data na 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
Obslužná rutina UpdateCommand
události je o něco více zapojená. Musí číst v upravených produktech ProductID
z DataKeys
kolekce spolu s názvem produktu a cenou z textových polí v objektu EditItemTemplate
a potom volat metodu ProductsBLL
třídy před UpdateProduct
vrácením DataList do stavu předběžné úpravy.
Prozatím stačí použít stejný kód z UpdateCommand
obslužné rutiny události v přehledu úprav a odstranění dat v kurzu DataList . Kód přidáme pro řádné zpracování výjimek v 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
Ve tváři neplatného vstupu, který může být ve formě nesprávně formátované jednotkové ceny, neplatná jednotková cena hodnota jako -5,00 nebo vynechání názvu produktu se vyvolá výjimka. Vzhledem k tomu, že UpdateCommand
obslužná rutina události v tomto okamžiku neobsahuje žádný kód zpracování výjimek, bude výjimka bublina až do modulu runtime ASP.NET, kde se zobrazí koncovému uživateli (viz obrázek 3).
Obrázek 3: Když dojde k neošetřené výjimce, koncový uživatel zobrazí chybovou stránku
Krok 2: Řádné zpracování výjimek v obslužné rutině události UpdateCommand
Během aktualizace pracovního postupu mohou v obslužné rutině události, BLL nebo DAL dojít k UpdateCommand
výjimkám. Pokud například uživatel zadá cenu Příliš drahé, Decimal.Parse
příkaz v obslužné rutině UpdateCommand
události vyvolá FormatException
výjimku. Pokud uživatel vynechá název produktu nebo pokud cena má zápornou hodnotu, dal vyvolá výjimku.
Když dojde k výjimce, chceme na samotné stránce zobrazit informativní zprávu. Přidejte ovládací prvek Label Web na stránku, jejíž ID
vlastnost je nastavena na ExceptionDetails
hodnotu . Nakonfigurujte text Popisek tak, aby se zobrazoval červeně, extra velké, tučné písmo a kurzívu tím, že přiřadíte jeho CssClass
vlastnost třídě Warning
CSS, která je definována Styles.css
v souboru.
Když dojde k chybě, chceme, aby se popisek zobrazoval jenom jednou. To znamená, že u následných postbacků by zpráva upozornění popisku měla zmizet. Toho lze dosáhnout zrušením vlastnosti Popisek Text
nebo nastavením jeho Visible
vlastnosti v Page_Load
False
obslužné rutině události (stejně jako jsme to udělali zpět v zpracování výjimek na úrovni BLL a DAL v kurzu ASP.NET Page) nebo zakázáním podpory stavu zobrazení Popisek. Pojďme použít druhou možnost.
<asp:Label ID="ExceptionDetails" EnableViewState="False" CssClass="Warning"
runat="server" />
Při vyvolání výjimky přiřadíme podrobnosti o výjimce ExceptionDetails
vlastnosti ovládacího prvku Text
Popisek. Vzhledem k tomu, že je jeho stav zobrazení zakázaný, při následných zpětném Text
odeslání programových změn vlastnosti se ztratí, vrátí se zpět k výchozímu textu (prázdný řetězec), čímž skryje zprávu upozornění.
Abychom zjistili, kdy byla vyvolána chyba, aby se na stránce zobrazila užitečná zpráva, musíme do UpdateCommand
obslužné rutiny události přidat Try ... Catch
blok. Část Try
obsahuje kód, který může vést k výjimce, zatímco Catch
blok obsahuje kód, který se spouští v případě výjimky. Další informace o Try ... Catch
bloku najdete v části Základy zpracování výjimek v dokumentaci k rozhraní .NET Framework.
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
Pokud kód v Try
bloku vyvolá výjimku z libovolného typu, Catch
začne se spouštět kód bloku. Typ výjimky, která je vyvolán DbException
, NoNullAllowedException
, ArgumentException
a tak dále závisí na tom, co, přesně, precipitoval chybu na prvním místě. Pokud na úrovni databáze dojde k nějakému problému, DbException
vyvolá se dotaz. Pokud je pro UnitPrice
pole , , UnitsInStock
UnitsOnOrder
nebo ReorderLevel
pole zadána neplatná hodnota, bude vyvolán, ArgumentException
protože jsme přidali kód pro ověření těchto hodnot polí ve ProductsDataTable
třídě (viz kurz Vytvoření vrstvy obchodní logiky).
Koncovému uživateli můžeme poskytnout užitečnější vysvětlení tím, že text zprávy začneme na typu zachycené výjimky. Následující kód, který byl použit v téměř identické podobě zpět v zpracování BLL- a DAL-level výjimky v kurzu ASP.NET Page poskytuje tuto úroveň podrobností:
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
K dokončení tohoto kurzu jednoduše zavolejte DisplayExceptionDetails
metodu Catch
z bloku předávajícího zachycenou Exception
instanci (ex
).
Když je Try ... Catch
blok na místě, zobrazí se uživatelům informativnější chybová zpráva, jak ukazují obrázky 4 a 5. Všimněte si, že v tváři výjimky, dataList zůstává v režimu úprav. Důvodem je to, že jakmile dojde k výjimce, řídicí tok se okamžitě přesměruje do Catch
bloku a vynechá kód, který vrátí dataList do stavu předběžné úpravy.
Obrázek 4: Zobrazí se chybová zpráva, pokud uživatel vynechá povinné pole (kliknutím zobrazíte obrázek v plné velikosti).
Obrázek 5: Při zadávání záporné ceny se zobrazí chybová zpráva (kliknutím zobrazíte obrázek v plné velikosti).
Shrnutí
GridView a ObjectDataSource poskytují obslužné rutiny událostí po úrovni, které obsahují informace o všech výjimkách, které byly vyvolány během aktualizace a odstraňování pracovního postupu, a také vlastnosti, které lze nastavit tak, aby značily, zda byla výjimka zpracována nebo ne. Tyto funkce ale nejsou při práci s dataListem a používáníM knihovny BLL přímo nedostupné. Místo toho zodpovídáme za implementaci zpracování výjimek.
V tomto kurzu jsme viděli, jak přidat zpracování výjimek do upravitelného pracovního postupu aktualizace DataList přidáním Try ... Catch
bloku do UpdateCommand
obslužné rutiny události. Pokud je během procesu aktualizace vyvolána výjimka, Catch
kód bloku se spustí a zobrazí užitečné informace v popisku ExceptionDetails
.
V tomto okamžiku dataList nesvádí žádné úsilí, aby se zabránilo výjimkám na prvním místě. I když víme, že záporná cena způsobí výjimku, ještě jsme nepřidali žádnou funkci, abychom proaktivně zabránili uživateli v zadávání takových neplatných vstupů. V našem dalším kurzu se dozvíte, jak pomoct snížit výjimky způsobené neplatným uživatelským vstupem přidáním ověřovacích ovládacích prvků do EditItemTemplate
.
Šťastné programování!
Další čtení
Další informace o tématech probíraných v tomto kurzu najdete v následujících zdrojích informací:
- Pokyny k návrhu pro výjimky
- Moduly a obslužné rutiny protokolování chyb (ELMAH) (opensourcová knihovna pro chyby protokolování)
- Podniková knihovna pro rozhraní .NET Framework 2.0 (zahrnuje blok aplikace správy výjimek)
O autorovi
Scott Mitchell, autor sedmi knih ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, trenér a spisovatel. Jeho nejnovější kniha je Sams Teach Yourself ASP.NET 2.0 za 24 hodin. Je dostupný na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím svého blogu, který lze najít na http://ScottOnWriting.NET.
Zvláštní díky
Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Vedoucí kontrolorem tohoto kurzu byl Ken Pespisa. Chcete si projít nadcházející články MSDN? Pokud ano, zahoďte mi řádek na mitchell@4GuysFromRolla.com.