Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Новая версия ASP.NET веб-формы представляет ряд улучшений, ориентированных на улучшение взаимодействия с пользователями при работе с данными.
В предыдущих версиях веб-формы при использовании привязки данных для выдачи значения члена объекта вы использовали выражения привязки данных Bind() или Eval(). В новой версии ASP.NET вы можете объявить тип данных, к которым будет привязан элемент управления с помощью нового свойства ItemType. Задание этого свойства позволит вам использовать строго типизированную переменную, чтобы полноценно воспользоваться всеми преимуществами среды разработки Visual Studio, такими как IntelliSense, навигация по элементам и проверка во время компиляции.
Теперь с помощью элементов управления с привязкой к данным можно также указать собственные пользовательские методы для выбора, обновления, удаления и вставки данных, упрощая взаимодействие между элементами управления страницы и логикой приложения. Кроме того, возможности привязки модели были добавлены в ASP.NET, что означает, что данные с страницы можно сопоставить непосредственно с параметрами типа метода.
Проверка входных данных пользователей также должна быть проще с последней версией веб-формы. Теперь можно аннотировать классы моделей проверочными атрибутами из пространства имен System.ComponentModel.DataAnnotations и запросить, чтобы все элементы управления сайта проверяли пользовательские входные данные с использованием этой информации. Проверка на стороне клиента в веб-формы теперь интегрирована с jQuery, обеспечивая более чистый клиентский код и ненавязчивые функции JavaScript.
В области проверки запросов были внесены улучшения, чтобы упростить отключение проверки запросов в отдельных частях приложений или доступ к данным недопущенных запросов.
Некоторые улучшения были сделаны для серверных элементов управления Web Forms, чтобы воспользоваться новыми функциями HTML5.
- Свойство TextMode элемента управления TextBox обновлено для поддержки новых типов входных данных HTML5, таких как электронная почта, дата и т. д.
- Теперь элемент управления FileUpload поддерживает несколько отправки файлов из браузеров, поддерживающих эту функцию HTML5.
- Теперь элементы управления validator поддерживают проверку входных элементов HTML5.
- Новые элементы HTML5, имеющие атрибуты, представляющие URL-адрес, теперь поддерживают runat="server". В результате вы можете использовать соглашения ASP.NET в URL-путях, например оператор ~, чтобы представить корневую папку приложения (например, <video runat="server" src="~/myVideo.wmv"></video>).
- Элемент управления UpdatePanel был исправлен для поддержки размещения полей ввода HTML5.
На официальном портале ASP.NET вы можете найти дополнительные примеры новых функций в ASP.NET WebForms 4.5: новые возможности ASP.NET 4.5 и Visual Studio 2012
Все примеры кода и фрагменты кода включены в комплект для обучения Web Camps.
Задачи
В этой практической лаборатории вы узнаете, как:
- Использование строго типизированных выражений привязки данных
- Использование новых функций привязки модели в веб-формы
- Использование поставщиков значений для сопоставления данных страницы с методами программной части
- Использование заметок данных для проверки ввода пользователем
- Воспользуйтесь незаметной проверкой на стороне клиента с помощью jQuery в веб-формах
- Реализация детализации проверки запроса
- Реализация асинхронной обработки страниц для веб-форм
Требования
Для выполнения этой лабораторной работы необходимо иметь следующие элементы:
- Microsoft Visual Studio Express 2012 для Интернета или более поздней версии (см . приложение A для инструкций по его установке).
Настройка
Установка фрагментов кода
Для удобства большая часть кода, который вы будете управлять вместе с этой лабораторией, доступна как фрагменты кода Visual Studio. Чтобы установить фрагменты кода, выполните файл .\Source\Setup\CodeSnippets.vsi .
Если вы не знакомы с фрагментами кода Visual Studio Code и хотите узнать, как их использовать, вы можете обратиться к приложению из этого документа "Приложение C: использование фрагментов кода".
Упражнения
Эта практическая лаборатория включает в себя следующие упражнения:
- Упражнение 1: Привязка модели в ASP.NET Web Forms
- Упражнение 2. Проверка данных
- Упражнение 3. Асинхронная обработка страниц в ASP.NET веб-формы
Примечание.
Каждое упражнение сопровождается папкой End , содержащей полученное решение, которое необходимо получить после выполнения упражнений. Это решение можно использовать в качестве руководства, если вам нужна дополнительная помощь в работе с упражнениями.
Предполагаемое время выполнения этой практической работы: 60 минут.
Упражнение 1: Привязка модели в веб-формах ASP.NET
Новая версия ASP.NET веб-формы представляет ряд улучшений, ориентированных на улучшение работы с данными. В этом упражнении вы узнаете о строго типизированных элементах управления данными и привязке модели.
Задача 1. Использование строго типизированных привязок данных
В этой задаче вы обнаружите новые строго типизированные привязки, доступные в ASP.NET 4.5.
Откройте решение Begin, расположенное в папке Source/Ex1-ModelBinding/Begin/.
Прежде чем продолжить, необходимо скачать некоторые отсутствующие пакеты NuGet. Для этого щелкните меню "Проект" и выберите "Управление пакетами NuGet".
В диалоговом окне "Управление пакетами NuGet" нажмите кнопку "Восстановить", чтобы скачать отсутствующие пакеты.
Наконец, создайте решение, нажав Сборка | Сборка решения.
Примечание.
Одним из преимуществ использования NuGet является то, что вам не нужно отправлять все библиотеки в проекте, уменьшая размер проекта. С помощью NuGet Power Tools, указав версии пакетов в файле Packages.config, вы сможете скачать все необходимые библиотеки при первом запуске проекта. Поэтому после открытия существующего решения в этой лаборатории необходимо выполнить эти действия.
Откройте страницу Customers.aspx . Поместите ненумерованный список в основной элемент управления и включите элемент управления повторителя внутри для перечисления каждого клиента. Задайте имя повторителя customersRepeater , как показано в следующем коде.
В предыдущих версиях веб-формы при использовании привязки данных для выдачи значения элемента в объекте, к которым выполняется привязка данных, вы будете использовать выражение привязки данных вместе с вызовом метода Eval, передавая имя члена в виде строки.
Во время выполнения эти вызовы Eval будут использовать механизм отражения для текущего связанного объекта, чтобы прочитать значение элемента с указанным именем и вывести результат в HTML. Такой подход упрощает привязку данных к произвольным, несформанным данным.
К сожалению, вы потеряете многие из отличных функций во время разработки в Visual Studio, включая IntelliSense для имен членов, поддержку навигации (например, переход к определению) и проверку времени компиляции.
... <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>Откройте файл Customers.aspx.cs.
Добавьте следующую инструкцию using.
using System.Linq;В методе Page_Load добавьте код для заполнения повторителя списком клиентов.
(Фрагмент кода — лаборатория веб-форм — Ex01 — привязка источника данных клиентов)
protected void Page_Load(object sender, EventArgs e) { using (var db = new WebFormsLab.Model.ProductsContext()) { this.customersRepeater.DataSource = db.Customers.ToList(); this.customersRepeater.DataBind(); } }Решение использует EntityFramework вместе с CodeFirst для создания и доступа к базе данных. В следующем коде customersRepeater привязан к материализованному запросу, возвращающему всех клиентов из базы данных.
Нажмите клавишу F5 , чтобы запустить решение и перейдите на страницу "Клиенты" , чтобы увидеть повторитель в действии. Так как решение использует CodeFirst, база данных будет создана и заполнена в локальном экземпляре SQL Express при запуске приложения.
Перечисление клиентов с повтором
Примечание.
В Visual Studio 2012 IIS Express является сервером веб-разработки по умолчанию.
Закройте браузер и вернитесь в Visual Studio.
Теперь замените реализацию для использования строго типизированных привязок. Откройте страницу Customers.aspx и используйте новый атрибут ItemType в повторитее, чтобы задать тип клиента в качестве типа привязки.
<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>Свойство ItemType позволяет объявлять тип данных, к которым будет привязан элемент управления, и позволяет использовать строго типизированную привязку внутри элемента управления с привязкой к данным.
Замените содержимое ItemTemplate следующим кодом.
<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>Одним из недостатков с приведенными выше подходами является то, что вызовы Eval() и Bind() являются поздними привязками. Это означает, что строки передаются для представления имен свойств. Это означает, что вы не получаете Intellisense для имен членов, поддержку навигации по коду (например, переход к определению), а также поддержку проверки во время компиляции.
Установка свойства ItemType приводит к созданию двух новых типизированных переменных в области выражений привязки данных: Item и BindItem. Эти строго типизированные переменные можно использовать в выражениях привязки данных и получить все преимущества разработки Visual Studio.
Символ ": ", используемый в выражении, автоматически кодирует в HTML выходные данные, чтобы избежать проблем безопасности (например, атак на межсайтовые сценарии). Эта нотация была доступна с .NET 4 для записи ответов, но теперь также доступна в выражениях привязки данных.
Примечание.
Элемент Item работает для односторонняя привязка. Если вы хотите выполнить двусторонняя привязка, используйте элемент BindItem .
Поддержка IntelliSense в строго типизированной привязке
Нажмите клавишу F5 , чтобы запустить решение и перейдите на страницу "Клиенты", чтобы убедиться, что изменения работают должным образом.
Перечисление сведений о клиенте
Закройте браузер и вернитесь в Visual Studio.
Задача 2. Введение привязки модели в веб-формы
В предыдущих версиях ASP.NET веб-формы, когда вы хотите выполнить двустороннюю привязку данных, извлечение и обновление данных, необходимо использовать объект Источника данных. Это может быть источник данных объекта, источник данных SQL, источник данных LINQ и т. д. Однако если в вашем сценарии требуется пользовательский код для обработки данных, необходимо использовать источник данных объекта, и это привело к некоторым недостаткам. Например, необходимо избежать сложных типов и обрабатывать исключения при выполнении логики проверки.
В новой версии ASP.NET веб-формы элементы управления с привязкой к данным поддерживают привязку модели. Это означает, что можно указать методы выбора, обновления, вставки и удаления непосредственно в элементе управления, привязанном к данным, для вызова логики из файла кода или из другого класса.
Чтобы узнать об этом, вы будете использовать GridView для перечисления категорий продуктов с помощью нового атрибута SelectMethod . Этот атрибут позволяет указать метод получения данных GridView.
Откройте страницу Products.aspx и включите GridView. Настройте GridView, как показано ниже, чтобы использовать строго типизированные привязки и включить сортировку и разбиение по страницам.
<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>Используйте новый атрибут SelectMethod , чтобы настроить GridView для вызова метода GetCategories для выбора данных.
<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>Откройте файл кода в файле Products.aspx.cs и добавьте следующие инструкции using.
(Фрагмент кода — Web Forms Lab — Ex01 — пространства имен)
using System.Collections.Generic; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Linq; using WebFormsLab.Model;Добавьте частный член в класс Products и назначьте новый экземпляр ProductsContext. Это свойство будет хранить контекст данных Entity Framework, позволяющий подключаться к базе данных.
public partial class Products : System.Web.UI.Page { private ProductsContext db = new ProductsContext(); ...Создайте метод GetCategories для получения списка категорий с помощью LINQ. Запрос будет содержать свойство Products , чтобы GridView отображал количество продуктов для каждой категории. Обратите внимание, что метод возвращает необработанный объект IQueryable, представляющий запрос, который будет выполняться позже в жизненном цикле страницы.
(Фрагмент кода — лаборатория веб-формы — Ex01 — GetCategories)
public IQueryable<Category> GetCategories() { var query = this.db.Categories .Include(c => c.Products); return query; }Примечание.
В предыдущих версиях ASP.NET Web Forms для активизации сортировки и разбивки на страницы с использованием логики собственного репозитория в контексте источника данных объекта, необходимо было написать собственный пользовательский код и получить все необходимые параметры. Теперь, когда методы привязки данных могут возвращать IQueryable, и это представляет запрос, который еще предстоит выполнить, ASP.NET может изменять запрос, чтобы добавить параметры сортировки и разбиения по страницам.
Нажмите клавишу F5 , чтобы начать отладку сайта и перейти на страницу "Продукты". Вы увидите, что GridView заполняется категориями, возвращаемыми методом GetCategories.
Заполнение GridView с помощью привязки модели
Нажмите SHIFT+F5, чтобы остановить отладку.
Задача 3. Поставщики значений в привязке модели
Привязка модели не только позволяет указывать пользовательские методы для работы с данными непосредственно в элементе управления с привязкой к данным, но и позволяет сопоставлять данные со страницы с параметрами из этих методов. В параметре метода можно использовать атрибуты поставщика значений для указания источника данных значения. Например:
- Элементы управления на странице
- Значения строки запроса
- Просмотреть данные
- Состояние сеанса
- Файлы cookie
- Отправленные данные формы
- Просмотр состояния
- Поставщики настраиваемых значений также поддерживаются
Если вы использовали ASP.NET MVC 4, вы заметите, что поддержка привязки модели аналогична. Действительно, эти функции были взяты из ASP.NET MVC и перемещены в сборку System.Web, чтобы также использовать их на веб-формах.
В этой задаче вы обновите GridView, чтобы отфильтровать результаты по количеству продуктов для каждой категории, получая параметр фильтра с привязкой модели.
Вернитесь на страницу Products.aspx .
В верхней части GridView добавьте метку и comboBox , чтобы выбрать количество продуктов для каждой категории, как показано ниже.
<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/>Добавьте emptyDataTemplate в GridView, чтобы отобразить сообщение, если нет категорий с выбранным количеством продуктов.
<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>Откройте файл с кодом Products.aspx.cs и добавьте следующую директиву using.
using System.Web.ModelBinding;Измените метод GetCategories , чтобы получить целочисленный аргумент minProductsCount и отфильтровать возвращаемые результаты. Для этого замените метод следующим кодом.
(Фрагмент кода — Web Forms Lab - 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; }Новый атрибут [Control] в аргументе minProductsCount позволит ASP.NET знать, что его значение должно быть заполнено с помощью элемента управления на странице. ASP.NET будет искать любой элемент управления, соответствующий имени аргумента (minProductsCount), и выполнить необходимое сопоставление и преобразование для заполнения параметра значением элемента управления.
Кроме того, атрибут предоставляет перегруженный конструктор, позволяющий указать элемент управления, из которого нужно получить значение.
Примечание.
Одной из целей функций привязки данных является уменьшение объема кода, который необходимо записать для взаимодействия со страницей. Помимо поставщика значений [Control], вы можете использовать другие поставщики привязки модели в параметрах метода. Некоторые из них перечислены во введении задачи.
Нажмите клавишу F5 , чтобы начать отладку сайта и перейти на страницу "Продукты". Выберите ряд продуктов в раскрывающемся списке и обратите внимание, как теперь обновляется GridView.
Фильтрация GridView по значению из раскрывающегося списка
Остановите отладку.
Задача 4. Использование привязки модели для фильтрации
В этой задаче вы добавите второй дочерний элемент GridView, чтобы отобразить продукты в выбранной категории.
Откройте страницу Products.aspx и обновите категории GridView, чтобы автоматически создать кнопку "Выбрать".
<asp:GridView ID="categoriesGrid" runat="server" AutoGenerateColumns="false" ItemType="WebFormsLab.Model.Category" DataKeyNames="CategoryId" SelectMethod="GetCategories" AutoGenerateSelectButton="true">Добавьте второй элемент GridView с именем productsGrid в нижней части экрана. Задайте для ItemType значение WebFormsLab.Model.Product, для DataKeyNames значение ProductId и для SelectMethod значение GetProducts. Установите для AutoGenerateColumns значение false и добавьте столбцы для ProductId, ProductName, Description и 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>Откройте файл кода программной части Products.aspx.cs. Реализуйте метод GetProducts для получения идентификатора категории из gridView категории и фильтрации продуктов. Привязка модели задает значение параметра, используя выбранную строку в categoriesGrid. Так как имя аргумента и имя элемента управления не совпадают, следует указать имя элемента управления в поставщике значений элемента управления.
(Фрагмент кода — лаборатория веб-формы — Ex01 — GetProducts)
public IEnumerable<Product> GetProducts([Control("categoriesGrid")]int? categoryId) { return this.db.Products.Where(p => p.CategoryId == categoryId); }Примечание.
Этот подход упрощает модульное тестирование этих методов. В контексте модульного теста, где веб-формы не выполняется, атрибут [Control] не будет выполнять какое-либо определенное действие.
Откройте страницу Products.aspx и найдите продукты GridView. Обновите таблицу GridView для отображения ссылки редактирования выбранного продукта.
<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>Откройте код страницы ProductDetails.aspx и замените метод SelectProduct следующим кодом.
(Фрагмент кода — Web Forms Lab — Ex01 — SelectProduct Method)
public Product SelectProduct([QueryString]int? productId) { return this.db.Products.Find(productId); }Примечание.
Обратите внимание, что атрибут [QueryString] используется для заполнения параметра метода из параметра productId в строке запроса.
Нажмите клавишу F5 , чтобы начать отладку сайта и перейти на страницу "Продукты". Выберите любую категорию из категорий GridView и обратите внимание, что продукт GridView обновлен.
Отображение продуктов из выбранной категории
Щелкните ссылку "Вид " на продукте, чтобы открыть страницу ProductDetails.aspx.
Обратите внимание, что страница извлекает продукт с помощью метода SelectMethod, используя параметр идентификатор_продукта из строки запроса.
Просмотр сведений о продукте
Примечание.
Возможность ввода описания HTML будет реализована в следующем упражнении.
Задача 5. Использование привязки модели для операций обновления
В предыдущей задаче вы использовали привязку модели главным образом для выбора данных, в этой задаче вы узнаете, как использовать привязку модели в операциях обновления.
Вы обновите категории GridView, чтобы позволить пользователям обновлять категории.
Откройте страницу Products.aspx и обновите категории GridView, чтобы автоматически создать кнопку "Изменить" и использовать новый атрибут UpdateMethod, чтобы указать метод UpdateCategory для обновления выбранного элемента.
<asp:GridView ID="categoriesGrid" runat="server" AutoGenerateColumns="false" ItemType="WebFormsLab.Model.Category" DataKeyNames="CategoryId" SelectMethod="GetCategories" AutoGenerateSelectButton="true" AutoGenerateEditButton="true" UpdateMethod="UpdateCategory">Атрибут DataKeyNames в GridView определяет, какие члены однозначно определяют объект, привязанный к модели, и, следовательно, которые являются параметрами, которые метод обновления должен получать по крайней мере.
Откройте файл кода Products.aspx.cs и реализуйте метод UpdateCategory. Метод должен получить идентификатор категории, чтобы загрузить текущую категорию, заполнить значения из GridView, а затем обновить категорию.
(Фрагмент кода — Web Forms Lab — Ex01 — UpdateCategory)
public void UpdateCategory(int categoryId) { var category = this.db.Categories.Find(categoryId); this.TryUpdateModel(category); if (this.ModelState.IsValid) { this.db.SaveChanges(); } }Новый метод TryUpdateModel в классе Page отвечает за заполнение объекта модели с помощью значений из элементов управления на странице. В этом случае обновленные значения из редактируемой строки GridView будут заменены в объекте категории.
Примечание.
В следующем упражнении объясняется использование ModelState.IsValid для проверки данных, введенных пользователем при редактировании объекта.
Запустите сайт и перейдите на страницу "Продукты". Изменение категории. Введите новое имя и нажмите кнопку "Обновить ", чтобы сохранить изменения.
Изменение категорий
Упражнение 2. Проверка данных
В этом упражнении вы узнаете о новых функциях проверки данных в ASP.NET 4.5. Вы ознакомитесь с новыми ненавязчивыми функциями проверки в веб-формах. Вы будете использовать заметки данных в классах модели приложения для проверки ввода пользователей, и, наконец, вы узнаете, как включить или отключить проверку запросов для отдельных элементов управления на странице.
Задача 1. Ненавязчивая проверка
Формы с сложными данными, включая проверяющие элементы, как правило, создают слишком много кода JavaScript на странице, что может представлять около 60% кода. С включенной ненавязчивой проверкой HTML-код будет выглядеть более чистым и упорядоченным.
В этом разделе описано, как включить ненавязчивую проверку в ASP.NET для сравнения HTML-кода, созданного обеими конфигурациями.
Откройте Visual Studio 2012 и откройте решение Begin, расположенное в папке Source\Ex2-Validation\Begin этой лаборатории. Кроме того, можно продолжить работу над существующим решением из предыдущего упражнения.
Если вы открыли предоставленное решение Begin , перед продолжением необходимо скачать некоторые отсутствующие пакеты NuGet. Для этого в Обозревателе решений щелкните проект WebFormsLab, затем выберите Управление пакетами NuGet.
В диалоговом окне "Управление пакетами NuGet" нажмите кнопку "Восстановить", чтобы скачать отсутствующие пакеты.
Наконец, создайте решение, нажав Сборка | Сборка решения.
Примечание.
Одним из преимуществ использования NuGet является то, что вам не нужно отправлять все библиотеки в проекте, уменьшая размер проекта. С помощью NuGet Power Tools, указав версии пакетов в файле Packages.config, вы сможете скачать все необходимые библиотеки при первом запуске проекта. Поэтому после открытия существующего решения в этой лаборатории необходимо выполнить эти действия.
Нажмите клавишу F5 , чтобы запустить веб-приложение. Перейдите на страницу "Клиенты" и щелкните ссылку "Добавить нового клиента ".
Щелкните правой кнопкой мыши страницу браузера и выберите пункт "Просмотреть источник" , чтобы открыть HTML-код, созданный приложением.
Отображение HTML-кода страницы
Прокрутите исходный код страницы и обратите внимание, что ASP.NET ввели код JavaScript и проверяющие данные на странице для выполнения проверок и отображения списка ошибок.
Проверка кода JavaScript на странице CustomerDetails
Закройте браузер и вернитесь в Visual Studio.
Теперь вы включите ненавязчивую проверку. Откройте Web.Config и найдите ключ ValidationSettings:UntrusiveValidationMode в разделе AppSettings. Задайте для параметра "Ключ" значение WebForms.
<configuration> ... <appSettings> <add key="aspnet:uselegacysynchronizationcontext" value="false" /> <add key="ValidationSettings:UnobtrusiveValidationMode" value="WebForms"/>Примечание.
Это свойство также можно задать в событии "Page_Load", если вы хотите включить ненавязчивую проверку только для некоторых страниц.
Откройте CustomerDetails.aspx и нажмите клавишу F5 , чтобы запустить веб-приложение.
Нажмите клавишу F12, чтобы открыть средства разработчика IE. После открытия средств разработчика выберите вкладку скрипта. Выберите CustomerDetails.aspx в меню и обратите внимание, что скрипты, необходимые для запуска jQuery на странице, были загружены в браузер с локального сайта.
Загрузка файлов JavaScript jQuery непосредственно с локального сервера IIS
Закройте браузер, чтобы вернуться в Visual Studio. Снова откройте файл Site.Master и найдите ScriptManager. Добавьте атрибут EnableCdn со свойством со значением True. Это приведет к загрузке jQuery из URL-адреса в Интернете, а не из URL-адреса локального сайта.
Откройте CustomerDetails.aspx в Visual Studio. Нажмите клавишу F5, чтобы запустить сайт. После открытия Internet Explorer нажмите клавишу F12, чтобы открыть средства разработчика. Выберите вкладку "Скрипт" , а затем просмотрите раскрывающийся список. Обратите внимание, что файлы JavaScript jQuery больше не загружаются с локального сайта, а не из сети jQuery CDN.
Загрузка файлов JavaScript jQuery из CDN
Снова откройте исходный код HTML-страницы с помощью параметра "Просмотр источника" в браузере. Обратите внимание, что включение ненавязчивой проверки заменяет внедренный код JavaScript атрибутами данных в ASP.NET.
Ненавязчивый код проверки
Примечание.
В этом примере вы узнали, как сводка проверки с заметками данных была упрощена до нескольких строк HTML и JavaScript. Ранее, без ненавязчивой проверки, чем больше вы добавляете элементов управления проверки, тем больше увеличивается код проверки JavaScript.
Задача 2. Проверка модели с помощью аннотаций данных
ASP.NET 4.5 включает аннотации для проверки данных для веб-форм. Вместо управления проверкой для каждого входного данных теперь можно определить ограничения в классах моделей и использовать их во всех веб-приложениях. В этом разделе вы узнаете, как использовать заметки данных для проверки новой или редактирования формы клиента.
Откройте страницу CustomerDetail.aspx . Обратите внимание, что имя клиента и второе имя в разделах EditItemTemplate и InsertItemTemplate проверяются с помощью элементов управления RequiredFieldValidator. Каждый проверяющий элемент связан с определенным условием, поэтому необходимо включить столько проверяющих элементов, сколько условий.
Добавьте аннотации данных для проверки класса модели Customer. Откройте класс Customer.cs в папке Model и украшайте каждое свойство с помощью атрибутов заметки данных.
(Фрагмент кода — Лаборатория веб-форм — Ex02 — аннотации данных)
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; } } }Примечание.
платформа .NET Framework 4.5 расширила существующую коллекцию заметок данных. Это некоторые заметки данных, которые можно использовать: [CreditCard], [Phone], [EmailAddress], [Range], [Compare], [URL], [FileExtensions], [Обязательный], [Ключ], [RegularExpression].
Некоторые примеры использования:
[Ключ]: указывает, что атрибут является уникальным идентификатором.
[Range(0.4, 0.5, ErrorMessage="{Запись сообщения об ошибке}"]: двойной диапазон
[EmailAddress(ErrorMessage="Invalid Email"), MaxLength(56)]: две заметки в одной строке.
Вы также можете определить собственные сообщения об ошибках в каждом атрибуте.
Откройте CustomerDetails.aspx и удалите все поля RequiredFieldValidator для полей имени и фамилии в разделах EditItemTemplate и InsertItemTemplate элемента управления 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> ...Примечание.
Одним из преимуществ использования заметок данных является то, что логика проверки не дублируется на страницах приложения. Вы определяете его один раз в модели и используете его на всех страницах приложения, которые управляют данными.
Откройте файл кода CustomerDetails.aspx и найдите метод SaveCustomer. Этот метод вызывается при вставке нового клиента и получает параметр Customer из значений элемента управления FormView. Когда происходит сопоставление между элементами управления страницы и объектом параметра, ASP.NET будет выполнять проверку модели на основе всех атрибутов аннотации данных и заполнять словарь ModelState ошибками, если таковые имеются.
ModelState.IsValid возвращает значение true, если все поля в модели действительны после выполнения проверки.
public void SaveCustomer(Customer customer) { if (this.ModelState.IsValid) { using (var db = new ProductsContext()) { ...Добавьте элемент управления ValidationSummary в конце страницы CustomerDetails, чтобы отобразить список ошибок модели.
</fieldset> </InsertItemTemplate> </asp:FormView> <asp:ValidationSummary runat="server" ShowModelStateErrors="true" ForeColor="Red" HeaderText="Please check the following errors:"/> </asp:Content>ShowModelStateErrors — это новое свойство в элементе управления ValidationSummary, которое при установке значения true элемент управления будет отображать ошибки из словаря ModelState. Эти ошибки возникают из проверки заметок данных.
Нажмите клавишу F5 , чтобы запустить веб-приложение. Заполните форму с некоторыми ошибочными значениями и нажмите кнопку "Сохранить ", чтобы выполнить проверку. Обратите внимание на сводку об ошибке внизу.
Валидация с помощью аннотаций данных
Задача 3. Обработка ошибок пользовательской базы данных с помощью ModelState
В предыдущих версиях Web Forms обработка ошибок базы данных, таких как слишком длинная строка или нарушение уникального ключа, могла включать возникновение исключений в коде репозитория с последующей обработкой этих исключений в коде code-behind для отображения ошибки. Для выполнения чего-то относительно простого требуется большое количество кода.
В веб-формы 4.5 объект ModelState можно использовать для отображения ошибок на странице из модели или базы данных в согласованном режиме.
В этой задаче вы добавите код для правильной обработки исключений базы данных и отобразите пользователю соответствующее сообщение с помощью объекта ModelState.
Пока приложение по-прежнему работает, попробуйте обновить имя категории с помощью повторяющегося значения.
Обновление категории с повторяющимся именем
Обратите внимание, что исключение генерируется из-за ограничения "unique" столбца CategoryName.
Исключение для повторяющихся имен категорий
Остановите отладку. В файле кода Products.aspx.cs обновите метод UpdateCategory для обработки исключений, вызываемых вызовом метода db.SaveChanges(), и добавьте ошибку в объект ModelState.
Новый метод TryUpdateModel обновляет объект категории, полученный из базы данных, с помощью данных формы, предоставленных пользователем.
(Фрагмент кода — Лаборатория Web Forms — Ex02 — Обработка ошибок обновления категории)
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); } } }Примечание.
В идеале необходимо определить причину DbUpdateException и проверить, является ли первопричина нарушением ограничения уникального ключа.
Откройте Products.aspx и добавьте элемент управления ValidationSummary под категориями GridView, чтобы отобразить список ошибок модели.
<asp:GridView ID="categoriesGrid" runat="server" ... </asp:GridView> <asp:ValidationSummary ID="ValidationSummary1" runat="server" ShowModelStateErrors="true" /> <h3>Products</h3>Запустите сайт и перейдите на страницу "Продукты". Попробуйте обновить имя категории с помощью повторяющегося значения.
Обратите внимание, что исключение было обработано, и сообщение об ошибке отображается в контроле ValidationSummary.
Ошибка дублированной категории
Задача 4. Проверка запроса в ASP.NET Web Forms 4.5
Функция проверки запросов в ASP.NET обеспечивает определенный уровень защиты по умолчанию от атак XSS. В предыдущих версиях ASP.NET проверка запросов была включена по умолчанию и может быть отключена только для всей страницы. С помощью новой версии ASP.NET веб-формы теперь можно отключить проверку запроса для одного элемента управления, выполнить отложенную проверку запросов или получить доступ к данным запроса без проверки (будьте осторожны, если это сделать!).
Нажмите клавиши CTRL+F5 , чтобы запустить сайт без отладки и перейти на страницу "Продукты". Выберите категорию и щелкните ссылку "Изменить " для любого из продуктов.
Введите описание, содержащее потенциально опасное содержимое, например теги HTML. Обратите внимание на исключение, возникшее из-за проверки запроса.
Редактирование продукта с потенциально опасным содержимым
Исключение, возникающее из-за проверки запроса
Закройте страницу и в Visual Studio нажмите клавиши SHIFT+F5, чтобы остановить отладку.
Откройте страницу ProductDetails.aspx и найдите текстовое поле "Описание ".
Добавьте новое свойство ValidateRequestMode в TextBox и задайте для нее значение Disabled.
Новый атрибут ValidateRequestMode позволяет отключить проверку запроса детализированно для каждого элемента управления. Это полезно, если вы хотите использовать входные данные, которые могут получать HTML-код, но хотите сохранить проверку для остальной части страницы.
<p> <asp:TextBox runat="server" ID="Description" TextMode="MultiLine" Cols="60" Rows="8" Text='<%# BindItem.Description %>' ValidateRequestMode="Disabled" /> </p>Нажмите клавишу F5 , чтобы запустить веб-приложение. Откройте страницу редактирования продукта еще раз и заполните описание продукта, включая html-теги. Обратите внимание, что теперь можно добавить HTML-содержимое в описание.
Проверка запроса отключена для описания продукта
Примечание.
В рабочем приложении необходимо удалить html-код, введенный пользователем, чтобы убедиться, что введены только безопасные HTML-теги (например, <нет тегов скрипта> ). Для этого можно использовать библиотеку Microsoft Web Protection.
Снова отредактируйте продукт. Введите HTML-код в поле "Имя" и нажмите кнопку "Сохранить". Обратите внимание, что проверка запроса отключена только для поля описания, а остальные поля по-прежнему проверяются на потенциально опасное содержимое.
Проверка запроса включена в остальных полях
ASP.NET веб-формы 4.5 включают в себя новый режим проверки запросов для ленивого выполнения проверки запросов. Если для режима проверки запроса задано значение 4.5, если часть кода обращается к Request.Form["key"], проверка запроса ASP.NET 4.5 будет активировать проверку только для этого конкретного элемента в коллекции форм.
Кроме того, ASP.NET 4.5 теперь включает основные процедуры кодирования из библиотеки Microsoft Anti-XSS версии 4.0. Подпрограммы кодирования Anti-XSS реализуются новым типом AntiXssEncoder , найденным в новом пространстве имен System.Web.Security.AntiXss . При настройке параметра encoderType для использования AntiXssEncoder все выходные кодировки в ASP.NET автоматически используют новые подпрограммы кодирования.
ASP.NET 4.5 проверка запроса также поддерживает незащищенный доступ к данным запроса. ASP.NET 4.5 добавляет новое свойство коллекции в объект HttpRequest с именем Unvalidated. При переходе по протоколу HttpRequest.Unvalidated у вас есть доступ ко всем общим частям данных запроса, включая Формы, QueryStrings, Файлы cookie, URL-адреса и т. д.
Объект Request.Unvalidated
Примечание.
Используйте свойство HttpRequest.Unvalidated с осторожностью! Убедитесь, что вы тщательно выполняете пользовательскую проверку необработанных данных запроса, чтобы опасный текст не возвращался и не отображался обратно ничего не подозревающим клиентам!
Упражнение 3: Асинхронная обработка страниц в ASP.NET веб-формах
В этом упражнении вы узнаете о новых функциях асинхронной обработки страниц в ASP.NET веб-формы.
Задача 1. Обновление страницы сведений о продукте для отправки и отображения изображений
В этой задаче вы обновите страницу сведений о продукте, чтобы разрешить пользователю указать URL-адрес изображения для продукта и отобразить его в режиме только для чтения. Вы создадите локальную копию указанного образа, скачав его синхронно. В следующей задаче вы обновите эту реализацию, чтобы она работала асинхронно.
Откройте Visual Studio 2012 и загрузите решение Begin, расположенное в папке Source\Ex3-Async\Begin из папки этой лаборатории. Кроме того, можно продолжить работу над существующим решением из предыдущих упражнений.
Если вы открыли предоставленное решение Begin , перед продолжением необходимо скачать некоторые отсутствующие пакеты NuGet. Для этого в Обозревателе решений выберите проект WebFormsLab и нажмите на Управление пакетами NuGet.
В диалоговом окне "Управление пакетами NuGet" нажмите кнопку "Восстановить", чтобы скачать отсутствующие пакеты.
Наконец, создайте решение, нажав Сборка | Сборка решения.
Примечание.
Одним из преимуществ использования NuGet является то, что вам не нужно отправлять все библиотеки в проекте, уменьшая размер проекта. С помощью NuGet Power Tools, указав версии пакетов в файле Packages.config, вы сможете скачать все необходимые библиотеки при первом запуске проекта. Поэтому после открытия существующего решения в этой лаборатории необходимо выполнить эти действия.
Откройте источник страницы ProductDetails.aspx и добавьте поле в элемент ItemTemplate FormView, чтобы отобразить изображение продукта.
<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>Добавьте поле, чтобы указать URL-адрес изображения в 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>Откройте файл ProductDetails.aspx.cs кода программной части и добавьте следующие директивы пространства имен.
(Фрагмент кода — Web Forms Lab — Ex03 — Пространства имен)
using System.IO; using System.Net; using System.Web;Создайте метод UpdateProductImage для хранения удаленных образов в локальной папке Images и обновления сущности продукта с новым значением расположения изображения.
(Фрагмент кода — лаборатория веб-формы — 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)); } } }Обновите метод UpdateProduct, чтобы вызвать метод UpdateProductImage.
(Фрагмент кода — Web Forms Lab — Ex03 — вызов функции UpdateProductImage)
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(); } }Запустите приложение и попытайтесь отправить образ для продукта.
Настройка образа для продукта
Задача 2. Добавление асинхронной обработки на страницу сведений о продукте
В этой задаче вы обновите страницу сведений о продукте, чтобы она работала асинхронно. Вы улучшите длительно выполняющуюся задачу — процесс загрузки изображений — с помощью асинхронной обработки страниц в ASP.NET 4.5.
Асинхронные методы в веб-приложениях можно использовать для оптимизации способа использования пулов потоков ASP.NET. В ASP.NET существует ограниченное количество потоков в пуле потоков для участия в запросах, поэтому, когда все потоки заняты, ASP.NET начинает отклонять новые запросы, отправляет сообщения об ошибках приложения и делает сайт недоступным.
Трудоемкие операции на вашем веб-сайте являются эффективными кандидатами для асинхронного программирования, так как они занимают выделенный поток в течение длительного времени. Это включает длительные запросы, страницы с большим количеством различных элементов и страниц, требующих автономных операций, таких как запрос базы данных или доступ к внешнему веб-серверу. Преимущество заключается в том, что если вы используете асинхронные методы для этих операций, при обработке страницы поток освобождается и возвращается в пул потоков, и его можно использовать для обслуживания нового запроса страницы. Это означает, что страница начнет обработку в одном потоке из пула потоков и может завершить обработку в другой, после завершения асинхронной обработки.
Откройте страницу ProductDetails.aspx . Добавьте атрибут Async в элемент Page и задайте для него значение true. Этот атрибут указывает ASP.NET реализовать интерфейс IHttpAsyncHandler.
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="ProductDetails.aspx.cs" Inherits="WebFormsLab.ProductDetails" Async="true" %>Добавьте ярлык внизу страницы, чтобы отобразить сведения о потоках, на которых выполняется работа страницы.
<EmptyDataTemplate>Product not found</EmptyDataTemplate> </asp:FormView> <asp:Label ID="threadsMessageLabel" runat="server" /> </asp:Content>Откройте ProductDetails.aspx.cs и добавьте следующие директивы пространства имен.
(Фрагмент кода — Web Forms Lab — Ex03 — Пространства имен 2)
using System.Web.UI; using System.Threading;Измените метод UpdateProductImage , чтобы скачать изображение с асинхронной задачей. Вы замените метод WebClientDownloadFile методом DownloadFileTaskAsync и включите ключевое слово await.
(Code Snippet - Web Forms Lab - 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 регистрирует новую асинхронную задачу страницы, выполняемую в другом потоке. Он получает лямбда-выражение с задачей (t), которая должна быть выполнена. Ключевое слово await в методе DownloadFileTaskAsync преобразует оставшуюся часть метода в обратный вызов, который вызывается асинхронно после завершения метода DownloadFileTaskAsync. ASP.NET возобновляет выполнение метода, автоматически сохраняя все исходные значения HTTP-запроса. Новая асинхронная модель программирования в .NET 4.5 позволяет создавать асинхронный код, который выглядит очень как синхронный код, и позволить компилятору обрабатывать осложнения функций обратного вызова или кода продолжения.
Примечание.
RegisterAsyncTask и PageAsyncTask уже доступны с .NET 2.0. Ключевое слово await является новым из модели асинхронного программирования .NET 4.5 и может использоваться вместе с новыми методами TaskAsync из объекта .NET WebClient.
Добавьте код для отображения потоков, на которых запущен и завершен выполнение кода. Для этого обновите метод UpdateProductImage со следующим кодом.
(Фрагмент кода — Web Forms Lab — Ex03 — Отображение потоков)
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); })); } }Откройте файл конфигурации web.config веб-сайта. Добавьте следующую переменную appSetting.
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>Нажмите клавишу F5 , чтобы запустить приложение и отправить изображение для продукта. Обратите внимание, что идентификатор потоков, на котором запущен и завершен код, может отличаться. Это связано с тем, что асинхронные задачи выполняются в отдельном потоке из пула потоков ASP.NET. По завершении задачи ASP.NET помещает задачу обратно в очередь и назначает любой из доступных потоков.
Асинхронное скачивание образа
Примечание.
Кроме того, вы можете опубликовать это приложение в Azure, следуя Приложению B: Публикация приложения ASP.NET MVC 4 с помощью Web Deploy.
Итоги
В этой практической лаборатории рассматриваются и демонстрируются следующие понятия:
- Использование строго типизированных выражений привязки данных
- Использование новых функций привязки модели в веб-формы
- Использование поставщиков значений для сопоставления данных страницы с методами программной части
- Использование заметок данных для проверки ввода пользователем
- Воспользуйтесь незаметной проверкой на стороне клиента с помощью jQuery в веб-формах
- Реализация детализации проверки запроса
- Реализация асинхронной обработки страниц для веб-форм
Приложение A. Установка Visual Studio Express 2012 для Интернета
Вы можете установить Microsoft Visual Studio Express 2012 для Web или другую версию Express с помощью установщика Microsoft Web Platform Installer. Ниже приведены инструкции по установке Visual Studio Express 2012 для Интернета с помощью установщика веб-платформа Майкрософт.
Перейдите в раздел [/iis/extensions/introduction-to-iis-express/iis-express-overview?linkid=9810169](/iis/extensions/introduction-to-iis-express/iis-express-overview?linkid=9810169). Кроме того, если вы уже установили установщик веб-платформы, его можно открыть и найти продукт Visual Studio Express 2012 для веба с Azure SDK.
Нажмите кнопку "Установить сейчас". Если у вас нет установщика веб-платформы, вы будете перенаправлены, чтобы скачать и установить его сначала.
После открытия установщика веб-платформы нажмите кнопку "Установить ", чтобы запустить настройку.
Установка Visual Studio Express
Прочитайте все лицензии и условия продуктов и нажмите кнопку "Принять ", чтобы продолжить.
Принятие условий лицензии
Дождитесь завершения процесса загрузки и установки.
Ход установки
После завершения установки нажмите кнопку "Готово".
Завершена установка
Нажмите кнопку " Выйти" , чтобы закрыть установщик веб-платформы.
Чтобы открыть Visual Studio Express для Интернета, перейдите на начальный экран и начните писать "VS Express", а затем щелкните элемент VS Express для веб-страницы.
Плитка VS Express для веб-сайта
Приложение B. Публикация приложения MVC 4 ASP.NET с помощью веб-развертывания
В этом приложении показано, как создать новый веб-сайт через портал управления Azure и опубликовать приложение, полученное в результате выполнения практического занятия, используя функцию веб-развертывания для публикации, предоставляемую Azure.
Задача 1. Создание веб-сайта на портале Azure
Перейдите на портал управления Azure и войдите с помощью учетных данных Майкрософт, связанных с подпиской.
Примечание.
С помощью Azure можно разместить 10 ASP.NET веб-сайты бесплатно, а затем масштабировать по мере роста трафика. Вы можете зарегистрироваться здесь.
Вход на портал
Нажмите кнопку "Создать" на панели команд.
Создание нового веб-сайта
Щелкните Вычислить | Веб-сайт. Затем нажмите кнопку быстрого создания . Укажите доступный URL-адрес для нового веб-сайта и нажмите кнопку "Создать веб-сайт".
Примечание.
Azure является хостом веб-приложения, работающего в облаке, которым вы можете управлять и администрировать. Параметр быстрого создания позволяет развернуть завершенное веб-приложение в Azure за пределами портала. Он не включает шаги по настройке базы данных.
Создание нового веб-сайта с помощью быстрого создания
Дождитесь создания нового веб-сайта .
После создания веб-сайта щелкните ссылку в столбце URL-адреса . Убедитесь, что новый веб-сайт работает.
Просмотр нового веб-сайта
Запущенный веб-сайт
Вернитесь на портал и щелкните имя веб-сайта в столбце "Имя ", чтобы отобразить страницы управления.
Открытие страниц управления веб-сайтами
На странице "Панель мониторинга", в разделе быстрого просмотра, щелкните ссылку "Скачать профиль публикации".
Примечание.
Профиль публикации содержит все сведения, необходимые для публикации веб-приложения в Azure для каждого включенного метода публикации. Профиль публикации содержит URL-адреса, учетные данные пользователя и строки базы данных, необходимые для подключения к каждой конечной точке, для которой включен метод публикации. Microsoft WebMatrix 2, Microsoft Visual Studio Express для Web и Microsoft Visual Studio 2012 поддерживают чтение профилей публикации для автоматизации настройки этих программ для публикации веб-приложений в Azure.
Загрузка профиля публикации веб-сайта
Скачайте файл профиля публикации в известное расположение. Далее в этом упражнении вы узнаете, как использовать этот файл для публикации веб-приложения в Azure из Visual Studio.
Сохранение файла профиля публикации
Задача 2. Настройка сервера базы данных
Если приложение использует базы данных SQL Server, вам потребуется создать сервер База данных SQL. Если вы хотите развернуть простое приложение, которое не использует SQL Server, вы можете пропустить эту задачу.
Для хранения базы данных приложения потребуется сервер База данных SQL. Вы можете просмотреть серверы баз данных SQL из вашей подписки в портале управления Azure, перейдя по пунктам меню Базы данных SQL | Серверы | на Панели управления сервера. Если у вас нет сервера, его можно создать с помощью кнопки "Добавить " на панели команд. Запишите имя сервера и URL-адрес, имя входа администратора и пароль, так как они будут использоваться в следующих задачах. Пока не создайте базу данных, так как она будет создана на более позднем этапе.
панель мониторинга сервера База данных SQL
В следующей задаче вы протестируете подключение к базе данных из Visual Studio, по этой причине необходимо включить локальный IP-адрес в список разрешенных IP-адресов сервера. Для этого нажмите кнопку "Настроить", выберите IP-адрес из текущего IP-адреса клиента и вставьте его в текстовые поля "Начальный IP-адрес" и add-client-ip-address-ok-button"Конечный IP-адрес".
Добавление IP-адреса клиента
После добавления IP-адреса клиента в список разрешенных IP-адресов нажмите кнопку "Сохранить", чтобы подтвердить изменения.
Подтверждение изменений
Задача 3. Публикация приложения MVC 4 ASP.NET с помощью веб-развертывания
Вернитесь к решению MVC 4 ASP.NET. В Обозреватель решений щелкните правой кнопкой мыши проект веб-сайта и выберите "Опубликовать".
Публикация веб-сайта
Импортируйте профиль публикации, сохраненный в первой задаче.
Импорт профиля публикации
Нажмите кнопку "Проверить подключение". После завершения проверки нажмите кнопку "Далее".
Примечание.
После завершения проверки появится зеленая галочка рядом с кнопкой "Проверить подключение".
Проверка подключения
На странице "Параметры" в разделе "Базы данных" нажмите кнопку рядом с текстовым полем подключения к базе данных (т. е. DefaultConnection).
Конфигурация веб-развертывания
Настройте подключение к базе данных следующим образом:
В поле "Имя сервера" введите URL-адрес сервера База данных SQL с помощью префикса TCP.
В поле "Имя пользователя" введите имя входа администратора сервера.
Введите пароль для входа администратора сервера.
Введите новое имя базы данных.
Настройка конечного строка подключения
Затем нажмите кнопку ОК. При появлении запроса на создание базы данных нажмите кнопку "Да".
Создание базы данных
В текстовом поле "Подключение по умолчанию" отображается строка подключения, используемая для подключения к базе данных SQL в Azure. Затем нажмите Далее.
Строка подключения к SQL-базе данных
На странице предварительного просмотра нажмите кнопку "Опубликовать".
Публикация веб-приложения
После завершения процесса публикации браузер по умолчанию откроет опубликованный веб-сайт.
Приложение C. Использование фрагментов кода
При использовании фрагментов кода у вас есть весь код, который вам нужен на пальцах. В документе лаборатории вы узнаете, когда их можно использовать, как показано на следующем рисунке.
Использование фрагментов кода Visual Studio для вставки кода в проект
Добавление фрагмента кода с помощью клавиатуры (только для C#)
- Поместите курсор, в который вы хотите вставить код.
- Начните вводить имя фрагмента кода (без пробелов или дефисов).
- Посмотрите, как IntelliSense отображает соответствующие имена фрагментов.
- Выберите правильный фрагмент кода (или продолжайте вводить текст до тех пор, пока не будет выбрано имя всего фрагмента кода).
- Дважды нажмите клавишу TAB, чтобы вставить фрагмент в расположение курсора.
Начните вводить имя фрагмента кода
Нажмите клавишу TAB, чтобы выбрать выделенный фрагмент кода
Нажмите клавишу TAB еще раз, и фрагмент будет развернут
Добавление фрагмента кода с помощью мыши (C#, Visual Basic и XML) 1. Щелкните правой кнопкой мыши место вставки фрагмента кода.
- Выберите Вставить фрагмент, затем Мои фрагменты кода.
- Выберите соответствующий фрагмент из списка, щелкнув его.
Щелкните правой кнопкой мыши место вставки фрагмента кода и выберите "Вставить фрагмент кода"
Выберите соответствующий фрагмент из списка, щелкнув его