Sdílet prostřednictvím


Zpracování výjimek na úrovni knihoven BLL a DAL (VB)

Scott Mitchell

Stáhnout PDF

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 Productsa 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).

Vrácení informací o produktu pomocí metody GetProducts()

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).

Každý produkt obsahuje tlačítko Upravit.

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, CancelCommanda 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 EditItemTemplatea 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).

Když dojde k neošetřené výjimce, koncový uživatel zobrazí chybovou stránku.

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 ExceptionDetailshodnotu . 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, ArgumentExceptiona 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 UnitPricepole , , UnitsInStockUnitsOnOrdernebo 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.

Chybová zpráva se zobrazí, pokud uživatel vynechá povinné pole.

Obrázek 4: Zobrazí se chybová zpráva, pokud uživatel vynechá povinné pole (kliknutím zobrazíte obrázek v plné velikosti).

Při zadávání záporné ceny se zobrazí chybová zpráva.

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í:

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.