Delen via


Afhandelen van BLL- en DAL-Level-uitzonderingen (C#)

door Scott Mitchell

PDF downloaden

In deze handleiding bekijken we hoe we op tactvolle wijze uitzonderingen kunnen verwerken die worden gegenereerd tijdens het bijwerken van een bewerkbare DataList.

Introductie

In het overzicht van het bewerken en verwijderen van gegevens in de zelfstudie DataList hebben we een DataList gemaakt die eenvoudige bewerkings- en verwijderingsmogelijkheden biedt. Hoewel het volledig functioneel was, was het nauwelijks gebruiksvriendelijk, omdat elke fout die optrad tijdens het bewerken of verwijderen leidde tot een onverwerkte uitzondering. Als u bijvoorbeeld de naam van het product weglaat of bij het bewerken van een product een prijswaarde van Zeer betaalbaar invoert,wordt er een uitzondering gegenereerd. Omdat deze uitzondering niet in de code wordt opgevangen, komt deze naar boven naar de ASP.NET runtime, die vervolgens de details van de uitzondering in de webpagina vermeldt.

Zoals we hebben gezien in de zelfstudie Afhandeling van BLL- en DAL-Level-uitzonderingen in een ASP.NET-pagina , worden de uitzonderingsgegevens geretourneerd naar de ObjectDataSource en vervolgens naar de GridView als er een uitzondering wordt gegenereerd op basis van de diepten van de lagen bedrijfslogica of gegevenstoegang. We hebben gezien hoe u deze uitzonderingen probleemloos kunt afhandelen door gebeurtenis-handlers te maken Updated of RowUpdated te gebruiken voor de ObjectDataSource of GridView, te controleren op een uitzondering en vervolgens aan te geven dat de uitzondering is verwerkt.

Onze DataList-zelfstudies gebruiken echter niet de ObjectDataSource voor het bijwerken en verwijderen van gegevens. In plaats daarvan werken we rechtstreeks tegen de BLL. Om uitzonderingen te detecteren die afkomstig zijn van de BLL of DAL, moeten we uitzonderingsafhandelingscode implementeren binnen de code-achter onze ASP.NET pagina. In deze handleiding ziet u hoe u uitzonderingen op een meer tactvolle manier kunt verwerken die zijn gegenereerd tijdens het bijwerken van een workflow van een bewerkbare gegevenslijst.

Opmerking

In de zelfstudie Een overzicht van het bewerken en verwijderen van gegevens in de DataList-zelfstudie hebben we verschillende technieken besproken voor het bewerken en verwijderen van gegevens uit DataList, enkele technieken die betrokken zijn bij het gebruik van een ObjectDataSource voor het bijwerken en verwijderen van gegevens. Als u deze technieken gebruikt, kunt u uitzonderingen van de BLL of DAL afhandelen via de ObjectDataSource-s Updated of Deleted gebeurtenis-handlers.

Stap 1: Een bewerkbare DataList maken

Voordat we ons zorgen maken over het afhandelen van uitzonderingen die optreden tijdens het bijwerken van de werkstroom, maken we eerst een bewerkbare DataList. Open de pagina ErrorHandling.aspx in de map EditDeleteDataList, voeg een DataList toe aan de ontwerper, stel de eigenschap ID in op Products, en voeg een nieuwe ObjectDataSource toe met de naam ProductsDataSource. Configureer de ObjectDataSource om de ProductsBLL klasse en GetProducts() methode te gebruiken voor het selecteren van records; stel de vervolgkeuzelijsten op de tabbladen INSERT, UPDATE en DELETE in op (Geen).

De productgegevens retourneren met behulp van de methode GetProducts()

Afbeelding 1: Retourneer de productgegevens met behulp van de GetProducts() methode (klik om de volledige afbeelding weer te geven)

Nadat de wizard ObjectDataSource is voltooid, maakt Visual Studio automatisch een ItemTemplate voor de DataList. Vervang dit door een ItemTemplate dat de naam en prijs van elk product weergeeft en een Bewerken-knop bevat. Maak vervolgens een EditItemTemplate TekstBox-webbesturingselement voor het invoeren van naam en prijs, en knoppen voor Bijwerken en Annuleren. Stel ten slotte de eigenschap DataList in RepeatColumns op 2.

Na deze wijzigingen moet de declaratieve markering van uw pagina er ongeveer als volgt uitzien. Controleer dubbel of de knoppen Bewerken, Annuleren en Bijwerken hun CommandName eigenschappen respectievelijk ingesteld zijn op Bewerken, Annuleren en Bijwerken.

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

Opmerking

Voor deze zelfstudie moet de weergavestatus van DataList zijn ingeschakeld.

Neem even de tijd om onze voortgang via een browser te bekijken (zie afbeelding 2).

Elk product bevat een knop Bewerken

Afbeelding 2: Elk product bevat een knop Bewerken (klik om de afbeelding op volledige grootte weer te geven)

Op dit moment veroorzaakt de knop Bewerken alleen een postback en maakt het product nog niet bewerkbaar. Als we bewerking willen inschakelen, moeten we gebeurtenishandlers maken voor de DataList EditCommand, CancelCommand en UpdateCommand gebeurtenissen. De EditCommand- en CancelCommand-gebeurtenissen werken simpelweg de eigenschap EditItemIndex van de DataList bij en binden de gegevens opnieuw aan de 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();
}

