Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
által Scott Mitchell
Ebben az oktatóanyagban bemutatjuk, hogyan kezelhetők a szerkeszthető DataList frissítési munkafolyamata során felmerülő kivételek.
Bevezetés
Az Adatok szerkesztésének és törlésének áttekintésében a DataList oktatóanyagban létrehoztunk egy DataListet, amely egyszerű szerkesztési és törlési képességeket kínál. Bár teljesen működőképes volt, alig volt felhasználóbarát, mivel a szerkesztési vagy törlési folyamat során előforduló hibák nem kezelt kivételt eredményeztek. Ha például kihagyja a termék nevét, vagy ha szerkeszt egy terméket, akkor a Nagyon megfizethető!árérték megadása kivételt jelent. Mivel ez a kivétel nincs kezelve a kódban, felbuborékol az ASP.NET futtatókörnyezethez, amely ezután megjeleníti a kivétel részleteit a weblapon.
Ahogy az ASP.NET lapon a BLL- és DAL-Level kivételek kezelése című oktatóanyagban láttuk, ha az üzleti logika vagy az adatelérési rétegek mélységéből kivétel keletkezik, a kivétel részletei visszakerülnek az ObjectDataSource-ba, majd a GridView-ba. Láttuk, hogyan kell ezeket a kivételeket elegánsan kezelni, úgy, hogy Updated vagy RowUpdated eseménykezelőket hozunk létre az ObjectDataSource-hoz vagy a GridView-hoz, ellenőrizzük a kivételt, és jelezzük, hogy a kivételt kezeltük.
A DataList-oktatóanyagok azonban nem az ObjectDataSource-t használják az adatok frissítéséhez és törléséhez. Ehelyett közvetlenül a BLL ellen dolgozunk. A BLL-ből vagy DAL-ból származó kivételek észleléséhez a kivételkezelési kódot a ASP.NET lap mögötti kódban kell implementálni. Ebben az oktatóanyagban azt fogjuk látni, hogyan kezelhetők a szerkeszthető DataList frissítési munkafolyamatai során felmerülő kivételek.
Megjegyzés:
Az Adatok szerkesztésének és törlésének áttekintése a DataList oktatóanyagban az adatok DataList-ből való szerkesztésének és törlésének különböző technikáiról volt szó, néhány módszer, amely az ObjectDataSource használatával történt a frissítéshez és a törléshez. Ha ezeket a technikákat alkalmazza, a BLL-ből vagy a DAL-ból származó kivételeket az ObjectDataSource-on Updated vagy Deleted az eseménykezelőn keresztül kezelheti.
1. lépés: Szerkeszthető adatlista létrehozása
Mielőtt a frissítési munkafolyamat során előforduló kivételek kezelésével foglalkoznánk, először hozzunk létre egy szerkeszthető DataListet. Nyissa meg a ErrorHandling.aspx lapot a EditDeleteDataList mappában, vegyen fel egy DataListet a Tervezőbe, állítsa be a tulajdonságát IDProducts, és adjon hozzá egy új ObjectDataSource nevű ProductsDataSourceobjektumot. Konfigurálja az ObjectDataSource-t úgy, hogy az ProductsBLL osztály s GetProducts() metódusát használja a rekordok kiválasztásához; állítsa az INSERT, UPDATE és DELETE fül legördülő listáit a (Nincs) értékre.
1. ábra: Adja vissza a termékinformációkat a GetProducts() metódus használatával (kattintson ide a teljes méretű kép megtekintéséhez)
Az ObjectDataSource varázsló befejezése után a Visual Studio automatikusan létrehoz egy ItemTemplate adatlistát. Cserélje le ezt egy olyanra ItemTemplate , amely megjeleníti az egyes termékek nevét és árát, és tartalmaz egy Szerkesztés gombot. Ezután hozzon létre egy EditItemTemplate-t, amely tartalmaz egy TextBox webvezérlőt a név és az ár megadásához, valamint Frissítés és Mégse gombokat. Végül állítsa a DataList tulajdonságát RepeatColumns 2-re.
A módosítások után a lap deklaratív korrektúrája az alábbihoz hasonlóan fog kinézni. Győződjön meg róla, hogy a Szerkesztés, Mégse és Frissítés gombok tulajdonságai be vannak állítva Szerkesztésre, Mégse-re és Frissítésre.
<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>
Megjegyzés:
Ebben az oktatóanyagban engedélyezni kell a DataList nézetállapotát.
Szánjon egy kis időt az előrehaladás megtekintésére egy böngészőben (lásd a 2. ábrát).
2. ábra: Minden termék tartalmaz szerkesztési gombot (kattintson ide a teljes méretű kép megtekintéséhez)
A Szerkesztés gomb jelenleg csak visszatöltést okoz, de még nem teszi szerkeszthetővé a terméket. A szerkesztés engedélyezéséhez eseménykezelőket kell létrehoznunk a DataList s EditCommandés CancelCommandUpdateCommand az események számára. Az EditCommand és CancelCommand események egyszerűen frissítik a DataList EditItemIndex tulajdonságát, és újrahozzárendelik az adatokat a DataListhez.
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
Az UpdateCommand eseménykezelő kicsit összetettebb. Be kell olvasnia a szerkesztett terméket ProductID a DataKeys gyűjteményből, a termék nevével és árával együtt a EditItemTemplate szövegmezőkből. Ezután meg kell hívnia az ProductsBLL osztály UpdateProduct metódusát, mielőtt visszaállítaná a DataListet az eredeti, szerkesztés előtti állapotába.
Egyelőre csak ugyanazt a kódot használjuk az eseménykezelőtől a UpdateCommandDataList oktatóanyag adatainak szerkesztésének és törlésének áttekintésében . Hozzáadjuk a kódot a 2. lépésben szereplő kivételek kecses kezeléséhez.
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
Érvénytelen bemenet esetén, amely nem megfelelően formázott egységár formájában is lehetséges, a rendszer kivételt emel ki egy illegális egységár-érték (például -5,00 USD) vagy a termék nevének kihagyása miatt. Mivel az UpdateCommand eseménykezelő jelenleg nem tartalmaz kivételkezelési kódot, a kivétel felborul a ASP.NET futtatókörnyezetig, ahol az megjelenik a végfelhasználó számára (lásd a 3. ábrát).
3. ábra: Kezeletlen kivétel esetén a végfelhasználó hibaüzenetet jelenít meg
2. lépés: Kivételek türelmes kezelése az UpdateCommand eseménykezelőben
A frissítési munkafolyamat során kivételek léphetnek fel az UpdateCommand eseménykezelőben, a BLL-ben vagy a DAL-ban. Ha például egy felhasználó túl drága árat ad meg, az Decimal.Parse eseménykezelőben lévő UpdateCommand utasítás kivételt FormatException fog eredményezni. Ha a felhasználó kihagyja a termék nevét, vagy ha az ár negatív értékkel rendelkezik, a DAL kivételt fog eredményezni.
Kivétel esetén egy tájékoztató üzenetet szeretnénk megjeleníteni a lapon belül. Adjon hozzá egy Címke webvezérlőt ahhoz a laphoz, amelynek ID be van állítva ExceptionDetails-re. A Címke szövegét úgy konfigurálhatja, hogy piros, extra nagy, félkövér és dőlt betűtípusban jelenjen meg, ha a tulajdonságot CssClass a Warning fájlban meghatározott Styles.css CSS-osztályhoz rendeli.
Hiba esetén csak egyszer szeretnénk megjeleníteni a címkét. Ez azt jelzi, hogy a későbbi visszalépések esetén a címke figyelmeztető üzenetének el kell tűnnie. Ezt úgy teheti meg, hogy törli a Label Text tulajdonságát, vagy az Visible eseménykezelőben beállítja a tulajdonságát FalsePage_Load értékre (ahogyan azt a ASP.NET oldalakon BLL- és DAL-Level kivételek kezelése című oktatóanyagban tettük), vagy a Label nézetállapot támogatásának letiltásával. Használjuk az utóbbi lehetőséget.
<asp:Label ID="ExceptionDetails" EnableViewState="False" CssClass="Warning"
runat="server" />
Kivétel felmerülésekor a kivétel részleteit a ExceptionDetails Címke vezérlőelem Text tulajdonságához rendeljük. Mivel a nézet állapota le van tiltva, a későbbi visszavételek során a Text tulajdonság programozott módosításai elvesznek, és visszaállnak az alapértelmezett szövegre (egy üres sztringre), így elrejtik a figyelmeztető üzenetet.
Annak megállapításához, hogy mikor jelentkezett hiba a lapon egy hasznos üzenet megjelenítéséhez, fel kell venni egy blokkot Try ... Catch az UpdateCommand eseménykezelőbe. A Try rész olyan kódot tartalmaz, amely kivételhez vezethet, míg a Catch blokk egy kivétellel szemben végrehajtott kódot tartalmaz. A blokkról további információt a .NET-keretrendszer dokumentációjának Try ... Catch című szakaszában talál.
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
Ha a Try blokkon belüli kód bármilyen típusú kivételt hoz létre, a Catch blokk kódja elkezd végrehajtódni. A kidobottDbExceptionNoNullAllowedExceptionArgumentException, stb. kivétel típusa attól függ, hogy pontosan mi okozza a hibát. Ha probléma merül fel az adatbázis szintjén, a rendszer egy DbException hibát fog dobni. Ha érvénytelen értéket adnak meg a UnitPrice, UnitsInStock, UnitsOnOrder vagy ReorderLevel mezőkhöz, akkor ArgumentException kivétel váltódik ki, mivel kódot adtunk hozzá a mezőértékek ellenőrzéséhez az ProductsDataTable osztályban (lásd az Üzleti logikai réteg létrehozása oktatóanyagot).
Hasznosabb magyarázatot adhatunk a végfelhasználónak, ha az üzenet szövegét a kifogott kivétel típusára alapozzuk. Az alábbi kód, amelyet régebben, szinte azonos formában használtak a BLL- és DAL-Level Kivételek kezelése ASP.NET oldalon bemutatóban, ezt a részletezési szintet nyújtja.
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
Az oktatóanyag elvégzéséhez egyszerűen hívja meg a DisplayExceptionDetails metódust a Catch blokkon belül, átadva a fogott Exception példányt (ex).
A blokk helyén egy Try ... Catch informatívabb hibaüzenet jelenik meg a felhasználók számára, ahogy a 4. és az 5. ábra is mutatja. Vegye figyelembe, hogy kivétel esetén a DataList szerkesztési módban marad. Ennek az az oka, hogy a kivétel bekövetkezése után a rendszer azonnal átirányítja a vezérlőfolyamatot a Catch blokkba, megkerülve azt a kódot, amely a DataListet az előszerkesztési állapotba adja vissza.
4. ábra: Hibaüzenet jelenik meg, ha egy felhasználó kihagy egy kötelező mezőt (ide kattintva megtekintheti a teljes méretű képet)
5. ábra: Negatív ár megadásakor hibaüzenet jelenik meg (ide kattintva megtekintheti a teljes méretű képet)
Összefoglalás
A GridView és az ObjectDataSource olyan posztszintű eseménykezelőket biztosít, amelyek információkat tartalmaznak a frissítési és törlési munkafolyamat során felmerült kivételekről, valamint olyan tulajdonságokat, amelyek megadhatók annak jelzésére, hogy a kivételt kezelték-e. Ezek a funkciók azonban nem érhetők el a DataList használata és a BLL közvetlen használata esetén. Ehelyett mi vagyunk a felelősek a kivételkezelés megvalósításáért.
Ebben az oktatóanyagban azt láttuk, hogyan adhat hozzá kivételkezelést egy szerkeszthető DataList-frissítési munkafolyamathoz úgy, hogy egy blokkot Try ... Catch ad hozzá az UpdateCommand eseménykezelőhöz. Ha a frissítési munkafolyamat során kivétel keletkezik, a Catch blokk kódjának végrehajtása hasznos információkat jelenít meg a ExceptionDetails címkében.
Ezen a ponton a DataList nem törekszik arra, hogy megakadályozza a kivételek bekövetkezését. Annak ellenére, hogy tudjuk, hogy a negatív ár kivételt eredményez, még nem adtunk hozzá semmilyen funkciót, hogy proaktív módon megakadályozzuk, hogy egy felhasználó ilyen érvénytelen bemenetet adjon meg. A következő oktatóanyagban bemutatjuk, hogyan csökkentheti az érvénytelen felhasználói bemenetek által okozott kivételeket azáltal, hogy érvényesítési vezérlőket ad hozzá a EditItemTemplate.
Boldog programozást!
További olvasás
Az oktatóanyagban tárgyalt témakörökről az alábbi forrásokban talál további információt:
- Tervezési irányelvek kivételekhez
- Hibanaplózó modulok és kezelők (ELMAH) (nyílt forráskódú kódtár naplózási hibákhoz)
- Enterprise Library for .NET Framework 2.0 (a kivételkezelési alkalmazásblokkot is tartalmazza)
Tudnivalók a szerzőről
Scott Mitchell, hét ASP/ASP.NET-könyv szerzője és a 4GuysFromRolla.com alapítója, 1998 óta dolgozik a Microsoft webtechnológiáival. Scott független tanácsadóként, edzőként és íróként dolgozik. Legújabb könyve Sams Tanuld meg ASP.NET 2.0 24 óra alatt. Ő itt elérhető mitchell@4GuysFromRolla.com.
Külön köszönet
Ezt az oktatóanyag-sorozatot sok hasznos véleményező áttekintette. Az oktatóanyag vezető véleményezője Ken Pespisa volt. Szeretné áttekinteni a közelgő MSDN-cikkeimet? Ha igen, írj egy sort a mitchell@4GuysFromRolla.com-ra.