Поделиться через


Новые возможности веб-форм в ASP.NET 4.5

Команда веб-лагерей

Новая версия ASP.NET веб-формы представляет ряд улучшений, ориентированных на улучшение взаимодействия с пользователями при работе с данными.

В предыдущих версиях веб-формы при использовании привязки данных для выдачи значения члена объекта вы использовали выражения привязки данных Bind() или Eval(). В новой версии ASP.NET вы можете объявить тип данных, к которым будет привязан элемент управления с помощью нового свойства ItemType. Задание этого свойства позволит использовать строго типизированную переменную для получения полных преимуществ возможностей разработки Visual Studio, таких как IntelliSense, навигация по членам и проверка времени компиляции.

Теперь с помощью элементов управления с привязкой к данным можно также указать собственные пользовательские методы для выбора, обновления, удаления и вставки данных, упрощая взаимодействие между элементами управления страницы и логикой приложения. Кроме того, возможности привязки модели были добавлены в ASP.NET, что означает, что данные с страницы можно сопоставить непосредственно с параметрами типа метода.

Проверка входных данных пользователей также должна быть проще с последней версией веб-формы. Теперь можно анимировать классы моделей с атрибутами проверки из пространства имен System.ComponentModel.DataAnnotations и запросить, чтобы все элементы управления сайта проверяли входные данные пользователей с помощью этой информации. Проверка на стороне клиента в веб-формы теперь интегрирована с jQuery, обеспечивая более чистый клиентский код и ненавязчивые функции JavaScript.

В области проверки запроса были улучшены улучшения, чтобы упростить выборочное отключение проверки запросов для определенных частей приложений или считывание недопустимых данных запроса.

Некоторые улучшения были сделаны для веб-формы серверных элементов управления, чтобы воспользоваться новыми функциями 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

Все примеры кода и фрагменты кода включены в набор для обучения веб-лагерей.

Задачи

В этой практической лаборатории вы узнаете, как:

  • Использование строго типизированных выражений привязки данных
  • Использование новых функций привязки модели в веб-формы
  • Использование поставщиков значений для сопоставления данных страницы с методами программной части
  • Использование заметок данных для проверки ввода пользователем
  • Использование ненавязчивой проверки на стороне клиента с помощью jQuery в веб-формы
  • Реализация детализации проверки запроса
  • Реализация асинхронной обработки страниц в веб-формы

Необходимые компоненты

Для выполнения этой лаборатории необходимо выполнить следующие элементы:

Настройка

Установка фрагментов кода

Для удобства большая часть кода, который вы будете управлять вместе с этой лабораторией, доступна как фрагменты кода Visual Studio. Чтобы установить фрагменты кода, выполните файл .\Source\Setup\CodeSnippets.vsi .

Если вы не знакомы с фрагментами кода Visual Studio Code и хотите узнать, как их использовать, вы можете обратиться к приложению из этого документа "Приложение C: использование фрагментов кода".

Упражнения

Эта практическая лаборатория включает в себя следующие упражнения:

  1. Упражнение 1. Привязка модели в ASP.NET веб-формы
  2. Упражнение 2. Проверка данных
  3. Упражнение 3. Асинхронная обработка страниц в ASP.NET веб-формы

Примечание.

Каждое упражнение сопровождается папкой End , содержащей полученное решение, которое необходимо получить после выполнения упражнений. Это решение можно использовать в качестве руководства, если вам нужна дополнительная помощь в работе с упражнениями.

Предполагаемое время выполнения этой лаборатории: 60 минут.

Упражнение 1. Привязка модели в ASP.NET веб-формы

Новая версия ASP.NET веб-формы представляет ряд улучшений, ориентированных на улучшение работы с данными. В этом упражнении вы узнаете о строго типизированных элементах управления данными и привязке модели.

Задача 1. Использование строго типизированных привязок данных

В этой задаче вы обнаружите новые строго типизированные привязки, доступные в ASP.NET 4.5.

  1. Откройте решение Begin, расположенное в папке Source/Ex1-ModelBinding/Begin/.

    1. Прежде чем продолжить, необходимо скачать некоторые отсутствующие пакеты NuGet. Для этого щелкните меню "Проект" и выберите "Управление пакетами NuGet".

    2. В диалоговом окне "Управление пакетами NuGet" нажмите кнопку "Восстановить", чтобы скачать отсутствующие пакеты.

    3. Наконец, создайте решение, нажав кнопку "Сборка решения сборки". |

      Примечание.

      Одним из преимуществ использования NuGet является то, что вам не нужно отправлять все библиотеки в проекте, уменьшая размер проекта. С помощью NuGet Power Tools, указав версии пакетов в файле Packages.config, вы сможете скачать все необходимые библиотеки при первом запуске проекта. Поэтому эти действия необходимо выполнить после открытия существующего решения из этой лаборатории.

  2. Откройте страницу Customers.aspx . Поместите ненумерованный список в основной элемент управления и включите элемент управления повторителя внутри для перечисления каждого клиента. Задайте имя повторителя клиентамRepeater , как показано в следующем коде.

    В предыдущих версиях веб-формы при использовании привязки данных для выдачи значения элемента в объекте, к которым выполняется привязка данных, вы будете использовать выражение привязки данных вместе с вызовом метода 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>
    
  3. Откройте файл Customers.aspx.cs.

  4. Добавьте следующую инструкцию using.

    using System.Linq;
    
  5. В методе 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 для создания и доступа к базе данных. В следующем коде клиентыRepeater привязаны к материализованному запросу, который возвращает всех клиентов из базы данных.

  6. Нажмите клавишу F5 , чтобы запустить решение и перейдите на страницу "Клиенты" , чтобы увидеть повторитель в действии. Так как решение использует CodeFirst, база данных будет создана и заполнена в локальном экземпляре SQL Express при запуске приложения.

    Перечисление клиентов с повтором

    Перечисление клиентов с повтором

    Примечание.

    В Visual Studio 2012 СЛУЖБА IIS Express является сервером веб-разработки по умолчанию.

  7. Закройте браузер и вернитесь в Visual Studio.

  8. Теперь замените реализацию для использования строго типизированных привязок. Откройте страницу 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 позволяет объявлять тип данных, к которым будет привязан элемент управления, и позволяет использовать строго типизированную привязку внутри элемента управления с привязкой к данным.

  9. Замените содержимое 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 в строго типизированной привязке

    Поддержка IntelliSense в строго типизированной привязке

  10. Нажмите клавишу F5 , чтобы запустить решение и перейдите на страницу "Клиенты", чтобы убедиться, что изменения работают должным образом.

    Перечисление сведений о клиенте

    Перечисление сведений о клиенте

  11. Закройте браузер и вернитесь в Visual Studio.