De UpdateCommand event-handler is iets gecompliceerder. Het moet de bewerkte producten in de ProductID uit de DataKeys verzameling lezen, samen met de naam en prijs van het product uit de tekstvakken in de EditItemTemplate, en vervolgens de ProductsBLL-methode van de UpdateProduct-klasse aanroepen voordat de DataList wordt teruggezet naar de toestand van voor de bewerking.

Laten we voorlopig gewoon dezelfde code van de UpdateCommand event handler gebruiken in het overzicht van het bewerken en verwijderen van gegevens in de tutorial DataList. We voegen de code toe om uitzonderingen in stap 2 correct af te handelen.

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();
}

Bij ongeldige invoer, zoals een onjuist opgemaakte eenheidsprijs, een ontoelaatbare eenheidsprijswaarde zoals -$ 5,00, of het weglaten van de productnaam, zal er een uitzondering worden gegenereerd. Omdat de UpdateCommand gebeurtenis-handler op dit moment geen foutafhandeling bevat, zal de uitzondering worden doorgegeven aan de ASP.NET-runtime, waar deze aan de eindgebruiker wordt weergegeven (zie Figuur 3).

Wanneer er een niet-verwerkte uitzondering optreedt, ziet de eindgebruiker een foutpagina

Afbeelding 3: Wanneer een niet-verwerkte uitzondering optreedt, ziet de eindgebruiker een foutpagina

Stap 2: Uitzonderingen correct verwerken in de UpdateCommand-gebeurtenishandler

Tijdens het bijwerken van de werkstroom kunnen uitzonderingen optreden in de UpdateCommand gebeurtenis-handler, de BLL of de DAL. Als een gebruiker bijvoorbeeld een te dure prijs invoert, genereert de Decimal.Parse instructie in de UpdateCommand gebeurtenishandler een FormatException uitzondering. Als de gebruiker de naam van het product weglaat of als de prijs een negatieve waarde heeft, zal de DAL een uitzondering genereren.

Wanneer er een uitzondering optreedt, willen we een informatief bericht op de pagina zelf weergeven. Voeg een Label Web-control toe aan de pagina waarvan de ID is ingesteld op ExceptionDetails. Configureer de tekst van het label om weer te geven in een rood, extra groot, vet en cursief CssClass lettertype door de eigenschap toe te wijzen aan de Warning CSS-klasse, die in het Styles.css bestand is gedefinieerd.

Wanneer er een fout optreedt, willen we dat het label slechts eenmaal wordt weergegeven. Bij volgende postbacks moet het waarschuwingsbericht van de label verdwijnen. Dit kan worden bereikt door de eigenschap van Label s Text leeg te maken of door de eigenschap Visible ervan in te stellen op False in de Page_Load gebeurtenishandler (zoals we eerder deden in de zelfstudie Afhandelen van BLL- en DAL-Level-uitzonderingen in een ASP.NET-pagina) of door de ondersteuningsstatus van de labelweergave uit te schakelen. Laten we de laatste optie gebruiken.

<asp:Label ID="ExceptionDetails" EnableViewState="False" CssClass="Warning"
    runat="server" />

Wanneer er een uitzondering wordt gegenereerd, wijzen we de details van de uitzondering toe aan de ExceptionDetails labelbesturingselement Text eigenschap. Omdat de weergavestatus is uitgeschakeld, gaan de programmatische wijzigingen van de Text eigenschap verloren, waarbij de standaardtekst (een lege tekenreeks) wordt teruggezet, waardoor het waarschuwingsbericht wordt verborgen.

Om te bepalen wanneer er een fout is opgetreden om een nuttig bericht op de pagina weer te geven, moeten we een Try ... Catch blok toevoegen aan de UpdateCommand gebeurtenis-handler. Het Try gedeelte bevat code die kan leiden tot een uitzondering, terwijl het Catch blok code bevat die wordt uitgevoerd in het gezicht van een uitzondering. Raadpleeg de sectie Basisprincipes van uitzonderingsafhandeling in de .NET Framework-documentatie voor meer informatie over het Try ... Catch blok.

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
    }
}

