Co nowego we wzorcu Web Forms na platformie ASP.NET 4.5
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 użycie silnie typizowanej zmiennej w celu uzyskania pełnych korzyści środowiska programistycznego programu Visual Studio, takich jak IntelliSense, nawigacja składowa i sprawdzanie czasu 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 dodawać adnotacje do klas modelu za pomocą atrybutów weryfikacji z przestrzeni nazw System.ComponentModel.DataAnnotations i żądać, aby wszystkie witryny walidować dane wejściowe użytkownika przy użyciu 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 typiowanych 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 za pomocą kodu
- Używanie adnotacji danych do sprawdzania poprawności danych wejściowych użytkownika
- Korzystanie z nieprawdziwej weryfikacji po stronie klienta za pomocą zapytania 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 powią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 pozycję Kompiluj rozwiązanie kompilacji | .
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 trzeba będzie uruchomić 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 w przypadku używania powiązania danych do emitowania wartości elementu członkowskiego w obiekcie, do którego jest powiązanie danych, należy użyć wyrażenia powiązania danych wraz z wywołaniem metody Eval, przekazując nazwę elementu członkowskiego jako ciąg.
W czasie wykonywania te wywołania usługi Eval będą używać odbicia względem aktualnie powiązanego obiektu w celu odczytania wartości elementu członkowskiego o podanej nazwie i wyświetlenia wyniku w kodzie HTML. Takie podejście sprawia, że bardzo łatwo powiązać dane z dowolnymi, nieszkształconymi danymi.
Niestety, utracisz wiele doskonałych funkcji środowiska w czasie programowania w programie Visual Studio, w tym funkcję IntelliSense dla nazw członków, obsługę nawigacji (np. Przejdź do definicji) i sprawdzanie czasu 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 elementu EntityFramework razem z aplikacją CodeFirst, aby utworzyć bazę danych i uzyskać do jej dostępu. W poniższym kodzie klientRepeater 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ć powtarzanie w działaniu. 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 z repeaterem
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 typiowanych 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>
Jednym z powyższych podejść jest to, że wywołania do Eval() i Bind() są opóźnione — co oznacza przekazywanie ciągów reprezentujących 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
Element członkowski elementu działa w przypadku powiązania jednokierunkowego. Jeśli chcesz wykonać powiązanie dwukierunkowe, użyj elementu członkowskiego 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 powiązania modelu w formularzach sieci Web
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 w celu wywołania logiki z pliku za pomocą kodu 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 Products.aspx.cs za pomocą kodu i dodaj następujące instrukcje 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 nieprzetworzonego obiektu 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 obiektów, wymagane do 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 przy użyciu powiązania modelu
Naciśnij SHIFT+F5 Zatrzymaj debugowanie.
Zadanie 3 — Dostawcy wartości w powią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óć do strony Products.aspx .
W górnej części kontrolki GridView dodaj etykietę i pole ComboBox, aby wybrać liczbę produktów dla każdej kategorii, jak pokazano 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 Products.aspx.cs za pomocą kodu i dodaj następującą instrukcję using.
using System.Web.ModelBinding;
Zmodyfikuj metodę GetCategories, aby otrzymać argument minProductsCount liczby całkowitej 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 drugą kontrolkę GridView o nazwie productsGrid u dołu. Ustaw wartość ItemType na WebFormsLab.Model.Product, wartości DataKeyNames na ProductId i SelectMethod na GetProducts. Ustaw kolumny 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 Products.aspx.cs za pomocą kodu. 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 — Laboratorium web forms — Ex01 — SelectProduct, metoda)
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 w produkcie, 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 elementy GridView definiuje, które są elementami członkowskimi, które jednoznacznie identyfikują obiekt powiązany z modelem, a zatem które są parametrami, które metoda aktualizacji powinna otrzymać co najmniej.
Otwórz plik Products.aspx.cs za pomocą kodu 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 bieżącego wiersza GridView edytowanego 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. Wyewidencjonujesz nowe nieprawdziwe funkcje walidacji w formularzach internetowych. 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 nieprawdziwej 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 Eksplorator rozwiązań kliknij projekt WebFormsLab 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 pozycję Kompiluj rozwiązanie kompilacji | .
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 trzeba będzie uruchomić 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 nietrudną walidację. Otwórz plik Web.Config i znajdź pozycję ValidationSettings:UnobtrusiveValidationMode klucza 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ź skryptManager. Dodaj właściwość EnableCdn atrybutu z wartością True. Spowoduje to wymusi załadowanie zapytania 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 niestrudyjnej weryfikacji ASP.NET zastąpiło wstrzyknięty kod JavaScript danymi — *atrybuty.
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 niestrudyjnej weryfikacji, tym więcej kontrolek walidacji dodawany, tym większy będzie wzrost kodu sprawdzania poprawności języka 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 pola RequiredFieldValidators dla pól pierwszego 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 CustomerDetails.aspx kod-behind 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 wartości true kontrolka będzie wyświetlać 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 unikatowe naruszenie klucza, może obejmować zgłaszanie wyjątków w kodzie repozytorium, a następnie obsługę wyjątków w kodzie w celu wyświetlenia błędu. 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 za pomocą kodu zaktualizuj metodę UpdateCategory, aby obsłużyć wyjątki zgłaszane przez bazę danych. Wywołanie metody SaveChanges() i dodanie błędu do obiektu ModelState.
Nowa metoda TryUpdateModel aktualizuje obiekt kategorii pobrany z bazy danych przy użyciu danych formularza dostarczonych przez użytkownika.
(Fragment kodu — Laboratorium web forms — Ex02 — UpdateCategory Handle Errors (Błędy obsługi updateCategory)
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 zgłoszony wyjątek 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 przydatne, gdy chcesz użyć danych wejściowych, które mogą odbierać kod HTML, ale chcesz zachować sprawdzanie poprawności w pozostałej części 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 odczytać kod HTML wprowadzony przez użytkownika, aby upewnić się, że wprowadzono tylko bezpieczne tagi HTML (na przykład nie <ma tagów skryptów> ). 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 w trybie weryfikacji żądania ustawiono wartość 4.5, jeśli fragment kodu uzyskuje dostęp do elementu 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 wszystkie kodowanie wyjściowe w ASP.NET automatycznie używa nowych procedur kodowania.
sprawdzanie poprawności żądania ASP.NET 4.5 obsługuje również niewalidowany dostęp do żądań danych. 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 nieprzetworzonych danych żądania, aby upewnić się, że niebezpieczny tekst nie jest zaokrąglony i renderowany z powrotem do niczego nie podejrzewających klientó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 przekazania 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 pozycję Kompiluj rozwiązanie kompilacji | .
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 trzeba będzie uruchomić 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 elemecie EditTemplate kontrolki 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 formularzy internetowych — 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 przekazać obraz dla 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. Rozszerzysz długotrwałe zadanie — proces pobierania obrazu — przy użyciu ASP.NET 4,5 asynchronicznego przetwarzania stron.
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ą jest to, że jeśli używasz metod asynchronicznych dla tych operacji, podczas przetwarzania strony, wątek jest zwalniany i zwracany do puli wątków i może służyć do udziału w nowym żądaniu 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ę WebClient DownloadFile 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 rozpoczęto kod i zakończył wykonywanie. 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 przekazać obraz dla produktu. 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 typiowanych 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 za pomocą kodu
- Używanie adnotacji danych do sprawdzania poprawności danych wejściowych użytkownika
- Korzystanie z nieprawdziwej weryfikacji po stronie klienta za pomocą zapytania 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 dla Sieci Web, przejdź do ekranu startowego 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 pozycję Compute Web Site (Obliczanie | witryny sieci Web). 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 Szybki przegląd kliknij link Pobierz profil publikowania.
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 usługi SQL Database można wyświetlić z subskrypcji w portalu zarządzania Azure na pulpicie nawigacyjnym serwera sql Database | Server | . 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 przycisk Konfiguruj, wybierz adres IP z bieżącego adresu IP klienta i wklej go w polach tekstowych Początkowy adres IP i 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
Parametry połączenia, którego użyjesz do nawiązania połączenia z usługą SQL Database na platformie Azure, jest wyświetlana 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 kodu zostanie rozwiń
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