Задача 2. Введение привязки модели в веб-формы

В предыдущих версиях ASP.NET веб-формы, когда вы хотите выполнить двустороннюю привязку данных, извлечение и обновление данных, необходимо использовать объект Источника данных. Это может быть источник данных объекта, источник данных SQL, источник данных LINQ и т. д. Однако если в вашем сценарии требуется пользовательский код для обработки данных, необходимо использовать источник данных объекта, и это привело к некоторым недостаткам. Например, необходимо избежать сложных типов и обрабатывать исключения при выполнении логики проверки.

В новой версии ASP.NET веб-формы элементы управления с привязкой к данным поддерживают привязку модели. Это означает, что можно указать методы выбора, обновления, вставки и удаления непосредственно в элементе управления, привязанном к данным, для вызова логики из файла кода или из другого класса.

Чтобы узнать об этом, вы будете использовать GridView для перечисления категорий продуктов с помощью нового атрибута SelectMethod . Этот атрибут позволяет указать метод получения данных GridView.

  1. Откройте страницу 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>
    
  2. Используйте новый атрибут 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>
    
  3. Откройте файл кода Products.aspx.cs и добавьте следующие инструкции using.

    (Фрагмент кода — веб-формы Lab — Ex01 — пространства имен)

    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;
    using System.Linq;
    using WebFormsLab.Model;
    
  4. Добавьте частный член в класс Products и назначьте новый экземпляр ProductsContext. Это свойство будет хранить контекст данных Entity Framework, позволяющий подключаться к базе данных.

    public partial class Products : System.Web.UI.Page
    {
        private ProductsContext db = new ProductsContext();
        ...
    
  5. Создайте метод GetCategories для получения списка категорий с помощью LINQ. Запрос будет содержать свойство Products , чтобы GridView отображал количество продуктов для каждой категории. Обратите внимание, что метод возвращает необработанный объект IQueryable, представляющий запрос, который будет выполняться позже в жизненном цикле страницы.

    (Фрагмент кода — лаборатория веб-формы — Ex01 — GetCategories)

    public IQueryable<Category> GetCategories()
    {
      var query = this.db.Categories
        .Include(c => c.Products);
    
      return query;
    }
    

    Примечание.

    В предыдущих версиях ASP.NET веб-формы включение сортировки и разбиения по страницам с помощью собственной логики репозитория в контексте источника данных объекта, необходимо написать собственный пользовательский код и получить все необходимые параметры. Теперь, когда методы привязки данных могут возвращать IQueryable, и это представляет запрос, который по-прежнему выполняется, ASP.NET может заботиться об изменении запроса, чтобы добавить правильные параметры сортировки и разбиения по страницам.

  6. Нажмите клавишу F5 , чтобы начать отладку сайта и перейти на страницу "Продукты". Вы увидите, что GridView заполняется категориями, возвращаемыми методом GetCategories.

    Заполнение GridView с помощью привязки модели

    Заполнение GridView с помощью привязки модели

  7. Нажмите клавиши SHIFT+F5 Stop debugging.

Задача 3. Поставщики значений в привязке модели

Привязка модели не только позволяет указывать пользовательские методы для работы с данными непосредственно в элементе управления с привязкой к данным, но и позволяет сопоставлять данные со страницы с параметрами из этих методов. В параметре метода можно использовать атрибуты поставщика значений для указания источника данных значения. Например:

  • Элементы управления на странице
  • Значения строки запроса
  • Просмотреть данные
  • Состояние сеанса
  • Файлы cookie
  • Опубликованные данные формы
  • Просмотр состояния
  • Поставщики настраиваемых значений также поддерживаются

Если вы использовали ASP.NET MVC 4, вы заметите, что поддержка привязки модели аналогична. Действительно, эти функции были взяты из ASP.NET MVC и перемещены в сборку System.Web, чтобы использовать их на веб-формы также.

В этой задаче вы обновите GridView, чтобы отфильтровать результаты по количеству продуктов для каждой категории, получая параметр фильтра с привязкой модели.

  1. Вернитесь на страницу Products.aspx .

  2. В верхней части 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/>
    
  3. Добавьте 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>
    
  4. Откройте Products.aspx.cs программной части и добавьте следующую инструкцию using.

    using System.Web.ModelBinding;
    
  5. Измените метод GetCategories , чтобы получить целочисленный аргумент minProductsCount и отфильтровать возвращаемые результаты. Для этого замените метод следующим кодом.

    (Фрагмент кода — веб-формы лаборатории - 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], вы можете использовать другие поставщики привязки модели в параметрах метода. Некоторые из них перечислены в этой статье.

  6. Нажмите клавишу F5 , чтобы начать отладку сайта и перейти на страницу "Продукты". Выберите ряд продуктов в раскрывающемся списке и обратите внимание, как теперь обновляется GridView.

    Фильтрация GridView со значением раскрывающегося списка

    Фильтрация GridView со значением раскрывающегося списка

  7. Остановите отладку.

Задача 4. Использование привязки модели для фильтрации

В этой задаче вы добавите второй дочерний элемент GridView, чтобы отобразить продукты в выбранной категории.

  1. Откройте страницу Products.aspx и обновите категории GridView, чтобы автоматически создать кнопку "Выбрать".

    <asp:GridView ID="categoriesGrid" runat="server"
      AutoGenerateColumns="false"
      ItemType="WebFormsLab.Model.Category" DataKeyNames="CategoryId"
      SelectMethod="GetCategories"
      AutoGenerateSelectButton="true">
    
  2. Добавьте второй элемент GridView с именем productsGrid в нижней части экрана. Задайте для ItemType значение WebFormsLab.Model.Product, DataKeyNamesProductId и SelectMethodGetProducts. Задайте для 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>
    
  3. Откройте файл Products.aspx.cs кода программной части. Реализуйте метод GetProducts для получения идентификатора категории из gridView категории и фильтрации продуктов. Привязка модели задает значение параметра с помощью выбранной строки в категорииGrid. Так как имя аргумента и имя элемента управления не совпадают, следует указать имя элемента управления в поставщике значений элемента управления.

    (Фрагмент кода — лаборатория веб-формы — Ex01 — GetProducts)

    public IEnumerable<Product> GetProducts([Control("categoriesGrid")]int? categoryId)
    {
        return this.db.Products.Where(p => p.CategoryId == categoryId);
    }
    

    Примечание.

    Этот подход упрощает модульное тестирование этих методов. В контексте модульного теста, где веб-формы не выполняется, атрибут [Control] не будет выполнять какое-либо определенное действие.

  4. Откройте страницу 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>
    
  5. Откройте код страницы ProductDetails.aspx и замените метод SelectProduct следующим кодом.

    (Фрагмент кода — веб-формы Lab — Ex01 — Метод SelectProduct)

    public Product SelectProduct([QueryString]int? productId)
    {
        return this.db.Products.Find(productId);
    }
    

    Примечание.

    Обратите внимание, что атрибут [QueryString] используется для заполнения параметра метода из параметра productId в строке запроса.

  6. Нажмите клавишу F5 , чтобы начать отладку сайта и перейти на страницу "Продукты". Выберите любую категорию из категорий GridView и обратите внимание, что продукт GridView обновлен.

    Отображение продуктов из выбранной категории

    Отображение продуктов из выбранной категории

  7. Щелкните ссылку "Вид " на продукте, чтобы открыть страницу ProductDetails.aspx.

    Обратите внимание, что страница извлекается из строки запроса с помощью параметра SelectMethod с помощью параметра ProductId.

    Просмотр сведений о продукте

    Просмотр сведений о продукте

    Примечание.

    Возможность ввода описания HTML будет реализована в следующем упражнении.

Задача 5. Использование привязки модели для операций обновления

В предыдущей задаче вы использовали привязку модели главным образом для выбора данных, в этой задаче вы узнаете, как использовать привязку модели в операциях обновления.

Вы обновите категории GridView, чтобы позволить пользователям обновлять категории.

  1. Откройте страницу 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 определяет, какие члены однозначно определяют объект, привязанный к модели, и, следовательно, которые являются параметрами, которые метод обновления должен получать по крайней мере.

  2. Откройте файл кода Products.aspx.cs и реализуйте метод UpdateCategory. Метод должен получить идентификатор категории, чтобы загрузить текущую категорию, заполнить значения из GridView, а затем обновить категорию.

    (Фрагмент кода — веб-формы 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 для проверки данных, введенных пользователем при редактировании объекта.

  3. Запустите сайт и перейдите на страницу "Продукты". Изменение категории. Введите новое имя и нажмите кнопку "Обновить ", чтобы сохранить изменения.

    Изменение категорий

    Изменение категорий

Упражнение 2. Проверка данных

В этом упражнении вы узнаете о новых функциях проверки данных в ASP.NET 4.5. Вы узнаете о новых ненавязчивых функциях проверки в веб-формы. Вы будете использовать заметки данных в классах модели приложения для проверки ввода пользователей, и, наконец, вы узнаете, как включить или отключить проверку запросов для отдельных элементов управления на странице.

Задача 1. Ненавязчивая проверка

Формы с сложными данными, включая проверяющие элементы, как правило, создают слишком много кода JavaScript на странице, что может представлять около 60% кода. С включенной ненавязчивой проверкой код HTML будет выглядеть более чистым и идионерным.

В этом разделе описано, как включить ненавязчивую проверку в ASP.NET для сравнения HTML-кода, созданного обеими конфигурациями.

  1. Откройте Visual Studio 2012 и откройте решение Begin, расположенное в папке Source\Ex2-Validation\Begin этой лаборатории. Кроме того, можно продолжить работу над существующим решением из предыдущего упражнения.

    1. Если вы открыли предоставленное решение Begin , перед продолжением необходимо скачать некоторые отсутствующие пакеты NuGet. Для этого в Обозреватель решений щелкните проект WebFormsLab Manage NuGet Packages.

    2. В диалоговом окне "Управление пакетами NuGet" нажмите кнопку "Восстановить", чтобы скачать отсутствующие пакеты.

    3. Наконец, создайте решение, нажав кнопку "Сборка решения сборки". |

      Примечание.

      Одним из преимуществ использования NuGet является то, что вам не нужно отправлять все библиотеки в проекте, уменьшая размер проекта. С помощью NuGet Power Tools, указав версии пакетов в файле Packages.config, вы сможете скачать все необходимые библиотеки при первом запуске проекта. Поэтому эти действия необходимо выполнить после открытия существующего решения из этой лаборатории.

  2. Нажмите клавишу F5 , чтобы запустить веб-приложение. Перейдите на страницу "Клиенты" и щелкните ссылку "Добавить нового клиента ".

  3. Щелкните правой кнопкой мыши страницу браузера и выберите пункт "Просмотреть источник" , чтобы открыть HTML-код, созданный приложением.

    Отображение HTML-кода страницы

    Отображение HTML-кода страницы

  4. Прокрутите исходный код страницы и обратите внимание, что ASP.NET ввели код JavaScript и проверяющие данные на странице для выполнения проверок и отображения списка ошибок.

    Проверка кода JavaScript на странице CustomerDetails

    Проверка кода JavaScript на странице CustomerDetails

  5. Закройте браузер и вернитесь в Visual Studio.

  6. Теперь вы включите ненавязчивую проверку. Откройте Web.Config и найдите ключ ValidationSettings:UntrusiveValidationMode в разделе AppSettings. Задайте для параметра "Ключ" значение WebForms.

    <configuration>
      ...
      <appSettings>
        <add key="aspnet:uselegacysynchronizationcontext" value="false" />
        <add key="ValidationSettings:UnobtrusiveValidationMode" value="WebForms"/>
    

    Примечание.

    Это свойство также можно задать в событии "Page_Load", если вы хотите включить ненавязчивую проверку только для некоторых страниц.

  7. Откройте CustomerDetails.aspx и нажмите клавишу F5 , чтобы запустить веб-приложение.

  8. Нажмите клавишу F12, чтобы открыть средства разработчика IE. После открытия средств разработчика выберите вкладку скрипта. Выберите CustomerDetails.aspx в меню и обратите внимание, что скрипты, необходимые для запуска jQuery на странице, были загружены в браузер с локального сайта.

    Загрузка файлов JavaScript jQuery непосредственно с локального сервера IIS

    Загрузка файлов JavaScript jQuery непосредственно с локального сервера IIS

  9. Закройте браузер, чтобы вернуться в Visual Studio. Снова откройте файл Site.Master и найдите ScriptManager. Добавьте свойство EnableCdn атрибута со значением True. Это приведет к загрузке jQuery из URL-адреса в Интернете, а не из URL-адреса локального сайта.

  10. Откройте CustomerDetails.aspx в Visual Studio. Нажмите клавишу F5, чтобы запустить сайт. После открытия Internet Explorer нажмите клавишу F12, чтобы открыть средства разработчика. Выберите вкладку "Скрипт" , а затем просмотрите раскрывающийся список. Обратите внимание, что файлы JavaScript jQuery больше не загружаются с локального сайта, а не из сети jQuery CDN.

    Загрузка файлов JavaScript jQuery из CDN

    Загрузка файлов JavaScript jQuery из CDN

  11. Снова откройте исходный код HTML-страницы с помощью параметра "Просмотр источника" в браузере. Обратите внимание, что включение ненавязчивой проверки ASP.NET заменило внедренный код JavaScript данными *атрибутами.

    Ненавязчивый код проверки

    Ненавязчивый код проверки

    Примечание.

    В этом примере вы узнали, как сводка проверки с заметками данных была упрощена до нескольких строк HTML и JavaScript. Ранее, без ненавязчивой проверки, чем больше элементов управления проверки вы добавили, тем больше будет увеличиваться код проверки JavaScript.

Задача 2. Проверка модели с помощью заметок данных

ASP.NET 4.5 содержит проверку заметок данных для веб-формы. Вместо управления проверкой для каждого входного данных теперь можно определить ограничения в классах моделей и использовать их во всех веб-приложениях. В этом разделе вы узнаете, как использовать заметки данных для проверки новой или редактирования формы клиента.

  1. Откройте страницу CustomerDetail.aspx . Обратите внимание, что имя клиента и второе имя в разделах EditItemTemplate и InsertItemTemplate проверяются с помощью элементов управления RequiredFieldValidator. Каждый проверяющий элемент связан с определенным условием, поэтому необходимо включить столько проверяющих элементов, сколько условий.

  2. Добавьте заметки данных для проверки класса модели 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)]: две заметки в одной строке.

    Вы также можете определить собственные сообщения об ошибках в каждом атрибуте.

  3. Откройте 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 %>' />
            &nbsp;<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 %>' />
              &nbsp;<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 %>' />           
         &nbsp;<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 %>' />
         &nbsp;<asp:RequiredFieldValidator runat="server" ControlToValidate="lastName" ErrorMessage="Please enter a value for Last Name" ForeColor="Red" />
        </p>
      ...
    

    Примечание.

    Одним из преимуществ использования заметок данных является то, что логика проверки не дублируется на страницах приложения. Вы определяете его один раз в модели и используете его на всех страницах приложения, которые управляют данными.

  4. Откройте 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())
            {
                ...
    
  5. Добавьте элемент управления 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. Эти ошибки возникают из проверки заметок данных.

  6. Нажмите клавишу F5 , чтобы запустить веб-приложение. Заполните форму с некоторыми ошибочными значениями и нажмите кнопку "Сохранить ", чтобы выполнить проверку. Обратите внимание на сводку об ошибке внизу.

    Проверка с помощью заметок данных

    Проверка с помощью заметок данных

Задача 3. Обработка ошибок пользовательской базы данных с помощью ModelState

В предыдущей версии веб-формы обработка ошибок базы данных, таких как слишком длинная строка или нарушение уникального ключа, может привести к возникновению исключений в коде репозитория, а затем обрабатывать исключения в коде, чтобы отобразить ошибку. Для выполнения чего-то относительно простого требуется большое количество кода.

В веб-формы 4.5 объект ModelState можно использовать для отображения ошибок на странице из модели или базы данных в согласованном режиме.

В этой задаче вы добавите код для правильной обработки исключений базы данных и отобразите пользователю соответствующее сообщение с помощью объекта ModelState.

  1. Пока приложение по-прежнему работает, попробуйте обновить имя категории с помощью повторяющегося значения.

    Обновление категории с повторяющимся именем

    Обновление категории с повторяющимся именем

    Обратите внимание, что исключение возникает из-за ограничения unique столбца CategoryName .

    Исключение для повторяющихся имен категорий

    Исключение для повторяющихся имен категорий

  2. Остановите отладку. В файле кода Products.aspx.cs обновите метод UpdateCategory для обработки исключений, создаваемых базой данных. Вызов метода SaveChanges() и добавление ошибки в объект ModelState.

    Новый метод TryUpdateModel обновляет объект категории, полученный из базы данных, с помощью данных формы, предоставленных пользователем.

    (Фрагмент кода — веб-формы лаборатории — ex02 — ошибки обработки обновленияCategory)

    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 и проверить, является ли первопричина нарушением ограничения уникального ключа.

  3. Откройте Products.aspx и добавьте элемент управления ValidationSummary под категориями GridView, чтобы отобразить список ошибок модели.

    <asp:GridView ID="categoriesGrid" runat="server"
      ...
    </asp:GridView>
    
    <asp:ValidationSummary ID="ValidationSummary1" runat="server" ShowModelStateErrors="true" />
    
    <h3>Products</h3>
    
  4. Запустите сайт и перейдите на страницу "Продукты". Попробуйте обновить имя категории с помощью повторяющегося значения.

    Обратите внимание, что исключение было обработано, и сообщение об ошибке отображается в элементе управления ValidationSummary .

    Ошибка повторяемой категории

    Ошибка повторяемой категории

Задача 4. Проверка запроса в ASP.NET веб-формы 4.5

Функция проверки запросов в ASP.NET обеспечивает определенный уровень защиты по умолчанию от атак XSS. В предыдущих версиях ASP.NET проверка запросов была включена по умолчанию и может быть отключена только для всей страницы. С помощью новой версии ASP.NET веб-формы теперь можно отключить проверку запроса для одного элемента управления, выполнить отложенную проверку запросов или получить доступ к данным запроса без проверки (будьте осторожны, если это сделать!).

  1. Нажмите клавиши CTRL+F5 , чтобы запустить сайт без отладки и перейти на страницу "Продукты". Выберите категорию и щелкните ссылку "Изменить " для любого из продуктов.

  2. Введите описание, содержащее потенциально опасное содержимое, например теги HTML. Обратите внимание на исключение, возникшее из-за проверки запроса.

    Редактирование продукта с потенциально опасным содержимым

    Редактирование продукта с потенциально опасным содержимым

    Исключение, возникающее из-за проверки запроса

    Исключение, возникающее из-за проверки запроса

  3. Закройте страницу и нажмите клавиши SHIFT+F5 , чтобы остановить отладку.

  4. Откройте страницу ProductDetails.aspx и найдите текстовое поле "Описание ".

  5. Добавьте новое свойство ValidateRequestMode в TextBox и задайте для нее значение Disabled.

    Новый атрибут ValidateRequestMode позволяет отключить проверку запроса детализированно для каждого элемента управления. Это полезно, если вы хотите использовать входные данные, которые могут получать HTML-код, но хотите сохранить проверку для остальной части страницы.

    <p>
      <asp:TextBox runat="server" ID="Description" TextMode="MultiLine" 
                Cols="60" Rows="8" Text='<%# BindItem.Description %>' 
        ValidateRequestMode="Disabled" />
    </p>
    
  6. Нажмите клавишу F5 , чтобы запустить веб-приложение. Откройте страницу редактирования продукта еще раз и заполните описание продукта, включая html-теги. Обратите внимание, что теперь можно добавить HTML-содержимое в описание.

    Проверка запроса отключена для описания продукта

    Проверка запроса отключена для описания продукта

    Примечание.

    В рабочем приложении необходимо удалить html-код, введенный пользователем, чтобы убедиться, что введены только безопасные HTML-теги (например, <нет тегов скрипта> ). Для этого можно использовать библиотеку Microsoft Web Protection.

  7. Снова измените продукт. Введите 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 автоматически используют новые подпрограммы кодирования.

  8. ASP.NET проверка запроса 4.5 также поддерживает неподверенный доступ к данным запроса. ASP.NET 4.5 добавляет новое свойство коллекции в объект HttpRequest с именем Unvalidated. При переходе по протоколу HttpRequest.Unvalidated у вас есть доступ ко всем общим частям данных запроса, включая Формы, QueryStrings, Файлы cookie, URL-адреса и т. д.

    Объект Request.Unvalidated

    Объект Request.Unvalidated

    Примечание.

    Используйте свойство HttpRequest.Unvalidated с осторожностью! Убедитесь, что вы тщательно выполняете пользовательскую проверку в необработанных данных запроса, чтобы убедиться, что опасный текст не споткнут и отрисовывается обратно в неуказанные клиенты!

Упражнение 3. Асинхронная обработка страниц в ASP.NET веб-формы

В этом упражнении вы узнаете о новых функциях асинхронной обработки страниц в ASP.NET веб-формы.

Задача 1. Обновление страницы сведений о продукте для отправки и отображения изображений

В этой задаче вы обновите страницу сведений о продукте, чтобы разрешить пользователю указать URL-адрес изображения для продукта и отобразить его в режиме только для чтения. Вы создадите локальную копию указанного образа, скачав его синхронно. В следующей задаче вы обновите эту реализацию, чтобы она работала асинхронно.

  1. Откройте Visual Studio 2012 и загрузите решение Begin, расположенное в папке Source\Ex3-Async\Begin из папки этой лаборатории. Кроме того, можно продолжить работу над существующим решением из предыдущих упражнений.

    1. Если вы открыли предоставленное решение Begin , перед продолжением необходимо скачать некоторые отсутствующие пакеты NuGet. Для этого в Обозреватель решений щелкните проект WebFormsLab и выберите "Управление пакетами NuGet".

    2. В диалоговом окне "Управление пакетами NuGet" нажмите кнопку "Восстановить", чтобы скачать отсутствующие пакеты.

    3. Наконец, создайте решение, нажав кнопку "Сборка решения сборки". |

      Примечание.

      Одним из преимуществ использования NuGet является то, что вам не нужно отправлять все библиотеки в проекте, уменьшая размер проекта. С помощью NuGet Power Tools, указав версии пакетов в файле Packages.config, вы сможете скачать все необходимые библиотеки при первом запуске проекта. Поэтому эти действия необходимо выполнить после открытия существующего решения из этой лаборатории.

  2. Откройте источник страницы 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" />&nbsp;
                    <asp:HyperLink NavigateUrl="~/Products.aspx" Text="Back" runat="server" />
              </p>
         </fieldset>
    </ItemTemplate>
    
  3. Добавьте поле, чтобы указать 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>
    
  4. Откройте файл ProductDetails.aspx.cs кода программной части и добавьте следующие директивы пространства имен.

    (Фрагмент кода — веб-формы Lab — Ex03 — пространства имен)

    using System.IO;
    using System.Net;
    using System.Web;
    
  5. Создайте метод 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));
            }
        }
    }
    
  6. Обновите метод UpdateProduct, чтобы вызвать метод UpdateProductImage.

    (Фрагмент кода — веб-формы 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();
        }
    }
    
  7. Запустите приложение и попытайтесь отправить образ для продукта.

    Настройка образа для продукта

    Настройка образа для продукта