Wanneer een uitzondering van eender welk type wordt opgeworpen door code in het Try blok, begint de code van het Catch blok te worden uitgevoerd. Het type uitzondering dat wordt gegenereerd DbException, NoNullAllowedException, ArgumentExceptionenzovoort, is afhankelijk van wat, precies, de fout in de eerste plaats precipiteerde. Als er een probleem is op databaseniveau, wordt er een DbException gegenereerd. Als er een ongeldige waarde wordt ingevoerd voor de UnitPricevelden , UnitsInStockUnitsOnOrderof ReorderLevel velden, wordt er een ArgumentException gegenereerd, omdat we code hebben toegevoegd om deze veldwaarden in de ProductsDataTable klasse te valideren (zie de zelfstudie Een bedrijfslogicalaag maken).

We kunnen de eindgebruiker een nuttigere uitleg geven door de berichttekst te baseren op het type uitzondering dat is opgetreden. De volgende code, die in een bijna identieke vorm werd gebruikt in de tutorial Handling BLL- en DAL-Level-excepties in een ASP.NET-pagina, biedt dit niveau van detail:

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;
}

Als u deze zelfstudie wilt voltooien, roept u de DisplayExceptionDetails methode aan van het Catch blok dat wordt doorgegeven in het gevangen Exception exemplaar (ex).

Als het Try ... Catch blok is ingesteld, krijgen gebruikers een meer informatief foutbericht te zien, zoals in cijfers 4 en 5 wordt weergegeven. Houd er rekening mee dat in het gezicht van een uitzondering de DataList in de bewerkingsmodus blijft. Dit komt doordat bij het optreden van de uitzondering de sturingsstroom onmiddellijk wordt omgeleid naar het Catch blok, waarbij het blok dat de DataList naar de staat van vóór het bewerken terugbrengt, wordt omzeild.

Er wordt een foutbericht weergegeven als een gebruiker een vereist veld weglaat

Afbeelding 4: Er wordt een foutbericht weergegeven als een gebruiker een vereist veld weglaat (klik om de afbeelding op volledige grootte weer te geven)

Er wordt een foutbericht weergegeven bij het invoeren van een negatieve prijs

Afbeelding 5: Er wordt een foutbericht weergegeven bij het invoeren van een negatieve prijs (klik om de afbeelding op volledige grootte weer te geven)

Samenvatting

GridView en ObjectDataSource bieden gebeurtenis-handlers op postniveau die informatie bevatten over eventuele uitzonderingen die zijn gegenereerd tijdens het bijwerken en verwijderen van de werkstroom, evenals eigenschappen die kunnen worden ingesteld om aan te geven of de uitzondering al dan niet is verwerkt. Deze functies zijn echter niet beschikbaar wanneer u met de DataList werkt en de BLL rechtstreeks gebruikt. In plaats daarvan zijn we verantwoordelijk voor het implementeren van uitzonderingsafhandeling.

In deze zelfstudie hebben we gezien hoe u de verwerking van uitzonderingen toevoegt aan een bewerkbare werkstroom van DataList door een Try ... Catch blok toe te voegen aan de UpdateCommand gebeurtenis-handler. Als er een uitzondering optreedt tijdens het bijwerken van de werkstroom, wordt de code van het Catch blok uitgevoerd, met nuttige informatie in het ExceptionDetails label.

Op dit moment doet de DataList er niets aan om te voorkomen dat uitzonderingen überhaupt optreden. Hoewel we weten dat een negatieve prijs tot een uitzondering leidt, hebben we nog geen functionaliteit toegevoegd om proactief te voorkomen dat een gebruiker dergelijke ongeldige invoer invoer invoert. In onze volgende zelfstudie zien we hoe u de uitzonderingen kunt verminderen die worden veroorzaakt door ongeldige gebruikersinvoer door validatiebesturingselementen toe te voegen in de EditItemTemplate.

Veel plezier met programmeren!

Meer lezen

Raadpleeg de volgende bronnen voor meer informatie over de onderwerpen die in deze zelfstudie worden besproken:

Over de auteur

Scott Mitchell, auteur van zeven ASP/ASP.NET-boeken en oprichter van 4GuysFromRolla.com, werkt sinds 1998 met Microsoft-webtechnologieën. Scott werkt als onafhankelijk consultant, trainer en schrijver. Zijn laatste boek is Sams Teach Yourself ASP.NET 2.0 in 24 uur. Hij kan worden bereikt op mitchell@4GuysFromRolla.com.

Speciale dank aan

Deze tutorialreeks is beoordeeld door veel behulpzame beoordelers. Hoofdrecensent voor deze tutorial was Ken Pespisa. Bent u geïnteresseerd in het bekijken van mijn aanstaande MSDN-artikelen? Zo ja, laat iets van je horen via mitchell@4GuysFromRolla.com.