Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Autor : Scott Mitchell
W tym samouczku zobaczymy, jak wyświetlić przyjazny, informacyjny komunikat o błędzie, jeśli wystąpi wyjątek podczas operacji dodawania, aktualizacji lub usuwania danych kontrolki sieci Web ASP.NET.
Wprowadzenie
Praca z danymi z aplikacji internetowej ASP.NET przy użyciu architektury aplikacji warstwowej obejmuje następujące trzy ogólne kroki:
- Ustal, jaką metodę warstwy logiki biznesowej należy wywołać i jakie wartości parametrów mają zostać przekazane. Wartości parametrów mogą być zakodowane trwale, programowo przypisane lub wprowadzone przez użytkownika dane wejściowe.
- Wywołaj metodę .
- Przetwarzanie wyników. Podczas wywoływania metody BLL zwracającej dane może to obejmować powiązanie danych z kontrolką sieci Web danych. W przypadku metod BLL, które modyfikują dane, może to obejmować wykonywanie pewnych akcji na podstawie wartości zwracanej lub płynne obsłużenie dowolnego wyjątku, który wystąpił w kroku 2.
Jak pokazano w poprzednim samouczku, zarówno kontrolki ObjectDataSource, jak i kontrolki danych sieci Web zapewniają możliwość rozszerzeń dla kroków 1 i 3. Na przykład obiekt GridView wywołuje zdarzenie RowUpdating
przed przypisaniem wartości pól do kolekcji ObjectDataSource UpdateParameters
; zdarzenie RowUpdated
jest zgłaszane po zakończeniu operacji przez obiekt ObjectDataSource.
Przeanalizowaliśmy już zdarzenia uruchamiane w kroku 1 i zobaczyliśmy, jak można ich użyć do dostosowania parametrów wejściowych lub anulowania operacji. W tym samouczku skupimy się na zdarzeniach uruchamianych po zakończeniu operacji. Dzięki tym procedurom obsługi zdarzeń na poziomie postu, możemy między innymi określić, czy wystąpił wyjątek podczas operacji i obsłużyć go w sposób elegancki, wyświetlając przyjazny i informacyjny komunikat o błędzie na ekranie zamiast domyślnej standardowej strony błędu ASP.NET.
Aby zilustrować pracę z tymi zdarzeniami po poziomie, utwórzmy stronę zawierającą listę produktów w edytowalnym widoku GridView. Jeśli podczas aktualizowania produktu zostanie zgłoszony wyjątek, na naszej stronie ASP.NET zostanie wyświetlony krótki komunikat powyżej kontrolki GridView wyjaśniający, że wystąpił problem. Zaczynamy!
Krok 1. Tworzenie edytowalnego elementu GridView produktów
W poprzednim samouczku utworzyliśmy edytowalny element GridView z zaledwie dwoma polami: ProductName
i UnitPrice
. Wymaga to utworzenia dodatkowego przeciążenia metody ProductsBLL
klasy UpdateProduct
, która zaakceptowała tylko trzy parametry wejściowe (nazwę produktu, cenę jednostkową i identyfikator) w przeciwieństwie do parametru dla każdego pola produktu. W tym samouczku przećwiczmy tę technikę ponownie, tworząc edytowalny element GridView, który wyświetla nazwę produktu, ilość na jednostkę, cenę jednostkową i jednostki w magazynie, ale zezwala tylko na edycję nazwy, ceny jednostkowej i jednostek w magazynie.
Aby obsłużyć ten scenariusz, potrzebujemy kolejnego przeciążenia metody UpdateProduct
, które akceptuje cztery parametry: nazwę produktu, cenę jednostkową, jednostki dostępne w magazynie oraz identyfikator. Dodaj następującą metodę do klasy ProductsBLL
:
[System.ComponentModel.DataObjectMethodAttribute(
System.ComponentModel.DataObjectMethodType.Update, false)]
public bool UpdateProduct(string productName, decimal? unitPrice, short? unitsInStock,
int productID)
{
Northwind.ProductsDataTable products = Adapter.GetProductByProductID(productID);
if (products.Count == 0)
// no matching record found, return false
return false;
Northwind.ProductsRow product = products[0];
product.ProductName = productName;
if (unitPrice == null) product.SetUnitPriceNull();
else product.UnitPrice = unitPrice.Value;
if (unitsInStock == null) product.SetUnitsInStockNull();
else product.UnitsInStock = unitsInStock.Value;
// Update the product record
int rowsAffected = Adapter.Update(product);
// Return true if precisely one row was updated, otherwise false
return rowsAffected == 1;
}
Po zakończeniu tej metody można utworzyć stronę ASP.NET, która umożliwia edytowanie tych czterech konkretnych pól produktu.
ErrorHandling.aspx
Otwórz stronę w folderze EditInsertDelete
i dodaj element GridView do strony za pośrednictwem projektanta. Powiąż element GridView z nowym obiektem ObjectDataSource, mapując metodę Select()
do metody ProductsBLL
klasy GetProducts()
i mapując metodę Update()
do właśnie utworzonego przeciążenia UpdateProduct
.
Rysunek 1: Użycie przeciążonej metody, która akceptuje cztery parametry wejściowe (UpdateProduct
)
Spowoduje to utworzenie obiektu ObjectDataSource z kolekcją UpdateParameters
z czterema parametrami i kontrolką GridView z polem dla każdego pola produktu. Znacznik deklaratywny ObjectDataSource przypisuje właściwości OldValuesParameterFormatString
wartość original_{0}
, co spowoduje wyjątek, ponieważ klasa BLL nie oczekuje przekazania parametru wejściowego o nazwie original_productID
. Nie zapomnij całkowicie usunąć tego ustawienia ze składni deklaratywnej (lub ustawić je na wartość domyślną, {0}
).
Następnie ogranicz element GridView, aby uwzględniał tylko ProductName
, QuantityPerUnit
, UnitPrice
i UnitsInStock
pola związane. Możesz również zastosować dowolne formatowanie na poziomie pola, które uważasz za niezbędne (takie jak zmiana HeaderText
właściwości).
W poprzednim samouczku przyjrzeliśmy się, jak sformatować UnitPrice
pole BoundField jako walutę zarówno w trybie tylko do odczytu, jak i w trybie edycji. Zróbmy to samo tutaj. Pamiętaj, że to wymaga ustawienia właściwości BoundField DataFormatString
na {0:c}
, właściwości HtmlEncode
na false
, oraz właściwości ApplyFormatInEditMode
na true
, jak pokazano na rysunku 2.
Rysunek 2: Skonfiguruj pole powiązane UnitPrice
do wyświetlania jako waluty (Kliknij, aby zobaczyć obraz w pełnym rozmiarze)
Aby sformatować UnitPrice
jako walutę w interfejsie edycji, należy utworzyć procedurę obsługi zdarzeń dla zdarzenia GridViewRowUpdating
, która przetworzy ciąg sformatowany jako waluta na wartość typu decimal
. Pamiętaj, że RowUpdating
obsługujący zdarzenia z ostatniego samouczka również sprawdzał, czy użytkownik podał wartość UnitPrice
. Jednak w tym samouczku pozwólmy użytkownikowi pominąć cenę.
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
if (e.NewValues["UnitPrice"] != null)
e.NewValues["UnitPrice"] =decimal.Parse(e.NewValues["UnitPrice"].ToString(),
System.Globalization.NumberStyles.Currency);
}
Nasz element GridView zawiera QuantityPerUnit
BoundField, ale ten BoundField powinien być przeznaczony tylko do celów wyświetlania i nie powinien dawać możliwości edycji użytkownikowi. Aby to rozmieścić, po prostu ustaw właściwość BoundFields ReadOnly
na true
.
Rysunek 3: Utwórz QuantityPerUnit
BoundField Read-Only (Kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Na koniec zaznacz pole wyboru „Włącz edytowanie” w inteligentnym tagu GridView. Po wykonaniu tych kroków Designer strony ErrorHandling.aspx
powinien wyglądać podobnie do rysunku 4.
Rysunek 4. Usuń wszystkie pola oprócz potrzebnych pól wiążących i zaznacz pole wyboru Włącz edycję (kliknij, aby wyświetlić obraz pełnowymiarowy)
W tym momencie dysponujemy listą wszystkich pól produktów ProductName
, QuantityPerUnit
, UnitPrice
i UnitsInStock
; jednak tylko pola ProductName
, UnitPrice
i UnitsInStock
mogą być edytowane.
Rysunek 5. Użytkownicy mogą teraz łatwo edytować nazwy, ceny i jednostki w polach magazynowych (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 2. Bezproblemowa obsługa wyjątków DAL-Level
Podczas gdy nasz edytowalny element GridView działa znakomicie, gdy użytkownicy wprowadzają prawidłowe wartości dla nazwy, ceny i ilości jednostek produktu na stanie, wprowadzanie niedozwolonych wartości powoduje wyjątek. Na przykład pominięcie wartości ProductName
powoduje zgłoszenie wyjątku NoNullAllowedException, ponieważ właściwość ProductName
w klasie ProductsRow
ma właściwość AllowDBNull
ustawioną na false
; jeśli baza danych nie działa, wyjątek SqlException
zostanie rzucony przez TableAdapter podczas próby połączenia z bazą danych. Bez podejmowania jakichkolwiek działań, te wyjątki są przenoszone z warstwy dostępu do danych do warstwy logiki biznesowej, następnie do strony ASP.NET, a na koniec do uruchomienia ASP.NET.
W zależności od tego, jak aplikacja internetowa jest skonfigurowana i czy odwiedzasz aplikację z witryny localhost
, nieobsługiwany wyjątek może spowodować wyświetlenie ogólnej strony błędu serwera, szczegółowego raportu o błędach lub przyjaznej dla użytkownika strony internetowej. Zobacz Obsługa błędów aplikacji internetowej w ASP.NET i element customErrors, aby uzyskać więcej informacji na temat sposobu reagowania środowiska uruchomieniowego ASP.NET na nieuchwycony wyjątek.
Rysunek 6 przedstawia ekran napotkany podczas próby zaktualizowania produktu bez określania ProductName
wartości. Jest to domyślny szczegółowy raport o błędach wyświetlany w trakcie przechodzenia przez localhost
.
Rysunek 6. Pominięcie nazwy produktu spowoduje wyświetlenie szczegółów wyjątku (kliknij, aby wyświetlić obraz pełnowymiarowy)
Chociaż takie szczegóły wyjątku są przydatne podczas testowania aplikacji, prezentowanie użytkownikowi końcowego takiego ekranu w obliczu wyjątku jest mniej niż idealne. Użytkownik końcowy prawdopodobnie nie wie, co to NoNullAllowedException
jest lub dlaczego został spowodowany. Lepszym rozwiązaniem jest przedstawienie użytkownikowi bardziej przyjaznego dla użytkownika komunikatu wyjaśniającego, że wystąpiły problemy podczas próby zaktualizowania produktu.
Jeśli wystąpi wyjątek podczas wykonywania operacji, zdarzenia wykonywane po zakończeniu operacji zarówno w obiekcie ObjectDataSource, jak i w kontrolce danych sieci Web zapewniają środki do wykrycia tego i zapobieżenia jego przeniknięciu do środowiska uruchomieniowego ASP.NET. W naszym przykładzie utworzymy procedurę obsługi zdarzeń dla zdarzenia GridView RowUpdated
, która określa, czy został wyzwolony wyjątek, a jeśli tak, wyświetla szczegóły wyjątku w kontrolce etykiety sieci Web.
Zacznij od dodania etykiety do strony ASP.NET, ustawienie jej ID
właściwości na ExceptionDetails
i wyczyszczenie jej Text
właściwości. Aby przyciągnąć uwagę użytkownika do tej wiadomości, ustaw jego właściwość CssClass
na wartość Warning
, która jest klasą CSS dodaną do pliku Styles.css
w poprzednim samouczku. Pamiętaj, że ta klasa CSS powoduje wyświetlanie tekstu etykiety w czerwonej, pochylonej, pogrubionej, bardzo dużej czcionce.
Rysunek 7. Dodaj kontrolkę etykiety sieci Web do strony (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Ponieważ chcemy, aby ta kontrolka etykiety sieci Web była widoczna tylko od razu po wystąpieniu wyjątku, ustaw jej Visible
właściwość na false w procedurze Page_Load
obsługi zdarzenia:
protected void Page_Load(object sender, EventArgs e)
{
ExceptionDetails.Visible = false;
}
W przypadku tego kodu, podczas pierwszej wizyty na stronie i kolejnych postbacków, kontrolka ExceptionDetails
będzie miała swoją Visible
właściwość ustawioną na false
wartość. W obliczu wyjątku na poziomie DAL lub BLL, który można wykryć w procedurze obsługi zdarzeń GridView RowUpdated
, ustawimy właściwość ExceptionDetails
kontrolki Visible
na wartość true. Ponieważ programy obsługi zdarzeń kontroli sieci Web występują po Page_Load
procedurze obsługi zdarzeń w cyklu życia strony, zostanie wyświetlona etykieta. Jednak w następnym poście zwrotnym Page_Load
program obsługi zdarzeń przywróci Visible
właściwość z powrotem do false
, ukrywając ją ponownie przed wyświetleniem.
Uwaga / Notatka
Alternatywnie możemy usunąć konieczność ustawienia właściwości ExceptionDetails
kontrolki Visible
w Page_Load
, przypisując jej właściwość Visible
do false
w składni deklaratywnej i wyłączając jej stan widoku (ustawiając właściwość EnableViewState
na false
). Użyjemy tego alternatywnego podejścia w przyszłym tutorialu.
Po dodaniu kontrolki Label następnym krokiem jest utworzenie procedury obsługi zdarzenia dla zdarzenia GridView RowUpdated
. Wybierz element GridView w projektancie, przejdź do okna Właściwości i kliknij ikonę błyskawicy, aby wyświetlić listę zdarzeń GridView. Dla zdarzenia GridView RowUpdating
powinien już istnieć wpis, ponieważ wcześniej w tym samouczku utworzyliśmy jego obsługę. Utwórz również procedurę obsługi zdarzeń dla RowUpdated
zdarzenia.
Rysunek 8. Tworzenie programu obsługi zdarzeń dla zdarzenia GridView RowUpdated
Uwaga / Notatka
Program obsługi zdarzeń można również utworzyć za pomocą list rozwijanych w górnej części pliku klasy code-behind. Wybierz GridView z listy rozwijanej po lewej stronie, a zdarzenie RowUpdated
po prawej stronie.
Utworzenie tej obsługi zdarzeń spowoduje dodanie następującego kodu do klasy code-behind strony ASP.NET.
protected void GridView1_RowUpdated(object sender, GridViewUpdatedEventArgs e)
{
}
Drugi parametr wejściowy tego programu obsługi zdarzeń jest obiektem typu GridViewUpdatedEventArgs, który ma trzy interesujące właściwości obsługi wyjątków:
-
Exception
odwołanie do zgłaszanego wyjątku; jeśli nie zgłoszono wyjątku, ta właściwość będzie miała wartośćnull
-
ExceptionHandled
wartość logiczna wskazująca, czy wyjątek został obsłużony wRowUpdated
procedurze obsługi zdarzeń; jeślifalse
(wartość domyślna), wyjątek jest ponownie wyrzucany, przechodząc do środowiska uruchomieniowego ASP.NET -
KeepInEditMode
jeślitrue
jest ustawiony, edytowany wiersz GridView pozostaje w trybie edycji; jeślifalse
(wartość domyślna), wiersz GridView zostaje przywrócony do trybu tylko do odczytu.
Nasz kod powinien sprawdzać, czy Exception
nie jest równy null
, co oznacza, że podczas wykonywania operacji został zgłoszony wyjątek. Jeśli tak jest, chcemy:
- Wyświetlanie przyjaznego dla użytkownika komunikatu w etykiecie
ExceptionDetails
- Informuje, że wyjątek został obsłużony
- Zachowaj wiersz GridView w trybie edycji
Ten poniższy kod realizuje następujące cele:
protected void GridView1_RowUpdated(object sender, GridViewUpdatedEventArgs e)
{
if (e.Exception != null)
{
// Display a user-friendly message
ExceptionDetails.Visible = true;
ExceptionDetails.Text = "There was a problem updating the product. ";
if (e.Exception.InnerException != null)
{
Exception inner = e.Exception.InnerException;
if (inner is System.Data.Common.DbException)
ExceptionDetails.Text +=
"Our database is currently experiencing problems." +
"Please try again later.";
else if (inner is NoNullAllowedException)
ExceptionDetails.Text +=
"There are one or more required fields that are missing.";
else if (inner is ArgumentException)
{
string paramName = ((ArgumentException)inner).ParamName;
ExceptionDetails.Text +=
string.Concat("The ", paramName, " value is illegal.");
}
else if (inner is ApplicationException)
ExceptionDetails.Text += inner.Message;
}
// Indicate that the exception has been handled
e.ExceptionHandled = true;
// Keep the row in edit mode
e.KeepInEditMode = true;
}
}
Ta procedura obsługi zdarzeń rozpoczyna się od sprawdzenia, czy e.Exception
jest null
. Jeśli tak nie jest, ExceptionDetails
właściwość Label Visible
jest ustawiona na true
, a jej Text
właściwość ma wartość "Wystąpił problem podczas aktualizowania produktu". Szczegóły rzeczywistego wyjątku, który został zgłoszony, znajdują się we e.Exception
właściwości obiektu InnerException
. Ten wyjątek wewnętrzny jest badany i, jeśli jest to określony typ, dodatkowy, pomocny komunikat jest dołączany do właściwości ExceptionDetails
Etykiety Text
. Na koniec, właściwości ExceptionHandled
i KeepInEditMode
są ustawione na true
wartość.
Rysunek 9 przedstawia zrzut ekranu tej strony podczas pomijania nazwy produktu; Rysunek 10 przedstawia wyniki podczas wprowadzania niedozwolonej UnitPrice
wartości (-50).
Rysunek 9. Pole BoundField musi zawierać wartość (ProductName
)
Rysunek 10. Wartości ujemne UnitPrice
są niedozwolone (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Ustawiając e.ExceptionHandled
właściwość na true
, RowUpdated
program obsługi zdarzeń wskazał, że obsłużył wyjątek. W związku z tym wyjątek nie będzie propagowany do środowiska uruchomieniowego ASP.NET.
Uwaga / Notatka
Na rysunkach 9 i 10 przedstawiono wdziękny sposób obsługi wyjątków zgłoszonych z powodu nieprawidłowych danych wejściowych użytkownika. W idealnym przypadku takie nieprawidłowe dane wejściowe nigdy nie dotrą do warstwy logiki biznesowej, ponieważ strona ASP.NET powinna upewnić się, że dane wejściowe użytkownika są prawidłowe przed wywołaniem ProductsBLL
metody klasy UpdateProduct
. W następnym samouczku zobaczymy, jak dodać kontrolki walidacji do interfejsów edycji i wstawiania, aby upewnić się, że dane przesłane do warstwy logiki biznesowej są zgodne z regułami biznesowymi. Kontrolki sprawdzania poprawności nie tylko uniemożliwiają wywołanie UpdateProduct
metody, dopóki dane dostarczone przez użytkownika nie będą prawidłowe, ale także zapewniają bardziej informacyjne środowisko użytkownika do identyfikowania problemów z wprowadzaniem danych.
Krok 3. Bezproblemowa obsługa wyjątków BLL-Level
Podczas wstawiania, aktualizowania lub usuwania danych warstwa dostępu do danych może zgłosić wyjątek w obliczu błędu związanego z danymi. Baza danych może być w trybie offline, wymagana kolumna tabeli bazy danych może nie mieć określonej wartości lub ograniczenie na poziomie tabeli mogło zostać naruszone. Oprócz ściśle powiązanych z danymi wyjątków warstwa logiki biznesowej może używać wyjątków, aby wskazać, kiedy reguły biznesowe zostały naruszone. Na przykład w samouczku Tworzenie warstwy logiki biznesowej dodaliśmy sprawdzanie reguły biznesowej do oryginalnego UpdateProduct
przeciążenia. W szczególności, jeśli użytkownik oznaczył produkt jako zaprzestany, wymagamy, aby produkt nie był jedynym produktem dostarczonym przez dostawcę. Jeśli ten warunek został naruszony, zgłoszono wyjątek typu ApplicationException
.
W przypadku przeciążenia utworzonego w tym samouczku UpdateProduct
, dodajmy regułę biznesową, która uniemożliwia ustawienie pola UnitPrice
na nową wartość większą niż dwa razy oryginalna wartość UnitPrice
. Aby to osiągnąć, dostosuj UpdateProduct
przeciążenie, aby wykonało to sprawdzanie i zgłasza ApplicationException
błąd, jeśli reguła zostanie naruszona. Zaktualizowana metoda jest następująca:
public bool UpdateProduct(string productName, decimal? unitPrice, short? unitsInStock,
int productID)
{
Northwind.ProductsDataTable products = Adapter.GetProductByProductID(productID);
if (products.Count == 0)
// no matching record found, return false
return false;
Northwind.ProductsRow product = products[0];
// Make sure the price has not more than doubled
if (unitPrice != null && !product.IsUnitPriceNull())
if (unitPrice > product.UnitPrice * 2)
throw new ApplicationException(
"When updating a product price," +
" the new price cannot exceed twice the original price.");
product.ProductName = productName;
if (unitPrice == null) product.SetUnitPriceNull();
else product.UnitPrice = unitPrice.Value;
if (unitsInStock == null) product.SetUnitsInStockNull();
else product.UnitsInStock = unitsInStock.Value;
// Update the product record
int rowsAffected = Adapter.Update(product);
// Return true if precisely one row was updated, otherwise false
return rowsAffected == 1;
}
Dzięki tej zmianie każda aktualizacja ceny, która jest ponad dwukrotnie wyższa od istniejącej ceny, spowoduje, że błąd ApplicationException
zostanie zgłoszony. Podobnie jak w przypadku wyjątku zgłoszonego z DAL, wyjątek zgłoszony przez BLL ApplicationException
można wykryć i obsłużyć w procedurze obsługi zdarzeń GridView RowUpdated
. W rzeczywistości kod obsługi zdarzeń RowUpdated
, tak jak zostało napisane, poprawnie wykryje ten wyjątek i wyświetli wartość właściwości ApplicationException
dla Message
. Rysunek 11 przedstawia zrzut ekranu, gdy użytkownik próbuje zaktualizować cenę Chai do 50,00 USD, co jest ponad dwukrotnie większe niż jego bieżąca cena w wysokości 19,95 USD.
Rysunek 11. Reguły biznesowe nie zezwalają na wzrost cen więcej niż dwukrotnie ceny produktu (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Uwaga / Notatka
Najlepiej, aby nasze reguły logiki biznesowej zostały przeniesione z przeciążeń metody UpdateProduct
do wspólnej metody. Pozostaje to ćwiczenie dla czytelnika.
Podsumowanie
Podczas operacji wstawiania, aktualizowania i usuwania zarówno kontrolka danych sieci Web, jak i obiekt ObjectDataSource wyzwalają zdarzenia na poziomie wstępnym i końcowym, które otaczają rzeczywistą operację. Jak pokazano w tym samouczku i poprzednim, podczas pracy z edytowalnym elementem GridView uruchamiane jest zdarzenie GridView RowUpdating
, a następnie zdarzenie ObjectDataSource, w którym to momencie następuje aktualizacja bazowego obiektu ObjectDataSource Updating
. Po zakończeniu operacji najpierw zostanie wyzwolone zdarzenie ObjectDataSource Updated
, a następnie GridView RowUpdated
.
Możemy utworzyć programy obsługi zdarzeń dla zdarzeń wstępnych w celu dostosowania parametrów wejściowych lub zdarzeń po poziomie w celu sprawdzenia wyników operacji i reagowania na nie. Procedury obsługi zdarzeń na poziomie post są najczęściej używane do wykrywania, czy wystąpił wyjątek podczas operacji. W obliczu wyjątku te programy obsługi zdarzeń po poziomie mogą opcjonalnie obsługiwać wyjątek samodzielnie. W tym samouczku pokazano, jak obsłużyć taki wyjątek, wyświetlając przyjazny komunikat o błędzie.
W następnym samouczku zobaczymy, jak zmniejszyć prawdopodobieństwo wyjątków wynikających z problemów z formatowaniem danych (na przykład wprowadzenie ujemnego UnitPrice
). W szczególności przyjrzymy się sposobom dodawania kontrolek weryfikacji do interfejsów edycji i wstawiania.
Szczęśliwe programowanie!
Informacje o autorze
Scott Mitchell, autor siedmiu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w ciągu 24 godzin. Można go uzyskać pod adresem mitchell@4GuysFromRolla.com.
Specjalne podziękowania
Ta seria samouczków została omówiona przez wielu przydatnych recenzentów. Głównym recenzentem tego samouczka była Liz Shulok. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, napisz do mnie na adres mitchell@4GuysFromRolla.com.