Задача 2. Добавление асинхронной обработки на страницу сведений о продукте

В этой задаче вы обновите страницу сведений о продукте, чтобы она работала асинхронно. Вы улучшите длинную задачу — процесс скачивания изображений с помощью ASP.NET асинхронной обработки страницы 4.5.

Асинхронные методы в веб-приложениях можно использовать для оптимизации способа использования пулов потоков ASP.NET. В ASP.NET существует ограниченное количество потоков в пуле потоков для участия в запросах, поэтому, когда все потоки заняты, ASP.NET начинает отклонять новые запросы, отправляет сообщения об ошибках приложения и делает сайт недоступным.

Трудоемкие операции на веб-сайте являются отличными кандидатами на асинхронное программирование, так как они занимают назначенный поток в течение длительного времени. Это включает длительные запросы, страницы с большим количеством различных элементов и страниц, требующих автономных операций, таких как запрос базы данных или доступ к внешнему веб-серверу. Преимущество заключается в том, что если вы используете асинхронные методы для этих операций, в то время как страница обрабатывается, поток освобождается и возвращается в пул потоков и может использоваться для участия в новом запросе страницы. Это означает, что страница начнет обработку в одном потоке из пула потоков и может завершить обработку в другой, после завершения асинхронной обработки.

  1. Откройте страницу 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" %>
    
  2. Добавьте метку в нижней части страницы, чтобы отобразить сведения о потоках, на которых выполняется страница.

    <EmptyDataTemplate>Product not found</EmptyDataTemplate>
      </asp:FormView>
    
      <asp:Label ID="threadsMessageLabel" runat="server" />
    </asp:Content>
    
  3. Откройте ProductDetails.aspx.cs и добавьте следующие директивы пространства имен.

    (Фрагмент кода — веб-формы лаборатории — Ex03 — пространства имен 2)

    using System.Web.UI;
    using System.Threading;
    
  4. Измените метод UpdateProductImage , чтобы скачать изображение с асинхронной задачей. Вы замените метод WebClient DownloadFile методом DownloadFileTaskAsync и включите ключевое слово await.

    (Фрагмент кода — веб-формы 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.

  5. Добавьте код для отображения потоков, на которых запущен и завершен выполнение кода. Для этого обновите метод UpdateProductImage со следующим кодом.

    (Фрагмент кода — веб-формы лаборатории — 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);
        }));
      }
    }
    
  6. Откройте файл конфигурации web.config веб-сайта. Добавьте следующую переменную appSetting.

    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
    
  7. Нажмите клавишу F5 , чтобы запустить приложение и отправить изображение для продукта. Обратите внимание, что идентификатор потоков, на котором запущен и завершен код, может отличаться. Это связано с тем, что асинхронные задачи выполняются в отдельном потоке из пула потоков ASP.NET. По завершении задачи ASP.NET помещает задачу обратно в очередь и назначает любой из доступных потоков.

    Асинхронное скачивание образа

    Асинхронное скачивание образа

