Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
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 Správa výjimek BLL a DAL-Level na stránce ASP.NET, pokud je výjimka vyvolána z hlubin vrstvy obchodní logiky nebo vrstvy přístupu k datům, podrobnosti výjimky 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).
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, CancelCommanda UpdateCommand události.
EditCommand Události CancelCommand jednoduše aktualizují vlastnost DataList s EditItemIndex a znovu propojují data na 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();
}
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 použijme stejný kód z UpdateCommand obslužné rutiny události v tutoriálu Přehled úprav a odstranění dat v DataList. Kód přidáme pro řádné zpracování výjimek v kroku 2.
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();
}
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 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 False v Page_Load obslužné rutině události (stejně jako jsme to udělali v kurzu zpracování výjimek BLL a DAL-Level na stránce ASP.NET) nebo zakázáním podpory stavu zobrazení pro 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 Try ... Catch obslužné rutiny události přidat UpdateCommand 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 bloku najdete v části Try ... Catch v dokumentaci k rozhraní .NET Framework.
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
}
}
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 pole UnitPrice, UnitsInStock, UnitsOnOrder nebo ReorderLevel zadána neplatná hodnota, bude vyvolána výjimka ArgumentException, protože jsme přidali kód pro ověření těchto hodnot polí ve třídě ProductsDataTable (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ě v zpracování BLL- a DAL-Level výjimky v návodu ASP.NET Page poskytuje tuto úroveň 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;
}
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 pro návrh výjimek
- Moduly a obslužné rutiny protokolování chyb (ELMAH) (open-source knihovna pro protokolování chyb)
- 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: Nauč se ASP.NET 2.0 za 24 hodin. Může být dosažitelný na mitchell@4GuysFromRolla.comadrese .
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, napište mi zprávu na mitchell@4GuysFromRolla.com.