Notatka
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: Web Camps Team
Nowa wersja ASP.NET Web Forms wprowadza szereg ulepszeń skoncentrowanych na ulepszaniu środowiska użytkownika podczas pracy z danymi.
W poprzednich wersjach formularzy sieci Web podczas używania powiązania danych do emitowania wartości elementu członkowskiego obiektu użyto wyrażeń powiązania danych Bind() lub Eval(). W nowej wersji ASP.NET można zadeklarować typ danych, z którymi ma być powiązana kontrolka przy użyciu nowej właściwości ItemType. Ustawienie tej właściwości umożliwi ci korzystanie z silnie typizowanej zmiennej, aby w pełni czerpać korzyści ze środowiska programistycznego Visual Studio, takich jak IntelliSense, nawigacja między elementami członkowskimi i sprawdzanie w czasie kompilacji.
Za pomocą kontrolek powiązanych z danymi można teraz również określić własne niestandardowe metody wybierania, aktualizowania, usuwania i wstawiania danych, upraszczając interakcję między kontrolkami strony a logiką aplikacji. Ponadto możliwości powiązania modelu zostały dodane do ASP.NET, co oznacza, że można mapować dane ze strony bezpośrednio do parametrów typu metody.
Walidacja danych wejściowych użytkownika powinna być również łatwiejsza w najnowszej wersji formularzy sieci Web. Możesz teraz opatrzyć klasy modelu adnotacjami za pomocą atrybutów weryfikacji z przestrzeni nazw System.ComponentModel.DataAnnotations i żądać, aby wszystkie kontrolki witryny sprawdzały poprawność danych wejściowych na podstawie tych informacji. Walidacja po stronie klienta w formularzach internetowych jest teraz zintegrowana z rozwiązaniem jQuery, zapewniając czystszy kod po stronie klienta i nietrudne funkcje języka JavaScript.
W obszarze weryfikacji żądań wprowadzono ulepszenia ułatwiające selektywne wyłączanie weryfikacji żądań dla określonych części aplikacji lub odczytywanie nieprawidłowych danych żądania.
Wprowadzono pewne ulepszenia kontrolek serwera Web Forms w celu korzystania z nowych funkcji HTML5:
- Właściwość TextMode kontrolki TextBox została zaktualizowana w celu obsługi nowych typów danych wejściowych HTML5, takich jak poczta e-mail, data/godzina itd.
- Kontrolka FileUpload obsługuje teraz wiele plików przekazywanych z przeglądarek, które obsługują tę funkcję HTML5.
- Kontrolki modułu sprawdzania poprawności obsługują teraz weryfikowanie elementów wejściowych HTML5.
- Nowe elementy HTML5, które mają atrybuty reprezentujące adres URL, obsługują teraz element runat="server". W związku z tym można użyć konwencji ASP.NET w ścieżkach url, takich jak operator ~ do reprezentowania katalogu głównego aplikacji (na przykład <video runat="server" src="~/myVideo.wmv"></video>).
- Kontrolka UpdatePanel została naprawiona w celu obsługi publikowania pól wejściowych HTML5.
W oficjalnym portalu ASP.NET można znaleźć więcej przykładów nowych funkcji w programie ASP.NET WebForms 4.5: What's New in ASP.NET 4.5 and Visual Studio 2012 (Co nowego w programie ASP.NET 4.5 i programie Visual Studio 2012)
Cały przykładowy kod i fragmenty kodu znajdują się w zestawie szkoleniowym Web Camps Training Kit.
Cele
W tym praktycznym laboratorium dowiesz się, jak wykonywać następujące działania:
- Używanie silnie typowanych wyrażeń powiązania danych
- Korzystanie z nowych funkcji powiązania modelu w formularzach sieci Web
- Używanie dostawców wartości do mapowania danych strony na metody code-behind
- Używanie adnotacji danych do sprawdzania poprawności danych wejściowych użytkownika
- Korzystanie z nieinwazyjnej weryfikacji po stronie klienta za pomocą jQuery w formularzach internetowych
- Implementowanie szczegółowej weryfikacji żądań
- Implementowanie asynchronicznego przetwarzania stron w formularzach internetowych
Wymagania wstępne
Aby ukończyć to laboratorium, musisz mieć następujące elementy:
- Microsoft Visual Studio Express 2012 for Web lub superior (przeczytaj dodatek A , aby uzyskać instrukcje dotyczące sposobu jego instalowania).
Ustawienia
Instalowanie fragmentów kodu
Dla wygody większość kodu, którym będziesz zarządzać w tym laboratorium, jest dostępna jako fragmenty kodu programu Visual Studio. Aby zainstalować fragmenty kodu, uruchom plik .\Source\Setup\CodeSnippets.vsi .
Jeśli nie znasz fragmentów kodu programu Visual Studio Code i chcesz dowiedzieć się, jak z nich korzystać, możesz zapoznać się z dodatkiem z tego dokumentu "Dodatek C: Używanie fragmentów kodu".
Ćwiczenia
To praktyczne laboratorium obejmuje następujące ćwiczenia:
- Ćwiczenie 1. Powiązanie modelu w ASP.NET Web Forms
- Ćwiczenie 2. Sprawdzanie poprawności danych
- Ćwiczenie 3. Asynchroniczne przetwarzanie stron w ASP.NET Web Forms
Uwaga
Każde ćwiczenie jest dołączone do folderu End zawierającego wynikowe rozwiązanie, które należy uzyskać po zakończeniu ćwiczeń. Możesz użyć tego rozwiązania jako przewodnika, jeśli potrzebujesz dodatkowej pomocy podczas wykonywania ćwiczeń.
Szacowany czas ukończenia tego laboratorium: 60 minut.
Ćwiczenie 1. Powiązanie modelu w ASP.NET Web Forms
Nowa wersja ASP.NET Web Forms wprowadza szereg ulepszeń skoncentrowanych na ulepszaniu środowiska pracy z danymi. W tym ćwiczeniu poznasz silnie typizowane kontrolki danych i wiązanie modelu.
Zadanie 1 — używanie silnie typiowanych powiązań danych
W tym zadaniu poznasz nowe silnie typizowane powiązania dostępne w ASP.NET 4.5.
Otwórz rozwiązanie Rozpocznij znajdujące się w folderze Source/Ex1-ModelBinding/Begin/.
Zanim przejdziesz dalej, musisz pobrać brakujące pakiety NuGet. W tym celu kliknij menu Projekt i wybierz pozycję Zarządzaj pakietami NuGet.
W oknie dialogowym Zarządzanie pakietami NuGet kliknij pozycję Przywróć, aby pobrać brakujące pakiety.
Na koniec skompiluj rozwiązanie, klikając Kompiluj | Kompiluj Rozwiązanie.
Uwaga
Jedną z zalet korzystania z narzędzia NuGet jest to, że nie trzeba dostarczać wszystkich bibliotek w projekcie, zmniejszając rozmiar projektu. Za pomocą narzędzi NuGet Power Tools, określając wersje pakietów w pliku Packages.config, będzie można pobrać wszystkie wymagane biblioteki przy pierwszym uruchomieniu projektu. Dlatego po otwarciu istniejącego rozwiązania z tego laboratorium będziesz musiał wykonać te kroki.
Otwórz stronę Customers.aspx. Umieść listę nienumerowaną w głównej kontrolce i dołącz kontrolkę repeatera do listy każdego klienta. Ustaw nazwę repeatera na customersRepeater , jak pokazano w poniższym kodzie.
W poprzednich wersjach formularzy sieci Web, gdy korzysta się z powiązania danych, aby uzyskać wartość członka obiektu, do którego następuje to powiązanie, należy użyć wyrażenia powiązania danych wraz z wywołaniem metody Eval, przekazując nazwę tego członka jako ciąg znaków.
W czasie wykonywania te wywołania Eval będą używać refleksji względem aktualnie powiązanego obiektu, aby odczytać wartość członu o podanej nazwie i wyświetlić wynik w HTML. Takie podejście sprawia, że bardzo łatwo powiązać dane z dowolnymi danymi bez określonej struktury.
Niestety, utracisz wiele doskonałych funkcji ułatwiających pracę w trakcie programowania w programie Visual Studio, w tym funkcję IntelliSense dla nazw członków, wsparcie nawigacyjne (np. przejdź do definicji) i sprawdzanie w czasie kompilacji.
... <asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server"> <h3>Customers</h3> <ul> <asp:Repeater ID="customersRepeater" runat="server"> <ItemTemplate> <li> <%# Eval("FirstName") %> <%# Eval("LastName") %> </li> </ItemTemplate> </asp:Repeater> </ul> <a href="CustomerDetails.aspx">Add a New Customer</a> </asp:Content>Otwórz plik Customers.aspx.cs.
Dodaj następującą instrukcję using.
using System.Linq;W metodzie Page_Load dodaj kod, aby wypełnić repeater listą klientów.
(Fragment kodu — Laboratorium formularzy internetowych — Ex01 — wiązanie źródła danych klientów)
protected void Page_Load(object sender, EventArgs e) { using (var db = new WebFormsLab.Model.ProductsContext()) { this.customersRepeater.DataSource = db.Customers.ToList(); this.customersRepeater.DataBind(); } }Rozwiązanie używa EntityFramework razem z podejściem CodeFirst, aby utworzyć bazę danych i uzyskać do niej dostęp. W poniższym kodzie, customersRepeater jest powiązany z zmaterializowanym zapytaniem, które zwraca wszystkich klientów z bazy danych.
Naciśnij F5, aby uruchomić rozwiązanie i przejdź do strony Klienci, aby zobaczyć działanie powielacza. Ponieważ rozwiązanie używa metody CodeFirst, baza danych zostanie utworzona i wypełniona w lokalnym wystąpieniu usługi SQL Express podczas uruchamiania aplikacji.
Wyświetlanie listy klientów za pomocą repeatera
Uwaga
W programie Visual Studio 2012 usługa IIS Express jest domyślnym serwerem tworzenia aplikacji internetowych.
Zamknij przeglądarkę i wróć do programu Visual Studio.
Teraz zastąp implementację, aby używać silnie typowanych powiązań. Otwórz stronę Customers.aspx i użyj nowego atrybutu ItemType w repeaterze, aby ustawić typ klienta jako typ powiązania.
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <ul> <asp:Repeater ID="customersRepeater" ItemType="WebFormsLab.Model.Customer" runat="server"> <ItemTemplate> ... </ItemTemplate> </asp:Repeater> </ul> <a href="CustomerDetails.aspx">Add a New Customer</a> </asp:Content>Właściwość ItemType umożliwia zadeklarowanie typu danych, z którymi ma być powiązana kontrolka, i umożliwia użycie silnie typizowanego powiązania wewnątrz kontrolki powiązanej z danymi.
Zastąp zawartość ItemTemplate następującym kodem.
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> ... <ul> <asp:Repeater ID="customersRepeater" ItemType="WebFormsLab.Model.Customer" runat="server"> <ItemTemplate> <li> <a href="CustomerDetails.aspx?id=<%#: Item.Id %>"> <%#: Item.FirstName %> <%#: Item.LastName %> </a> </li> </ItemTemplate> </asp:Repeater> </ul> <a href="CustomerDetails.aspx">Add a New Customer</a> </asp:Content>Jedną z wad powyższych podejść jest to, że wywołania Eval() i Bind() są późnym wiązaniem, czyli przekazywanie ciągów znaków, które reprezentują nazwy właściwości. Oznacza to, że nie uzyskujesz funkcji IntelliSense dla nazw elementów członkowskich, obsługi nawigacji kodu (takiej jak Przejdź do definicji), ani obsługi sprawdzania czasu kompilacji.
Ustawienie właściwości ItemType powoduje wygenerowanie dwóch nowych zmiennych typowych w zakresie wyrażeń powiązania danych: Item i BindItem. Te silnie typizowane zmienne można używać w wyrażeniach powiązania danych i uzyskać pełne korzyści wynikające z programowania w programie Visual Studio.
Wyrażenie ": " używane w wyrażeniu automatycznie koduje dane wyjściowe w formacie HTML, aby uniknąć problemów z zabezpieczeniami (na przykład ataków skryptowych między witrynami). Ta notacja była dostępna od platformy .NET 4 na potrzeby pisania odpowiedzi, ale teraz jest również dostępna w wyrażeniach powiązania danych.
Uwaga
Członek Item działa w przypadku powiązania jednokierunkowego. Jeśli chcesz wykonać powiązanie dwukierunkowe, użyj członka BindItem.
Obsługa funkcji IntelliSense w silnie typiowanym powiązaniu
Naciśnij F5 , aby uruchomić rozwiązanie i przejdź do strony Klienci, aby upewnić się, że zmiany działają zgodnie z oczekiwaniami.
Wyświetlanie listy szczegółów klienta
Zamknij przeglądarkę i wróć do programu Visual Studio.
Zadanie 2 - Wprowadzenie do wiązania modelu w formularzach webowych
W poprzednich wersjach ASP.NET Web Forms, gdy chcesz wykonać dwukierunkowe powiązanie danych, zarówno pobieranie, jak i aktualizowanie danych, należy użyć obiektu Źródła danych. Może to być źródło danych obiektu, źródło danych SQL, źródło danych LINQ itd. Jeśli jednak w scenariuszu wymagany jest kod niestandardowy do obsługi danych, konieczne jest użycie źródła danych obiektu, co przyniosło pewne wady. Na przykład należy unikać złożonych typów i trzeba było obsługiwać wyjątki podczas wykonywania logiki walidacji.
W nowej wersji ASP.NET Web Forms kontrolki powiązane z danymi obsługują powiązanie modelu. Oznacza to, że można określić metody wybierania, aktualizowania, wstawiania i usuwania bezpośrednio w kontrolce powiązanej z danymi, aby wywołać logikę z pliku code-behind lub z innej klasy.
Aby dowiedzieć się więcej na ten temat, użyjesz kontrolki GridView, aby wyświetlić listę kategorii produktów przy użyciu nowego atrybutu SelectMethod . Ten atrybut umożliwia określenie metody pobierania danych GridView.
Otwórz stronę Products.aspx i dołącz element GridView. Skonfiguruj obiekt GridView, jak pokazano poniżej, aby używać silnie typiowanych powiązań i włączać sortowanie i stronicowanie.
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server"> <asp:GridView ID="categoriesGrid" runat="server" AutoGenerateColumns="false" ItemType="WebFormsLab.Model.Category" DataKeyNames="CategoryID"> <Columns> <asp:BoundField DataField="CategoryId" HeaderText="ID" SortExpression="CategoryId" /> <asp:BoundField DataField="CategoryName" HeaderText="Name" SortExpression="CategoryName" /> <asp:BoundField DataField="Description" HeaderText="Description" /> <asp:TemplateField HeaderText="# of Products"> <ItemTemplate><%#: Item.Products.Count %></ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> </asp:Content>Użyj nowego atrybutu SelectMethod , aby skonfigurować element GridView w celu wywołania metody GetCategories w celu wybrania danych.
<asp:GridView ID="categoriesGrid" runat="server" AutoGenerateColumns="false" ItemType="WebFormsLab.Model.Category" DataKeyNames="CategoryId" SelectMethod="GetCategories"> <Columns> <asp:BoundField DataField="CategoryId" HeaderText="ID" SortExpression="CategoryId" /> <asp:BoundField DataField="CategoryName" HeaderText="Name" SortExpression="CategoryName" /> <asp:BoundField DataField="Description" HeaderText="Description" /> <asp:TemplateField HeaderText="# of Products"> <ItemTemplate><%#: Item.Products.Count %></ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView>Otwórz plik zaplecza kodu Products.aspx.cs i dodaj następujące dyrektywy using.
(Fragment kodu — Laboratorium formularzy internetowych — Ex01 — Przestrzenie nazw)
using System.Collections.Generic; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Linq; using WebFormsLab.Model;Dodaj prywatny element członkowski w klasie Products i przypisz nowe wystąpienie klasy ProductsContext. Ta właściwość będzie przechowywać kontekst danych programu Entity Framework, który umożliwia nawiązywanie połączenia z bazą danych.
public partial class Products : System.Web.UI.Page { private ProductsContext db = new ProductsContext(); ...Utwórz metodę GetCategories , aby pobrać listę kategorii przy użyciu LINQ. Zapytanie będzie zawierać właściwość Products , aby kontrolka GridView mogła wyświetlać ilość produktów dla każdej kategorii. Zwróć uwagę, że metoda zwraca surowy obiekt IQueryable, który reprezentuje zapytanie do wykonania w dalszej części cyklu życia strony.
(Fragment kodu — Laboratorium formularzy internetowych — Ex01 — GetCategories)
public IQueryable<Category> GetCategories() { var query = this.db.Categories .Include(c => c.Products); return query; }Uwaga
W poprzednich wersjach ASP.NET Web Forms włączanie sortowania i stronicowania przy użyciu własnej logiki repozytorium w kontekście Źródła Danych Obiektowych wymagało pisania własnego kodu niestandardowego i odbierania wszystkich niezbędnych parametrów. Teraz, ponieważ metody powiązania danych mogą zwracać zapytanie IQueryable i reprezentuje to zapytanie, które nadal ma być wykonywane, ASP.NET może dbać o modyfikowanie zapytania w celu dodania odpowiednich parametrów sortowania i stronicowania.
Naciśnij F5 , aby rozpocząć debugowanie witryny i przejdź do strony Produkty. Powinien zostać wyświetlony widok GridView wypełniony kategoriami zwróconymi przez metodę GetCategories.
Wypełnianie kontrolki GridView z wykorzystaniem bindowania modelu
Naciśnij SHIFT+F5 Zatrzymaj debugowanie.
Zadanie 3 — Dostawcy wartości w wiązaniu modelu
Powiązanie modelu umożliwia nie tylko określanie niestandardowych metod pracy z danymi bezpośrednio w kontrolce powiązanej z danymi, ale także umożliwia mapowanie danych ze strony na parametry z tych metod. W parametrze metody można użyć atrybutów dostawcy wartości, aby określić źródło danych wartości. Na przykład:
- Kontrolki na stronie
- Wartości ciągu zapytania
- Wyświetlanie danych
- Stan sesji
- Pliki cookie
- Opublikowane dane formularza
- Stan widoku
- Dostawcy wartości niestandardowych są również obsługiwani
Jeśli użyto ASP.NET MVC 4, zauważysz, że obsługa powiązań modelu jest podobna. Rzeczywiście, te funkcje zostały pobrane z ASP.NET MVC i przeniesione do zestawu System.Web, aby móc ich również używać w formularzach Web Forms.
W tym zadaniu zaktualizujesz kontrolkę GridView, aby filtrować wyniki według ilości produktów dla każdej kategorii, odbierając parametr filtru z powiązaniem modelu.
Wróć na stronę Products.aspx.
Na górze GridView dodaj etykietę i ComboBox, aby wybrać liczbę produktów dla każdej kategorii, jak poniżej.
<h3>Categories</h3> <asp:Label ID="Label1" runat="server" AssociatedControlID="minProductsCount"> Show categories with at least this number of products: </asp:Label> <asp:DropDownList runat="server" ID="minProductsCount" AutoPostBack="true"> <asp:ListItem Value="" Text="-" /> <asp:ListItem Text="1" /> <asp:ListItem Text="3" /> <asp:ListItem Text="5" /> </asp:DropDownList> <br/>Dodaj element EmptyDataTemplate do kontrolki GridView, aby wyświetlić komunikat, gdy nie ma żadnych kategorii z wybraną liczbą produktów.
<asp:GridView ID="categoriesGrid" runat="server" AutoGenerateColumns="false" ItemType="WebFormsLab.Model.Category" DataKeyNames="CategoryId" SelectMethod="GetCategories"> <Columns> <asp:BoundField DataField="CategoryId" HeaderText="ID" /> <asp:BoundField DataField="CategoryName" HeaderText="Name" /> <asp:BoundField DataField="Description" HeaderText="Description" /> <asp:TemplateField HeaderText="# of Products"> <ItemTemplate><%#: Item.Products.Count %></ItemTemplate> </asp:TemplateField> </Columns> <EmptyDataTemplate> No categories found with a product count of <%#: minProductsCount.SelectedValue %> </EmptyDataTemplate> </asp:GridView>Otwórz plik Products.aspx.cs z kodem zaplecza i dodaj następującą instrukcję using.
using System.Web.ModelBinding;Zmodyfikuj metodę GetCategories, aby otrzymać jako argument liczbę całkowitą minProductsCount i przefiltrować zwrócone wyniki. W tym celu zastąp metodę następującym kodem.
(Fragment kodu — Laboratorium formularzy internetowych — Ex01 — GetCategories 2)
public IQueryable<Category> GetCategories([Control]int? minProductsCount) { var query = this.db.Categories .Include(c => c.Products); if (minProductsCount.HasValue) { query = query.Where(c => c.Products.Count >= minProductsCount); } return query; }Nowy atrybut [Control] w argumencie minProductsCount poinformuje ASP.NET, że jego wartość musi zostać wypełniona za pomocą kontrolki na stronie. ASP.NET wyszuka dowolną kontrolkę zgodną z nazwą argumentu (minProductsCount) i wykona niezbędne mapowanie i konwersję, aby wypełnić parametr wartością kontrolki.
Alternatywnie atrybut udostępnia przeciążony konstruktor, który umożliwia określenie kontrolki, z której ma być pobierana wartość.
Uwaga
Jednym z celów funkcji powiązania danych jest zmniejszenie ilości kodu, który należy napisać na potrzeby interakcji ze stroną. Oprócz dostawcy wartości [Control] można użyć innych dostawców powiązania modelu w parametrach metody. Niektóre z nich są wymienione we wprowadzeniu do zadania.
Naciśnij F5 , aby rozpocząć debugowanie witryny i przejdź do strony Produkty. Wybierz kilka produktów z listy rozwijanej i zwróć uwagę na sposób aktualizacji kontrolki GridView.
Filtrowanie kontrolki GridView przy użyciu wartości listy rozwijanej
Zatrzymaj debugowanie.
Zadanie 4 . Używanie powiązania modelu do filtrowania
W tym zadaniu dodasz drugą podrzędną kontrolkę GridView, aby wyświetlić produkty w wybranej kategorii.
Otwórz stronę Products.aspx i zaktualizuj kategorie GridView, aby automatycznie wygenerować przycisk Wybierz.
<asp:GridView ID="categoriesGrid" runat="server" AutoGenerateColumns="false" ItemType="WebFormsLab.Model.Category" DataKeyNames="CategoryId" SelectMethod="GetCategories" AutoGenerateSelectButton="true">Dodaj drugi element GridView o nazwie productsGrid u dołu. Ustaw wartość ItemType na WebFormsLab.Model.Product, wartości DataKeyNames na ProductId i SelectMethod na GetProducts. Ustaw AutoGenerateColumns na false i dodaj kolumny ProductId, ProductName, Description i UnitPrice.
<h3>Products</h3> <asp:GridView ID="productsGrid" runat="server" CellPadding="4" AutoGenerateColumns="false" ItemType="WebFormsLab.Model.Product" DataKeyNames="ProductId" SelectMethod="GetProducts"> <Columns> <asp:BoundField DataField="ProductId" HeaderText="ID" /> <asp:BoundField DataField="ProductName" HeaderText="Name" /> <asp:BoundField DataField="Description" HeaderText="Description" HtmlEncode="false" /> <asp:BoundField DataField="UnitPrice" HeaderText="Price" /> </Columns> <EmptyDataTemplate> Select a category above to see its products </EmptyDataTemplate> </asp:GridView>Otwórz plik kodu zaplecza Products.aspx.cs. Zaimplementuj metodę GetProducts, aby odebrać identyfikator kategorii z kategorii GridView i przefiltrować produkty. Powiązanie modelu spowoduje ustawienie wartości parametru przy użyciu wybranego wiersza w kategoriiGrid. Ponieważ nazwa argumentu i nazwa kontrolki nie są zgodne, należy określić nazwę kontrolki w dostawcy wartości kontrolki.
(Fragment kodu — Laboratorium formularzy internetowych — Ex01 — GetProducts)
public IEnumerable<Product> GetProducts([Control("categoriesGrid")]int? categoryId) { return this.db.Products.Where(p => p.CategoryId == categoryId); }Uwaga
Takie podejście ułatwia testowanie jednostkowe tych metod. W kontekście testu jednostkowego, w którym nie są wykonywane formularze sieci Web, atrybut [Control] nie będzie wykonywać żadnej konkretnej akcji.
Otwórz stronę Products.aspx i znajdź produkty GridView. Zaktualizuj element GridView produktów, aby wyświetlić link do edycji wybranego produktu.
<h3>Products</h3> <asp:GridView ID="productsGrid" runat="server" CellPadding="4" AutoGenerateColumns="false" ItemType="WebFormsLab.Model.Product" DataKeyNames="ProductId" SelectMethod="GetProducts"> <Columns> <asp:TemplateField> <ItemTemplate> <a href="ProductDetails.aspx?productId=<%#: Item.ProductId %>">View</a> </ItemTemplate> </asp:TemplateField> <asp:BoundField DataField="ProductId" HeaderText="ID" /> <asp:BoundField DataField="ProductName" HeaderText="Name" /> <asp:BoundField DataField="Description" HeaderText="Description" HtmlEncode="false" /> <asp:BoundField DataField="UnitPrice" HeaderText="Price" /> </Columns> <EmptyDataTemplate> Select a category above to see its products </EmptyDataTemplate> </asp:GridView>Otwórz kod strony ProductDetails.aspx i zastąp metodę SelectProduct następującym kodem.
(Fragment kodu — Web Forms Lab — Ex01 — SelectProduct Method)
public Product SelectProduct([QueryString]int? productId) { return this.db.Products.Find(productId); }Uwaga
Zwróć uwagę, że atrybut [QueryString] jest używany do wypełnienia parametru metody z parametru productId w ciągu zapytania.
Naciśnij F5 , aby rozpocząć debugowanie witryny i przejdź do strony Produkty. Wybierz dowolną kategorię z kategorii GridView i zwróć uwagę, że produkty GridView zostały zaktualizowane.
Pokazywanie produktów z wybranej kategorii
Kliknij link Wyświetl dla produktu, aby otworzyć stronę ProductDetails.aspx.
Zwróć uwagę, że strona pobiera produkt za pomocą parametru SelectMethod przy użyciu parametru productId z ciągu zapytania.
Wyświetlanie szczegółów produktu
Uwaga
Możliwość wpisywania opisu HTML zostanie zaimplementowana w następnym ćwiczeniu.
Zadanie 5 . Używanie powiązania modelu dla operacji aktualizacji
W poprzednim zadaniu użyto powiązania modelu głównie do wybierania danych. W tym zadaniu dowiesz się, jak używać powiązania modelu w operacjach aktualizacji.
Zaktualizujesz kategorie GridView, aby zezwolić użytkownikowi na aktualizowanie kategorii.
Otwórz stronę Products.aspx i zaktualizuj kategorie GridView, aby automatycznie wygenerować przycisk Edytuj i użyć nowego atrybutu UpdateMethod, aby określić metodę UpdateCategory w celu zaktualizowania wybranego elementu.
<asp:GridView ID="categoriesGrid" runat="server" AutoGenerateColumns="false" ItemType="WebFormsLab.Model.Category" DataKeyNames="CategoryId" SelectMethod="GetCategories" AutoGenerateSelectButton="true" AutoGenerateEditButton="true" UpdateMethod="UpdateCategory">Atrybut DataKeyNames w elemencie GridView definiuje, które elementy członkowskie jednoznacznie identyfikują obiekt powiązany z modelem, a tym samym, jakie parametry powinna co najmniej otrzymać metoda aktualizacji.
Otwórz plik kodu zaplecza Products.aspx.cs i zaimplementuj metodę UpdateCategory. Metoda powinna otrzymać identyfikator kategorii, aby załadować bieżącą kategorię, wypełnić wartości z kontrolki GridView, a następnie zaktualizować kategorię.
(Fragment kodu — Laboratorium formularzy internetowych — Ex01 — UpdateCategory)
public void UpdateCategory(int categoryId) { var category = this.db.Categories.Find(categoryId); this.TryUpdateModel(category); if (this.ModelState.IsValid) { this.db.SaveChanges(); } }Nowa metoda TryUpdateModel w klasie Page jest odpowiedzialna za wypełnianie obiektu modelu przy użyciu wartości z kontrolek na stronie. W takim przypadku zastąpi zaktualizowane wartości z edytowanego bieżącego wiersza GridView w obiekcie kategorii.
Uwaga
W następnym ćwiczeniu wyjaśniono użycie elementu ModelState.IsValid w celu weryfikacji danych wprowadzonych przez użytkownika podczas edytowania obiektu.
Uruchom witrynę i przejdź do strony Produkty. Edytuj kategorię. Wpisz nową nazwę, a następnie kliknij przycisk Aktualizuj, aby utrwały zmiany.
Edytowanie kategorii
Ćwiczenie 2. Sprawdzanie poprawności danych
W tym ćwiczeniu poznasz nowe funkcje weryfikacji danych w ASP.NET 4.5. Sprawdzisz nowe nienachalne funkcje walidacji w formularzach sieciowych. Adnotacje danych będą używane w klasach modelu aplikacji na potrzeby weryfikacji danych wejściowych użytkownika, a na koniec dowiesz się, jak włączyć lub wyłączyć walidację żądań dla poszczególnych kontrolek na stronie.
Zadanie 1 . Nietrudna walidacja
Formularze ze złożonymi danymi, w tym modułami sprawdzania poprawności, zwykle generują zbyt duży kod JavaScript na stronie, który może reprezentować około 60% kodu. Po włączeniu walidacji bezinwazyjnej, kod HTML będzie wyglądał czystszy i bardziej przejrzysty.
W tej sekcji włączysz nietrudną walidację w ASP.NET, aby porównać kod HTML wygenerowany przez obie konfiguracje.
Otwórz program Visual Studio 2012 i otwórz rozwiązanie Begin znajdujące się w folderze Source\Ex2-Validation\Begin tego laboratorium. Alternatywnie możesz kontynuować pracę nad istniejącym rozwiązaniem z poprzedniego ćwiczenia.
Jeśli otwarto podane rozwiązanie Begin , przed kontynuowanie musisz pobrać brakujące pakiety NuGet. W tym celu w Eksploratorze rozwiązań kliknij projektu WebFormsLabZarządzaj pakietami NuGet.
W oknie dialogowym Zarządzanie pakietami NuGet kliknij pozycję Przywróć, aby pobrać brakujące pakiety.
Na koniec skompiluj rozwiązanie, klikając Kompiluj | Kompiluj Rozwiązanie.
Uwaga
Jedną z zalet korzystania z narzędzia NuGet jest to, że nie trzeba dostarczać wszystkich bibliotek w projekcie, zmniejszając rozmiar projektu. Za pomocą narzędzi NuGet Power Tools, określając wersje pakietów w pliku Packages.config, będzie można pobrać wszystkie wymagane biblioteki przy pierwszym uruchomieniu projektu. Dlatego po otwarciu istniejącego rozwiązania z tego laboratorium będziesz musiał wykonać te kroki.
Naciśnij F5 , aby uruchomić aplikację internetową. Przejdź do strony Klienci i kliknij link Dodaj nowego klienta .
Kliknij prawym przyciskiem myszy stronę przeglądarki i wybierz opcję Wyświetl źródło , aby otworzyć kod HTML wygenerowany przez aplikację.
Wyświetlanie kodu HTML strony
Przewiń kod źródłowy strony i zwróć uwagę, że ASP.NET wprowadził kod JavaScript i moduły sprawdzania poprawności danych na stronie, aby wykonać walidacje i wyświetlić listę błędów.
Walidacja kodu JavaScript na stronie CustomerDetails
Zamknij przeglądarkę i wróć do programu Visual Studio.
Teraz włączysz niezauważalną walidację. Otwórz plik Web.Config i znajdź klucz ValidationSettings:UnobtrusiveValidationMode w sekcji AppSettings. Ustaw wartość klucza na WebForms.
<configuration> ... <appSettings> <add key="aspnet:uselegacysynchronizationcontext" value="false" /> <add key="ValidationSettings:UnobtrusiveValidationMode" value="WebForms"/>Uwaga
Tę właściwość można również ustawić w zdarzeniu "Page_Load", jeśli chcesz włączyć nietrudną walidację tylko dla niektórych stron.
Otwórz CustomerDetails.aspx i naciśnij F5 , aby uruchomić aplikację internetową.
Naciśnij F12, aby otworzyć narzędzia deweloperskie IE. Po otwarciu narzędzi deweloperskich wybierz kartę skryptu. Wybierz CustomerDetails.aspx z menu i zwróć uwagę, że skrypty wymagane do uruchomienia zapytania jQuery na stronie zostały załadowane do przeglądarki z witryny lokalnej.
Ładowanie plików JavaScript w trybie jQuery bezpośrednio z lokalnego serwera usług IIS
Zamknij przeglądarkę, aby powrócić do programu Visual Studio. Otwórz ponownie plik Site.Master i znajdź ScriptManager. Dodaj atrybut EnableCdn z właściwością True. Spowoduje to wymusi załadowanie się biblioteki jQuery z adresu URL online, a nie z adresu URL witryny lokalnej.
Otwórz CustomerDetails.aspx w programie Visual Studio. Naciśnij F5, aby uruchomić witrynę. Po otwarciu programu Internet Explorer naciśnij F12, aby otworzyć narzędzia deweloperskie. Wybierz kartę Skrypt , a następnie przyjrzyj się liście rozwijanej. Zwróć uwagę, że pliki JavaScript w trybie jQuery nie są już ładowane z witryny lokalnej, ale raczej z online usługi jQuery CDN.
Ładowanie plików JavaScript jQuery z usługi CDN
Otwórz ponownie kod źródłowy strony HTML przy użyciu opcji Wyświetl źródło w przeglądarce. Zwróć uwagę, że włączenie nieinwazyjnej weryfikacji w ASP.NET zastąpiło wstrzyknięty kod JavaScript atrybutami data-*.
Niestrudny kod weryfikacji
Uwaga
W tym przykładzie pokazano, jak podsumowanie walidacji z adnotacjami danych zostało uproszczone tylko do kilku wierszy HTML i JavaScript. Wcześniej, bez niedostrzegalnej walidacji, im więcej kontrolek walidacji dodasz, tym większy będzie kod walidacji JavaScript.
Zadanie 2 . Weryfikowanie modelu przy użyciu adnotacji danych
ASP.NET 4.5 wprowadza walidację adnotacji danych dla formularzy sieci Web. Zamiast kontrolować walidację poszczególnych danych wejściowych, można teraz definiować ograniczenia w klasach modelu i używać ich we wszystkich aplikacjach internetowych. W tej sekcji dowiesz się, jak używać adnotacji danych do weryfikowania nowego/edytowania formularza klienta.
Otwórz stronę CustomerDetail.aspx . Zwróć uwagę, że imię i drugie imię klienta w sekcjach EditItemTemplate i InsertItemTemplate są weryfikowane przy użyciu kontrolek RequiredFieldValidator. Każdy moduł sprawdzania poprawności jest skojarzony z określonym warunkiem, dlatego należy uwzględnić dowolną liczbę modułów sprawdzania poprawności.
Dodaj adnotacje danych, aby zweryfikować klasę modelu Klienta. Otwórz klasę Customer.cs w folderze Model i dekoruj każdą właściwość przy użyciu atrybutów adnotacji danych.
(Fragment kodu — Laboratorium formularzy internetowych — Ex02 — Adnotacje danych)
namespace WebFormsLab.Model { using System.Collections.Generic; using System.ComponentModel.DataAnnotations; public class Customer { [Key] public int Id { get; set; } [Required] public string FirstName { get; set; } [Required] public string LastName { get; set; } [Range(0, 130)] public int Age { get; set; } public Address Address { get; set; } [Phone] public string DaytimePhone { get; set; } [EmailAddress, StringLength(256)] public string EmailAddress { get; set; } } }Uwaga
Program .NET Framework 4.5 rozszerzył istniejącą kolekcję adnotacji danych. Oto niektóre adnotacje danych, których można użyć: [CreditCard], [Phone], [EmailAddress], [Range], [Compare], [Url], [FileExtensions], [Required], [Key], [RegularExpression].
Przykłady użycia:
[Klucz]: określa, że atrybut jest unikatowym identyfikatorem
[Zakres(0.4, 0.5, ErrorMessage="{Napisz komunikat o błędzie}"]: Podwójny zakres
[EmailAddress(ErrorMessage="Invalid Email"), MaxLength(56)]: Dwie adnotacje w tym samym wierszu.
Możesz również zdefiniować własne komunikaty o błędach w ramach każdego atrybutu.
Otwórz CustomerDetails.aspx i usuń wszystkie walidatory RequiredFieldValidators dla pól imienia i nazwiska w sekcjach EditItemTemplate i InsertItemTemplate kontrolki FormView.
<EditItemTemplate> <fieldset> <p><asp:Label runat="server" AssociatedControlID="firstName">First Name: </asp:Label></p> <p><asp:TextBox runat="server" ID="firstName" Text='<%#: BindItem.FirstName %>' /> <asp:RequiredFieldValidator runat="server" ControlToValidate="firstName" ErrorMessage="Please enter a value for First Name" ForeColor="Red" /> </p> <p><asp:Label runat="server" AssociatedControlID="lastName">Last Name: </asp:Label></p> <p><asp:TextBox runat="server" ID="lastName" Text='<%#: BindItem.LastName %>' /> <asp:RequiredFieldValidator runat="server" ControlToValidate="lastName" ErrorMessage="Please enter a value for Last Name" ForeColor="Red" /> </p> ... <InsertItemTemplate> <fieldset> <p><asp:Label runat="server" AssociatedControlID="firstName">First Name: </asp:Label></p> <p><asp:TextBox runat="server" ID="firstName" Text='<%#: BindItem.FirstName %>' /> <asp:RequiredFieldValidator runat="server" ControlToValidate="firstName" ErrorMessage="Please enter a value for First Name" ForeColor="Red" /> </p> <p><asp:Label runat="server" AssociatedControlID="lastName">Last Name: </asp:Label></p> <p><asp:TextBox runat="server" ID="lastName" Text='<%#: BindItem.LastName %>' /> <asp:RequiredFieldValidator runat="server" ControlToValidate="lastName" ErrorMessage="Please enter a value for Last Name" ForeColor="Red" /> </p> ...Uwaga
Jedną z zalet używania adnotacji danych jest to, że logika walidacji nie jest duplikowana na stronach aplikacji. Definiujesz go raz w modelu i używasz go na wszystkich stronach aplikacji, które manipulują danymi.
Otwórz zaplecze kodu w CustomerDetails.aspx i znajdź metodę SaveCustomer. Ta metoda jest wywoływana podczas wstawiania nowego klienta i odbiera parametr Customer z wartości kontrolki FormView. Gdy zostanie wykonane mapowanie między kontrolkami strony a obiektem parametru, ASP.NET wykona walidację modelu względem wszystkich atrybutów adnotacji danych i wypełni słownik ModelState błędami, jeśli istnieją.
Parametr ModelState.IsValid zwróci wartość true tylko wtedy, gdy wszystkie pola w modelu są prawidłowe po przeprowadzeniu walidacji.
public void SaveCustomer(Customer customer) { if (this.ModelState.IsValid) { using (var db = new ProductsContext()) { ...Dodaj kontrolkę ValidationSummary na końcu strony CustomerDetails, aby wyświetlić listę błędów modelu.
</fieldset> </InsertItemTemplate> </asp:FormView> <asp:ValidationSummary runat="server" ShowModelStateErrors="true" ForeColor="Red" HeaderText="Please check the following errors:"/> </asp:Content>ShowModelStateErrors jest nową właściwością kontrolki ValidationSummary, która po ustawieniu na true, kontrolka wyświetli błędy ze słownika ModelState. Te błędy pochodzą z walidacji adnotacji danych.
Naciśnij F5 , aby uruchomić aplikację internetową. Wypełnij formularz kilkoma błędnymi wartościami i kliknij przycisk Zapisz , aby wykonać walidację. Zwróć uwagę na podsumowanie błędu u dołu.
Walidacja przy użyciu adnotacji danych
Zadanie 3 . Obsługa niestandardowych błędów bazy danych za pomocą elementu ModelState
W poprzedniej wersji formularzy internetowych obsługa błędów bazy danych, takich jak zbyt długi ciąg lub naruszenie unikatowego klucza, zazwyczaj obejmowała zgłaszanie wyjątków w kodzie repozytorium, a następnie ich obsługę w kodzie-behind, aby wyświetlić błąd. Wymagana jest duża ilość kodu, aby wykonać coś stosunkowo prostego.
W formularzach Web Forms 4.5 obiekt ModelState może służyć do wyświetlania błędów na stronie z modelu lub z bazy danych w spójny sposób.
W tym zadaniu dodasz kod, aby prawidłowo obsługiwać wyjątki bazy danych i wyświetlać użytkownikowi odpowiedni komunikat przy użyciu obiektu ModelState.
Gdy aplikacja jest nadal uruchomiona, spróbuj zaktualizować nazwę kategorii przy użyciu zduplikowanej wartości.
Aktualizowanie kategorii z zduplikowaną nazwą
Zwróć uwagę, że wyjątek jest zgłaszany z powodu ograniczenia "unikatowego" kolumny CategoryName.
Wyjątek dla zduplikowanych nazw kategorii
Zatrzymaj debugowanie. W pliku Products.aspx.cs zaktualizuj metodę UpdateCategory, aby obsłużyć wyjątki zgłaszane przez wywołanie metody db.SaveChanges() i dodać błąd do obiektu ModelState.
Nowa metoda TryUpdateModel aktualizuje obiekt kategorii pobrany z bazy danych przy użyciu danych formularza dostarczonych przez użytkownika.
(Fragment kodu — Lab Web Forms — Ex02 — UpdateCategory Obsługa błędów)
public void UpdateCategory(int categoryId) { var category = this.db.Categories.Find(categoryId); this.TryUpdateModel(category); if (this.ModelState.IsValid) { try { this.db.SaveChanges(); } catch (DbUpdateException) { var message = string.Format("A category with the name {0} already exists.", category.CategoryName); this.ModelState.AddModelError("CategoryName", message); } } }Uwaga
W idealnym przypadku należy zidentyfikować przyczynę elementu DbUpdateException i sprawdzić, czy główną przyczyną jest naruszenie ograniczenia unikatowego klucza.
Otwórz Products.aspx i dodaj kontrolkę ValidationSummary poniżej kategorii GridView, aby wyświetlić listę błędów modelu.
<asp:GridView ID="categoriesGrid" runat="server" ... </asp:GridView> <asp:ValidationSummary ID="ValidationSummary1" runat="server" ShowModelStateErrors="true" /> <h3>Products</h3>Uruchom witrynę i przejdź do strony Produkty. Spróbuj zaktualizować nazwę kategorii przy użyciu zduplikowanej wartości.
Zwróć uwagę, że wyjątek został obsłużony, a komunikat o błędzie pojawia się w kontrolce ValidationSummary .
Błąd zduplikowanej kategorii
Zadanie 4. Sprawdzanie poprawności żądania w programie ASP.NET Web Forms 4.5
Funkcja weryfikacji żądań w ASP.NET zapewnia określony poziom domyślnej ochrony przed atakami skryptowymi między witrynami (XSS). W poprzednich wersjach ASP.NET walidacja żądań została domyślnie włączona i może być wyłączona tylko dla całej strony. Dzięki nowej wersji ASP.NET web forms można teraz wyłączyć walidację żądania dla pojedynczej kontrolki, przeprowadzić walidację leniwych żądań lub uzyskać dostęp do danych niezwalidowanych żądań (należy zachować ostrożność, jeśli to zrobisz!).
Naciśnij Ctrl+F5 , aby uruchomić witrynę bez debugowania i przejdź do strony Produkty. Wybierz kategorię, a następnie kliknij link Edytuj w dowolnym z produktów.
Wpisz opis zawierający potencjalnie niebezpieczną zawartość, na przykład tagi HTML. Zwróć uwagę na wyjątek rzucany z powodu weryfikacji żądania.
Edytowanie produktu z potencjalnie niebezpieczną zawartością
Zgłoszony wyjątek z powodu weryfikacji żądania
Zamknij stronę i w programie Visual Studio naciśnij SHIFT+F5 , aby zatrzymać debugowanie.
Otwórz stronę ProductDetails.aspx i znajdź pole tekstowe Opis.
Dodaj nową właściwość ValidateRequestMode do kontrolki TextBox i ustaw jej wartość na Disabled.
Nowy atrybut ValidateRequestMode umożliwia szczegółowe wyłączenie walidacji żądania dla każdej kontrolki. Jest to użyteczne, gdy chcesz użyć danych wejściowych, które mogą odbierać kod HTML, ale chcesz zachować działające sprawdzanie poprawności dla reszty strony.
<p> <asp:TextBox runat="server" ID="Description" TextMode="MultiLine" Cols="60" Rows="8" Text='<%# BindItem.Description %>' ValidateRequestMode="Disabled" /> </p>Naciśnij F5 , aby uruchomić aplikację internetową. Otwórz ponownie stronę edytowania produktu i wypełnij opis produktu, w tym tagi HTML. Zwróć uwagę, że możesz teraz dodać zawartość HTML do opisu.
Sprawdzanie poprawności żądania wyłączone dla opisu produktu
Uwaga
W aplikacji produkcyjnej należy oczyścić kod HTML wprowadzony przez użytkownika, aby upewnić się, że wprowadzono tylko bezpieczne tagi HTML (na przykład, aby nie było tagów <script>). W tym celu możesz użyć biblioteki microsoft Web Protection.
Ponownie edytuj produkt. Wpisz kod HTML w polu Nazwa i kliknij przycisk Zapisz. Zwróć uwagę, że weryfikacja żądania jest wyłączona tylko dla pola Opis, a pozostałe pola są nadal weryfikowane pod kątem potencjalnie niebezpiecznej zawartości.
Sprawdzanie poprawności żądania włączone w pozostałych polach
ASP.NET Web Forms 4.5 zawiera nowy tryb weryfikacji żądania w celu przeprowadzenia weryfikacji żądania w sposób leniwy. Jeśli tryb weryfikacji żądania jest ustawiony na 4.5 i fragment kodu uzyskuje dostęp do Request.Form["key"], walidacja żądania ASP.NET 4.5 spowoduje wyzwolenie weryfikacji żądania tylko dla tego określonego elementu w kolekcji formularzy.
Ponadto ASP.NET 4.5 zawiera teraz podstawowe procedury kodowania z biblioteki Microsoft Anti-XSS Library w wersji 4.0. Procedury kodowania Anti-XSS są implementowane przez nowy typ AntiXssEncoder znaleziony w nowej przestrzeni nazw System.Web.Security.AntiXss. W przypadku parametru encoderType skonfigurowanego do używania AntiXssEncoder, całe kodowanie wyjściowe w ASP.NET automatycznie wykorzystuje nowe procedury kodowania.
Sprawdzanie poprawności żądania w ASP.NET 4.5 obsługuje również niezwalidowany dostęp do danych żądania. ASP.NET 4.5 dodaje nową właściwość kolekcji do obiektu HttpRequest o nazwie Unvalidated. Po przejściu do pliku HttpRequest.Unvalidated masz dostęp do wszystkich typowych elementów danych żądania, w tym formularzy, querystrings, plików cookie, adresów URL itd.
Request.Unvalidated obiekt
Uwaga
Użyj właściwości HttpRequest.Unvalidated z ostrożnością! Upewnij się, że dokładnie przeprowadzasz walidację niestandardową na surowych danych żądania, aby niebezpieczny tekst nie był przesyłany i zwracany do niczego niepodejrzewających użytkowników!
Ćwiczenie 3. Asynchroniczne przetwarzanie stron w ASP.NET Web Forms
W tym ćwiczeniu zapoznasz się z nowymi funkcjami asynchronicznego przetwarzania stron w ASP.NET Web Forms.
Zadanie 1. Aktualizowanie strony szczegółów produktu w celu wczytania i wyświetlenia obrazów
W tym zadaniu zaktualizujesz stronę szczegółów produktu, aby umożliwić użytkownikowi określenie adresu URL obrazu dla produktu i wyświetlenie go w widoku tylko do odczytu. Utworzysz lokalną kopię określonego obrazu, pobierając ją synchronicznie. W następnym zadaniu zaktualizujesz tę implementację, aby działała asynchronicznie.
Otwórz program Visual Studio 2012 i załaduj rozwiązanie Begin znajdujące się w folderze Source\Ex3-Async\Begin z tego laboratorium. Alternatywnie możesz kontynuować pracę nad istniejącym rozwiązaniem z poprzednich ćwiczeń.
Jeśli otwarto podane rozwiązanie Begin , przed kontynuowanie musisz pobrać brakujące pakiety NuGet. W tym celu w Eksplorator rozwiązań kliknij projekt WebFormsLab i wybierz pozycję Zarządzaj pakietami NuGet.
W oknie dialogowym Zarządzanie pakietami NuGet kliknij pozycję Przywróć, aby pobrać brakujące pakiety.
Na koniec skompiluj rozwiązanie, klikając Kompiluj | Kompiluj Rozwiązanie.
Uwaga
Jedną z zalet korzystania z narzędzia NuGet jest to, że nie trzeba dostarczać wszystkich bibliotek w projekcie, zmniejszając rozmiar projektu. Za pomocą narzędzi NuGet Power Tools, określając wersje pakietów w pliku Packages.config, będzie można pobrać wszystkie wymagane biblioteki przy pierwszym uruchomieniu projektu. Dlatego po otwarciu istniejącego rozwiązania z tego laboratorium będziesz musiał wykonać te kroki.
Otwórz źródło strony ProductDetails.aspx i dodaj pole w elemencie ItemTemplate kontrolki FormView, aby wyświetlić obraz produktu.
<ItemTemplate> <fieldset> <p><b><asp:Label ID="Label2" runat="server" AssociatedControlID="itemProductName">Name:</asp:Label></b></p> <p><asp:Label runat="server" ID="itemProductName" Text='<%#: Item.ProductName %>' /></p> <p><b><asp:Label ID="Label3" runat="server" AssociatedControlID="itemDescription">Description (HTML):</asp:Label></b></p> <p><asp:Label runat="server" ID="itemDescription" Text='<%# Item.Description %>' /></p> <p><b><asp:Label ID="Label4" runat="server" AssociatedControlID="itemUnitPrice">Price:</asp:Label></b></p> <p><asp:Label runat="server" ID="itemUnitPrice" Text='<%#: Item.UnitPrice %>' /></p> <p><b><asp:Label ID="Label5" runat="server" AssociatedControlID="itemUnitPrice">Image:</asp:Label></b></p> <p> <img src="<%# string.IsNullOrEmpty(Item.ImagePath) ? "/Images/noimage.jpg" : Item.ImagePath %>" alt="Image" /> </p> <br /> <p> <asp:Button ID="Button1" runat="server" CommandName="Edit" Text="Edit" /> <asp:HyperLink NavigateUrl="~/Products.aspx" Text="Back" runat="server" /> </p> </fieldset> </ItemTemplate>Dodaj pole, aby określić adres URL obrazu w elemencie EditTemplate FormView.
<fieldset> <p><asp:Label ID="Label2" runat="server" AssociatedControlID="ProductName">Name:</asp:Label></p> <p><asp:TextBox runat="server" ID="ProductName" Text='<%#: BindItem.ProductName %>' /></p> <p><asp:Label ID="Label3" runat="server" AssociatedControlID="Description">Description (HTML):</asp:Label></p> <p> <asp:TextBox runat="server" ID="Description" TextMode="MultiLine" Cols="60" Rows="8" Text='<%# BindItem.Description %>' ValidateRequestMode="Disabled" /> </p> <p><asp:Label ID="Label4" runat="server" AssociatedControlID="UnitPrice">Price:</asp:Label></p> <p><asp:TextBox runat="server" ID="UnitPrice" Text='<%#: BindItem.UnitPrice %>' /></p> <p><asp:Label ID="Label1" runat="server" AssociatedControlID="ImagePath">Image URL:</asp:Label></p> <p><asp:TextBox runat="server" ID="ImagePath" Text='<%#: BindItem.ImagePath %>' /></p> <br /> <p> <asp:Button runat="server" CommandName="Update" Text="Save" /> <asp:Button runat="server" CommandName="Cancel" Text="Cancel" CausesValidation="false" /> </p> </fieldset>Otwórz plik ProductDetails.aspx.cs za pomocą kodu i dodaj następujące dyrektywy przestrzeni nazw.
(Fragment kodu — Laboratorium Web Forms — Ex03 — Przestrzenie nazw)
using System.IO; using System.Net; using System.Web;Utwórz metodę UpdateProductImage do przechowywania obrazów zdalnych w folderze Obrazy lokalne i zaktualizuj jednostkę produktu przy użyciu nowej wartości lokalizacji obrazu.
(Fragment kodu — Laboratorium formularzy internetowych — Ex03 — UpdateProductImage)
private void UpdateProductImage(Product product) { string imageUrl = product.ImagePath; if (!string.IsNullOrEmpty(imageUrl) && !VirtualPathUtility.IsAbsolute(imageUrl)) { product.ImagePath = string.Format( "/Images/{0}{1}", product.ProductId, Path.GetExtension(imageUrl)); using (var wc = new WebClient()) { wc.DownloadFile(imageUrl, Server.MapPath(product.ImagePath)); } } }Zaktualizuj metodę UpdateProduct, aby wywołać metodę UpdateProductImage.
(Fragment kodu — Laboratorium formularzy internetowych — Ex03 — UpdateProductImage Call)
public void UpdateProduct(int productId) { var product = this.db.Products.Find(productId); this.TryUpdateModel(product); this.UpdateProductImage(product); if (this.ModelState.IsValid) { this.db.SaveChanges(); } }Uruchom aplikację i spróbuj przesłać obraz produktu.
Ustawianie obrazu dla produktu
Zadanie 2 . Dodawanie asynchronicznego przetwarzania do strony szczegółów produktu
W tym zadaniu zaktualizujesz stronę szczegółów produktu, aby działała asynchronicznie. Ulepszysz długotrwałe zadanie — proces pobierania obrazu — przy użyciu asynchronicznego przetwarzania stron w ASP.NET 4.5.
Metody asynchroniczne w aplikacjach internetowych mogą służyć do optymalizowania sposobu użycia pul wątków ASP.NET. W ASP.NET istnieje ograniczona liczba wątków w puli wątków do udziału w żądaniach, w związku z czym gdy wszystkie wątki są zajęte, ASP.NET zaczyna odrzucać nowe żądania, wysyła komunikaty o błędach aplikacji i sprawia, że witryna jest niedostępna.
Czasochłonne operacje w witrynie internetowej są doskonałymi kandydatami do programowania asynchronicznego, ponieważ zajmują przypisany wątek przez długi czas. Obejmuje to długotrwałe żądania, strony z wieloma różnymi elementami i stronami, które wymagają operacji offline, takich jak wykonywanie zapytań względem bazy danych lub uzyskiwanie dostępu do zewnętrznego serwera internetowego. Zaletą używania metod asynchronicznych jest to, że podczas przetwarzania strony wątek zostaje zwolniony i zwrócony do puli wątków, co pozwala na obsłużenie nowego żądania strony. Oznacza to, że strona rozpocznie przetwarzanie w jednym wątku z puli wątków i może zakończyć przetwarzanie w innym, po zakończeniu przetwarzania asynchronicznego.
Otwórz stronę ProductDetails.aspx. Dodaj atrybut Async w elemecie Page i ustaw go na wartość true. Ten atrybut informuje ASP.NET o zaimplementowaniu interfejsu IHttpAsyncHandler.
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="ProductDetails.aspx.cs" Inherits="WebFormsLab.ProductDetails" Async="true" %>Dodaj etykietę w dolnej części strony, aby wyświetlić szczegóły wątków uruchomionych na stronie.
<EmptyDataTemplate>Product not found</EmptyDataTemplate> </asp:FormView> <asp:Label ID="threadsMessageLabel" runat="server" /> </asp:Content>Otwórz ProductDetails.aspx.cs i dodaj następujące dyrektywy przestrzeni nazw.
(Fragment kodu — Laboratorium formularzy internetowych — Ex03 — Przestrzenie nazw 2)
using System.Web.UI; using System.Threading;Zmodyfikuj metodę UpdateProductImage, aby pobrać obraz za pomocą zadania asynchronicznego. Zastąpisz metodę WebClientDownloadFile metodą DownloadFileTaskAsync i dołączysz słowo kluczowe await.
(Fragment kodu — Laboratorium formularzy internetowych — Ex03 — UpdateProductImage Async)
private void UpdateProductImage(Product product) { string imageUrl = product.ImagePath; if (!string.IsNullOrEmpty(imageUrl) && !VirtualPathUtility.IsAbsolute(imageUrl)) { product.ImagePath = string.Format( "/Images/{0}{1}", product.ProductId, Path.GetExtension(imageUrl)); this.RegisterAsyncTask(new PageAsyncTask(async (t) => { using (var wc = new WebClient()) { await wc.DownloadFileTaskAsync(imageUrl, this.Server.MapPath(product.ImagePath)); } })); } }RegisterAsyncTask rejestruje nowe zadanie asynchroniczne strony do wykonania w innym wątku. Otrzymuje wyrażenie lambda z zadaniem (t) do wykonania. Słowo kluczowe await w metodzie DownloadFileTaskAsync konwertuje pozostałą część metody na wywołanie zwrotne wywoływane asynchronicznie po zakończeniu metody DownloadFileTaskAsync . ASP.NET wznowi wykonywanie metody przez automatyczne utrzymywanie wszystkich oryginalnych wartości żądania HTTP. Nowy model programowania asynchronicznego na platformie .NET 4.5 umożliwia pisanie kodu asynchronicznego, który wygląda bardzo podobnie do kodu synchronicznego, i umożliwia kompilatorowi obsługę komplikacji funkcji wywołania zwrotnego lub kodu kontynuacji.
Uwaga
RegisterAsyncTask i PageAsyncTask były już dostępne od wersji .NET 2.0. Słowo kluczowe await jest nowe z modelu programowania asynchronicznego platformy .NET 4.5 i może być używane razem z nowymi metodami TaskAsync z obiektu .NET WebClient.
Dodaj kod, aby wyświetlić wątki, na których kod został rozpoczęty i zakończony. W tym celu zaktualizuj metodę UpdateProductImage przy użyciu następującego kodu.
(Fragment kodu — Laboratorium formularzy internetowych — Ex03 — Pokaż wątki)
private void UpdateProductImage(Product product) { string imageUrl = product.ImagePath; if (!string.IsNullOrEmpty(imageUrl) && !VirtualPathUtility.IsAbsolute(imageUrl)) { product.ImagePath = string.Format( "/Images/{0}{1}", product.ProductId, Path.GetExtension(imageUrl)); this.RegisterAsyncTask(new PageAsyncTask(async (t) => { var startThread = Thread.CurrentThread.ManagedThreadId; using (var wc = new WebClient()) { await wc.DownloadFileTaskAsync(imageUrl, this.Server.MapPath(product.ImagePath)); } var endThread = Thread.CurrentThread.ManagedThreadId; this.threadsMessageLabel.Text = string.Format("Started on thread: {0}<br /> Finished on thread: {1}", startThread, endThread); })); } }Otwórz plik Web.config witryny sieci Web. Dodaj następującą zmienną appSetting.
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>Naciśnij F5, aby uruchomić aplikację i załadować obraz za produkt. Zwróć uwagę na identyfikator wątków, w których kod został uruchomiony i zakończony, może być inny. Dzieje się tak, ponieważ zadania asynchroniczne są uruchamiane w osobnym wątku od puli wątków ASP.NET. Po zakończeniu zadania ASP.NET umieszcza zadanie z powrotem w kolejce i przypisuje dowolny z dostępnych wątków.
Asynchroniczne pobieranie obrazu
Uwaga
Ponadto tę aplikację można wdrożyć na platformie Azure w następującym dodatku B: Publikowanie aplikacji ASP.NET MVC 4 przy użyciu narzędzia Web Deploy.
Podsumowanie
W tym praktycznym laboratorium zostały omówione i pokazano następujące koncepcje:
- Używanie silnie typowanych wyrażeń powiązania danych
- Korzystanie z nowych funkcji powiązania modelu w formularzach sieci Web
- Używanie dostawców wartości do mapowania danych strony na metody code-behind
- Używanie adnotacji danych do sprawdzania poprawności danych wejściowych użytkownika
- Korzystanie z nieinwazyjnej weryfikacji po stronie klienta za pomocą jQuery w formularzach internetowych
- Implementowanie szczegółowej weryfikacji żądań
- Implementowanie asynchronicznego przetwarzania stron w formularzach internetowych
Dodatek A: Instalowanie programu Visual Studio Express 2012 dla sieci Web
Program Microsoft Visual Studio Express 2012 dla sieci Web lub innej wersji "Express" można zainstalować przy użyciu Instalator platformy Microsoft Web. Poniższe instrukcje zawierają instrukcje wymagane do zainstalowania programu Visual Studio Express 2012 for Web przy użyciu Instalator platformy Microsoft Web.
Przejdź do strony [/iis/extensions/introduction-to-iis-express/iis-express-overview?linkid=9810169](/iis/extensions/introduction-to-iis-express/iis-express-overview?linkid=9810169). Alternatywnie, jeśli masz już zainstalowany Instalator platformy internetowej, możesz go otworzyć i wyszukać produkt "Visual Studio Express 2012 for Web with Azure SDK" (Program Visual Studio Express 2012 for Web with Azure SDK).
Kliknij pozycję Zainstaluj teraz. Jeśli nie masz Instalatora platformy internetowej, nastąpi przekierowanie do pobrania i zainstalowania go najpierw.
Po otwarciu Instalatora platformy internetowej kliknij przycisk Zainstaluj , aby rozpocząć instalację.
Instalowanie programu Visual Studio Express
Przeczytaj wszystkie licencje i postanowienia dotyczące produktów, a następnie kliknij pozycję Akceptuję , aby kontynuować.
Akceptowanie postanowień licencyjnych
Poczekaj na zakończenie procesu pobierania i instalacji.
Postęp instalacji
Po zakończeniu instalacji kliknij przycisk Zakończ.
Ukończono instalację
Kliknij przycisk Zakończ, aby zamknąć Instalatora platformy internetowej.
Aby otworzyć program Visual Studio Express for Web, przejdź do ekranu Start i zacznij pisać "VS Express", a następnie kliknij kafelek VS Express for Web.
Kafelek programu VS Express dla sieci Web
Dodatek B: publikowanie aplikacji MVC 4 ASP.NET przy użyciu narzędzia Web Deploy
W tym dodatku pokazano, jak utworzyć nową witrynę internetową w witrynie Azure Portal i opublikować aplikację uzyskaną w ramach laboratorium, korzystając z funkcji publikowania Web Deploy udostępnionej przez platformę Azure.
Zadanie 1 . Tworzenie nowej witryny sieci Web w witrynie Azure Portal
Przejdź do portalu zarządzania Platformy Azure i zaloguj się przy użyciu poświadczeń firmy Microsoft skojarzonych z subskrypcją.
Uwaga
Platforma Azure umożliwia hostowanie 10 ASP.NET witryn internetowych bezpłatnie, a następnie skalowanie w miarę wzrostu ruchu. Możesz zarejestrować się tutaj.
Zaloguj się do portalu
Kliknij pozycję Nowy na pasku poleceń.
Tworzenie nowej witryny sieci Web
Kliknij Compute | Web Site. Następnie wybierz opcję Szybkie tworzenie . Podaj dostępny adres URL nowej witryny sieci Web i kliknij pozycję Utwórz witrynę sieci Web.
Uwaga
Platforma Azure jest hostem aplikacji internetowej działającej w chmurze, którą można kontrolować i zarządzać. Opcja Szybkie tworzenie umożliwia wdrożenie ukończonej aplikacji internetowej na platformie Azure spoza portalu. Nie obejmuje on kroków konfigurowania bazy danych.
Tworzenie nowej witryny sieci Web przy użyciu szybkiego tworzenia
Poczekaj na utworzenie nowej witryny sieci Web.
Po utworzeniu witryny sieci Web kliknij link w kolumnie ADRES URL . Sprawdź, czy nowa witryna sieci Web działa.
Przechodzenie do nowej witryny sieci Web
Uruchomiona witryna sieci Web
Wróć do portalu i kliknij nazwę witryny sieci Web w kolumnie Nazwa , aby wyświetlić strony zarządzania.
Otwieranie stron zarządzania witrynami sieci Web
Na stronie Pulpit nawigacyjny w sekcji szybkości spojrzenia kliknij link Pobierz profil publikacji.
Uwaga
Profil publikowania zawiera wszystkie informacje wymagane do opublikowania aplikacji internetowej na platformie Azure dla każdej włączonej metody publikacji. Profil publikowania zawiera adresy URL, poświadczenia użytkownika i ciągi bazy danych wymagane do nawiązania połączenia i uwierzytelnienia względem każdego z punktów końcowych, dla których włączono metodę publikacji. Microsoft WebMatrix 2, Microsoft Visual Studio Express for Web i Microsoft Visual Studio 2012 obsługują odczytywanie profilów publikowania w celu zautomatyzowania konfiguracji tych programów do publikowania aplikacji internetowych na platformie Azure.
Pobieranie profilu publikowania witryny sieci Web
Pobierz plik profilu publikowania do znanej lokalizacji. W tym ćwiczeniu zobaczysz, jak używać tego pliku do publikowania aplikacji internetowej na platformie Azure z poziomu programu Visual Studio.
Zapisywanie pliku profilu publikowania
Zadanie 2 — Konfigurowanie serwera bazy danych
Jeśli aplikacja korzysta z baz danych programu SQL Server, musisz utworzyć serwer usługi SQL Database. Jeśli chcesz wdrożyć prostą aplikację, która nie korzysta z programu SQL Server, możesz pominąć to zadanie.
Do przechowywania bazy danych aplikacji potrzebny będzie serwer usługi SQL Database. Serwery SQL Database można wyświetlić z subskrypcji w portalu zarządzania Azure w sekcji SQL Database | Serwery | Na Pulpicie serwera. Jeśli nie masz utworzonego serwera, możesz go utworzyć przy użyciu przycisku Dodaj na pasku poleceń. Zanotuj nazwę serwera i adres URL, nazwę logowania administratora i hasło, ponieważ będą one używane w następnych zadaniach. Nie twórz jeszcze bazy danych, ponieważ zostanie ona utworzona w późniejszym etapie.
Pulpit nawigacyjny serwera usługi SQL Database
W następnym zadaniu przetestujesz połączenie z bazą danych z programu Visual Studio, dlatego musisz uwzględnić lokalny adres IP na liście dozwolonych adresów IP serwera. W tym celu kliknij Konfiguruj, wybierz adres IP z Bieżący adres IP klienta i wklej go w polu tekstowym Początkowy adres IP oraz Końcowy adres IP, a następnie kliknij przycisk
.
Dodawanie adresu IP klienta
Po dodaniu adresu IP klienta do listy dozwolonych adresów IP kliknij pozycję Zapisz, aby potwierdzić zmiany.
Potwierdzanie zmian
Zadanie 3 . Publikowanie aplikacji MVC 4 ASP.NET przy użyciu narzędzia Web Deploy
Wróć do rozwiązania ASP.NET MVC 4. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt witryny internetowej i wybierz polecenie Publikuj.
Publikowanie witryny sieci Web
Zaimportuj profil publikowania zapisany w pierwszym zadaniu.
Importowanie profilu publikowania
Kliknij pozycję Zweryfikuj połączenie. Po zakończeniu walidacji kliknij przycisk Dalej.
Uwaga
Walidacja zostanie ukończona po wyświetleniu zielonego znacznika wyboru obok przycisku Zweryfikuj połączenie.
Weryfikowanie połączenia
Na stronie Ustawienia w sekcji Bazy danych kliknij przycisk obok pola tekstowego połączenia bazy danych (tj. DefaultConnection).
Konfiguracja narzędzia Web Deploy
Skonfiguruj połączenie z bazą danych w następujący sposób:
W polu Nazwa serwera wpisz adres URL serwera usługi SQL Database przy użyciu prefiksu tcp: .
W polu Nazwa użytkownika wpisz nazwę logowania administratora serwera.
W polu Hasło wpisz hasło logowania administratora serwera.
Wpisz nową nazwę bazy danych.
Konfigurowanie parametry połączenia docelowej
Następnie kliknij przycisk OK. Po wyświetleniu monitu o utworzenie bazy danych kliknij przycisk Tak.
Tworzenie bazy danych
Ciąg połączenia, którego użyjesz do nawiązania połączenia z usługą SQL Database na platformie Azure, jest wyświetlany w polu tekstowym "Domyślne połączenie". Następnie kliknij Dalej.
Parametry połączenia wskazujące usługę SQL Database
Na stronie Wersja zapoznawcza kliknij pozycję Publikuj.
Publikowanie aplikacji internetowej
Po zakończeniu procesu publikowania domyślna przeglądarka otworzy opublikowaną witrynę internetową.
Dodatek C: Używanie fragmentów kodu
W przypadku fragmentów kodu masz cały potrzebny kod na wyciągnięcie ręki. Dokument laboratorium zawiera informacje o tym, kiedy można ich używać, jak pokazano na poniższej ilustracji.
Wstawianie kodu do projektu przy użyciu fragmentów kodu programu Visual Studio Code
Aby dodać fragment kodu przy użyciu klawiatury (tylko w języku C#)
- Umieść kursor, w którym chcesz wstawić kod.
- Zacznij wpisywać nazwę fragmentu kodu (bez spacji lub łączników).
- Zobacz, jak funkcja IntelliSense wyświetla pasujące nazwy fragmentów kodu.
- Wybierz poprawny fragment kodu (lub kontynuuj wpisywanie do momentu wybrania nazwy całego fragmentu kodu).
- Naciśnij dwukrotnie Tab, aby wstawić fragment kodu w lokalizacji kursora.
Zacznij wpisywać nazwę fragmentu kodu
Naciśnij Tab, aby wybrać wyróżniony fragment kodu
Ponownie naciśnij Tab, a fragment zostanie rozszerzony
Aby dodać fragment kodu przy użyciu myszy (C#, Visual Basic i XML) 1. Kliknij prawym przyciskiem myszy miejsce, w którym chcesz wstawić fragment kodu.
- Wybierz pozycję Wstaw fragment kodu , a następnie pozycję Moje fragmenty kodu.
- Wybierz odpowiedni fragment kodu z listy, klikając go.
Kliknij prawym przyciskiem myszy miejsce, w którym chcesz wstawić fragment kodu, a następnie wybierz polecenie Wstaw fragment kodu
Wybierz odpowiedni fragment kodu z listy, klikając go