Примечание.

Кроме того, вы можете развернуть это приложение в Azure в следующем приложении B. Публикация приложения ASP.NET MVC 4 с помощью веб-развертывания.


Итоги

В этой практической лаборатории рассматриваются и демонстрируются следующие понятия:

  • Использование строго типизированных выражений привязки данных
  • Использование новых функций привязки модели в веб-формы
  • Использование поставщиков значений для сопоставления данных страницы с методами программной части
  • Использование заметок данных для проверки ввода пользователем
  • Использование ненавязчивой проверки на стороне клиента с помощью jQuery в веб-формы
  • Реализация детализации проверки запроса
  • Реализация асинхронной обработки страниц в веб-формы

Приложение A. Установка Visual Studio Express 2012 для Интернета

Вы можете установить Microsoft Visual Studio Express 2012 для Интернета или другой версии Express с помощью установщика веб-платформа Майкрософт. Ниже приведены инструкции по установке Visual Studio Express 2012 для Интернета с помощью установщика веб-платформа Майкрософт.

  1. Перейдите к [https://go.microsoft.com/?linkid=9810169](https://go.microsoft.com/?linkid=9810169). Кроме того, если вы уже установили установщик веб-платформы, его можно открыть и найти в продукте Visual Studio Express 2012 для Интернета с помощью пакета SDK Для Azure.

  2. Нажмите кнопку "Установить сейчас". Если у вас нет установщика веб-платформы, вы будете перенаправлены, чтобы скачать и установить его сначала.

  3. После открытия установщика веб-платформы нажмите кнопку "Установить ", чтобы запустить настройку.

    Установка Visual Studio Express

    Установка Visual Studio Express

  4. Прочитайте все лицензии и условия продуктов и нажмите кнопку "Принять ", чтобы продолжить.

    Принятие условий лицензии

    Принятие условий лицензии

  5. Дождитесь завершения процесса загрузки и установки.

    Ход выполнения установки

    Ход установки

  6. После завершения установки нажмите кнопку "Готово".

    Завершена установка

    Завершена установка

  7. Нажмите кнопку " Выйти" , чтобы закрыть установщик веб-платформы.

  8. Чтобы открыть Visual Studio Express для Интернета, перейдите на начальный экран и начните писать "VS Express", а затем щелкните элемент VS Express для веб-страницы.

    Плитка VS Express для веб-сайта

    Плитка VS Express для веб-сайта

Приложение B. Публикация приложения MVC 4 ASP.NET с помощью веб-развертывания

В этом приложении показано, как создать веб-сайт на портале Azure и опубликовать приложение, полученное после лаборатории, используя функцию публикации веб-развертывания, предоставляемую Azure.

Задача 1. Создание веб-сайта на портале Azure

  1. Перейдите на портал управления Azure и войдите с помощью учетных данных Майкрософт, связанных с подпиской.

    Примечание.

    С помощью Azure можно разместить 10 ASP.NET веб-сайты бесплатно, а затем масштабировать по мере роста трафика. Вы можете зарегистрироваться здесь.

    Вход в Windows портал Azure

    Вход на портал

  2. Нажмите кнопку "Создать" на панели команд.

    Создание нового веб-сайта

    Создание нового веб-сайта

  3. Щелкните "Вычислительный | веб-сайт". Затем нажмите кнопку быстрого создания . Укажите доступный URL-адрес для нового веб-сайта и нажмите кнопку "Создать веб-сайт".

    Примечание.

    Azure — это узел веб-приложения, работающего в облаке, который можно управлять ими. Параметр быстрого создания позволяет развернуть завершенное веб-приложение в Azure за пределами портала. Он не включает шаги по настройке базы данных.

    Создание нового веб-сайта с помощью быстрого создания

    Создание нового веб-сайта с помощью быстрого создания

  4. Дождитесь создания нового веб-сайта .

  5. После создания веб-сайта щелкните ссылку в столбце URL-адреса . Убедитесь, что новый веб-сайт работает.

    Просмотр нового веб-сайта

    Просмотр нового веб-сайта

    Запущенный веб-сайт

    Запущенный веб-сайт

  6. Вернитесь на портал и щелкните имя веб-сайта в столбце "Имя ", чтобы отобразить страницы управления.

    Открытие страниц управления веб-сайтами

    Открытие страниц управления веб-сайтами

  7. На странице "Панель мониторинга" в разделе быстрого просмотра щелкните ссылку "Скачать профиль публикации".

    Примечание.

    Профиль публикации содержит все сведения, необходимые для публикации веб-приложения в Azure для каждого включенного метода публикации. Профиль публикации содержит URL-адреса, учетные данные пользователя и строки базы данных, необходимые для подключения к каждой конечной точке, для которой включен метод публикации. Microsoft WebMatrix 2, Microsoft Visual Studio Express для Web и Microsoft Visual Studio 2012 поддерживают чтение профилей публикации для автоматизации настройки этих программ для публикации веб-приложений в Azure.

    Скачивание профиля публикации веб-сайта

    Скачивание профиля публикации веб-сайта

  8. Скачайте файл профиля публикации в известное расположение. Далее в этом упражнении вы узнаете, как использовать этот файл для публикации веб-приложения в Azure из Visual Studio.

    Сохранение файла профиля публикации

    Сохранение файла профиля публикации

Задача 2. Настройка сервера базы данных

Если приложение использует базы данных SQL Server, вам потребуется создать сервер База данных SQL. Если вы хотите развернуть простое приложение, которое не использует SQL Server, может пропустить эту задачу.

  1. Для хранения базы данных приложения потребуется сервер База данных SQL. Вы можете просмотреть серверы База данных SQL из подписки на портале управления Azure на панели мониторинга Сервера баз данных | Sql Server | . Если у вас нет сервера, его можно создать с помощью кнопки "Добавить " на панели команд. Запишите имя сервера и URL-адрес, имя входа администратора и пароль, так как они будут использоваться в следующих задачах. Пока не создайте базу данных, так как она будет создана на более позднем этапе.

    панель мониторинга сервера База данных SQL

    панель мониторинга сервера База данных SQL

  2. В следующей задаче вы протестируете подключение к базе данных из Visual Studio, по этой причине необходимо включить локальный IP-адрес в список разрешенных IP-адресов сервера. Для этого нажмите кнопку "Настроить", выберите IP-адрес из текущего IP-адреса клиента и вставьте его в текстовые поля Кнопка add-client-ip-address-ok-button "Начальный IP-адрес" и "Конечный IP-адрес".

    Добавление IP-адреса клиента

    Добавление IP-адреса клиента

  3. После добавления IP-адреса клиента в список разрешенных IP-адресов нажмите кнопку "Сохранить", чтобы подтвердить изменения.

    Подтверждение изменений

    Подтверждение изменений

Задача 3. Публикация приложения MVC 4 ASP.NET с помощью веб-развертывания

  1. Вернитесь к решению MVC 4 ASP.NET. В Обозреватель решений щелкните правой кнопкой мыши проект веб-сайта и выберите "Опубликовать".

    Публикация приложения

    Публикация веб-сайта

  2. Импортируйте профиль публикации, сохраненный в первой задаче.

    Импорт профиля публикации

    Импорт профиля публикации

  3. Нажмите кнопку "Проверить подключение". После завершения проверки нажмите кнопку "Далее".

    Примечание.

    После завершения проверки появится зеленая галочка рядом с кнопкой "Проверить подключение".

    Проверка подключения

    Проверка подключения

  4. На странице "Параметры" в разделе "Базы данных" нажмите кнопку рядом с текстовым полем подключения к базе данных (т. е. DefaultConnection).

    Конфигурация веб-развертывания

    Конфигурация веб-развертывания

  5. Настройте подключение к базе данных следующим образом:

    • В поле "Имя сервера" введите URL-адрес сервера База данных SQL с помощью префикса TCP.

    • В поле "Имя пользователя" введите имя входа администратора сервера.

    • Введите пароль для входа администратора сервера.

    • Введите новое имя базы данных.

      Настройка конечного строка подключения

      Настройка конечного строка подключения

  6. Затем нажмите кнопку ОК. При появлении запроса на создание базы данных нажмите кнопку "Да".

    Создание базы данных

    Создание базы данных

  7. В текстовом поле "Подключение по умолчанию" отображается строка подключения, используемое для подключения к База данных SQL в Azure. Затем нажмите кнопку Далее.

    Строка подключения, указывающая на База данных SQL

    Строка подключения, указывающая на База данных SQL

  8. На странице предварительного просмотра нажмите кнопку "Опубликовать".

    Публикация веб-приложения

    Публикация веб-приложения

  9. После завершения процесса публикации браузер по умолчанию откроет опубликованный веб-сайт.

Приложение C. Использование фрагментов кода

При использовании фрагментов кода у вас есть весь код, который вам нужен на пальцах. В документе лаборатории вы узнаете, когда их можно использовать, как показано на следующем рисунке.

Использование фрагментов кода Visual Studio для вставки кода в проект

Использование фрагментов кода Visual Studio для вставки кода в проект

Добавление фрагмента кода с помощью клавиатуры (только для C#)

  1. Поместите курсор, в который вы хотите вставить код.
  2. Начните вводить имя фрагмента кода (без пробелов или дефисов).
  3. Посмотрите, как IntelliSense отображает соответствующие имена фрагментов.
  4. Выберите правильный фрагмент кода (или продолжайте вводить текст до тех пор, пока не будет выбрано имя всего фрагмента кода).
  5. Дважды нажмите клавишу TAB, чтобы вставить фрагмент в расположение курсора.

Начните вводить имя фрагмента кода

Начните вводить имя фрагмента кода

Нажмите клавишу TAB, чтобы выбрать выделенный фрагмент кода

Нажмите клавишу TAB, чтобы выбрать выделенный фрагмент кода

Нажмите клавишу TAB еще раз, и фрагмент будет развернут

Нажмите клавишу TAB еще раз, и фрагмент будет развернут

Добавление фрагмента кода с помощью мыши (C#, Visual Basic и XML) 1. Щелкните правой кнопкой мыши место вставки фрагмента кода.

  1. Выберите " Вставить фрагмент кода" , за которым следует фрагменты кода.
  2. Выберите соответствующий фрагмент из списка, щелкнув его.

Щелкните правой кнопкой мыши место вставки фрагмента кода и выберите

Щелкните правой кнопкой мыши место вставки фрагмента кода и выберите "Вставить фрагмент кода"

Выберите соответствующий фрагмент из списка, щелкнув его

Выберите соответствующий фрагмент из списка, щелкнув его