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


Маршрутизация URL-адресов

Эрик Рейтан (Erik Reitan)

Скачать пример проекта Wingtip Toys (C#) или скачать электронную книгу (PDF)

В этой серии учебников вы узнаете об основах создания приложения ASP.NET Web Forms с помощью ASP.NET 4.5 и Microsoft Visual Studio Express 2013 для Интернета. В этой серии руководств доступен проект Visual Studio 2013 с исходным кодом C#.

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

Из этого руководства вы узнаете, как выполнять такие задачи:

  • Как зарегистрировать маршруты для приложения ASP.NET Web Forms.
  • Добавление маршрутов на веб-страницу.
  • Выбор данных из базы данных для поддержки маршрутов.

Общие сведения о маршрутизации ASP.NET

Маршрутизация URL-адресов позволяет настроить приложение для приема URL-адресов запросов, не сопоставленных с физическими файлами. URL-адрес запроса — это просто URL-адрес, который пользователь вводит в браузере для поиска страницы на веб-сайте. Маршрутизация используется для определения семантически значимых ДЛЯ пользователей URL-адресов, которые могут помочь в оптимизации поисковой системы (SEO).

По умолчанию шаблон веб-формы содержит ASP.NET понятные URL-адреса. Большая часть базовой работы по маршрутизации будет реализована с помощью понятных URL-адресов. Однако в этом руководстве вы добавите настраиваемые возможности маршрутизации.

Перед настройкой маршрутизации URL-адресов пример приложения Wingtip Toys может ссылаться на продукт, используя следующий URL-адрес:

https://localhost:44300/ProductDetails.aspx?productID=2

При настройке маршрутизации URL-адресов пример приложения Wingtip Toys будет ссылаться на тот же продукт, используя более удобный для чтения URL-адрес:

https://localhost:44300/Product/Convertible%20Car

Маршруты

Маршрут — это шаблон URL-адреса, сопоставляемый с обработчиком. Обработчиком может быть физический файл, например ASPX-файл в веб-формы приложении. Обработчик также может быть классом, обрабатывающим запрос. Чтобы определить маршрут, необходимо создать экземпляр класса Route, указав шаблон URL-адреса, обработчик и при необходимости имя маршрута.

Чтобы добавить маршрут к приложению, добавьте объект в Route статическое Routes свойство RouteTable класса . Свойство Routes — это объект, в котором RouteCollection хранятся все маршруты для приложения.

Шаблоны URL-адресов

Шаблон URL-адреса может содержать литеральные значения и заполнители переменных (называемые параметрами URL-адреса). Литералы и заполнители расположены в сегментах URL-адреса, разделенных символом косой черты (/).

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

В шаблоне URL-адреса заполнители определяются путем их заключения в фигурные скобки ( { и } ). В сегменте можно определить несколько заполнителей, но заполнители должны быть разделены литеральным значением. Например, {language}-{country}/{action} является допустимым шаблоном маршрута. {language}{country}/{action} Однако не является допустимым шаблоном, так как между заполнителями нет литерального значения или разделителя. Таким образом, маршрутизация не может определить, где следует отделить значение заполнителя языка от значения заполнителя страны.

Сопоставление и регистрация маршрутов

Перед включением маршрутов на страницы примера приложения Wingtip Toys необходимо зарегистрировать маршруты при запуске приложения. Чтобы зарегистрировать маршруты, измените Application_Start обработчик событий.

  1. В Обозреватель решений visual Studio найдите и откройте файл Global.asax.cs.

  2. Добавьте в файл Global.asax.cs код, выделенный желтым цветом, следующим образом:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Optimization;
    using System.Web.Routing;
    using System.Web.Security;
    using System.Web.SessionState;
    using System.Data.Entity;
    using WingtipToys.Models;
    using WingtipToys.Logic;
    
    namespace WingtipToys
    {
        public class Global : HttpApplication
        {
            void Application_Start(object sender, EventArgs e)
            {
              // Code that runs on application startup
              RouteConfig.RegisterRoutes(RouteTable.Routes);
              BundleConfig.RegisterBundles(BundleTable.Bundles);
    
              // Initialize the product database.
              Database.SetInitializer(new ProductDatabaseInitializer());
    
              // Create custom role and user.
              RoleActions roleActions = new RoleActions();
              roleActions.AddUserAndRole();
    
              // Add Routes.
              RegisterCustomRoutes(RouteTable.Routes);
            }
    
            void RegisterCustomRoutes(RouteCollection routes)
            {
              routes.MapPageRoute(
                  "ProductsByCategoryRoute",
                  "Category/{categoryName}",
                  "~/ProductList.aspx"
              );
              routes.MapPageRoute(
                  "ProductByNameRoute",
                  "Product/{productName}",
                  "~/ProductDetails.aspx"
              );
            }
        }
    }
    

При запуске примера приложения Wingtip Toys оно вызывает Application_Start обработчик событий. В конце этого обработчика RegisterCustomRoutes событий вызывается метод . Метод RegisterCustomRoutes добавляет каждый маршрут путем MapPageRoute вызова метода RouteCollection объекта . Маршруты определяются с помощью имени маршрута, URL-адреса маршрута и физического URL-адреса.

Первый параметр ("ProductsByCategoryRoute") — это имя маршрута. Он используется для вызова маршрута при необходимости. Второй параметр ("Category/{categoryName}") определяет понятный URL-адрес замены, который может быть динамическим на основе кода. Этот маршрут используется при заполнении элемента управления данными ссылками, созданными на основе данных. Маршрут отображается следующим образом:

routes.MapPageRoute(
      "ProductsByCategoryRoute",
      "Category/{categoryName}",
      "~/ProductList.aspx"
  );

Второй параметр маршрута включает динамическое значение, заданное фигурными скобками ({ }). В этом случае является переменной, categoryName которая будет использоваться для определения правильного пути маршрутизации.

Примечание

Необязательно

Вы можете упростить управление кодом, переместив метод в RegisterCustomRoutes отдельный класс. В папке Логика создайте отдельный RouteActions класс. Переместите приведенный выше RegisterCustomRoutes метод из файла Global.asax.cs в новый RoutesActions класс. RoleActions Используйте класс и метод в createAdmin качестве примера вызова RegisterCustomRoutes метода из файла Global.asax.cs.

Возможно, вы также заметили RegisterRoutes вызов метода с использованием RouteConfig объекта в начале обработчика Application_Start событий. Этот вызов выполняется для реализации маршрутизации по умолчанию. Он был включен в качестве кода по умолчанию при создании приложения с помощью шаблона веб-формы Visual Studio.

Получение и использование данных маршрута

Как упоминалось выше, можно определить маршруты. Код, добавленный Application_Start в обработчик событий в файле Global.asax.cs , загружает определяемые маршруты.

Настройка маршрутов

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

Включение маршрутов для категорий и продуктов

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

  1. В Обозреватель решений откройте страницу Site.Master, если она еще не открыта.

  2. Обновите элемент управления ListView с именем "categoryList", указав изменения, выделенные желтым цветом, чтобы разметка выглядела следующим образом:

    <asp:ListView ID="categoryList"  
        ItemType="WingtipToys.Models.Category" 
        runat="server"
        SelectMethod="GetCategories" >
        <ItemTemplate>
            <b style="font-size: large; font-style: normal">
            <a href="<%#: GetRouteUrl("ProductsByCategoryRoute", new {categoryName = Item.CategoryName}) %>">
                <%#: Item.CategoryName %>
            </a>
            </b>
        </ItemTemplate>
        <ItemSeparatorTemplate>  |  </ItemSeparatorTemplate>
    </asp:ListView>
    
  3. В Обозреватель решений откройте страницу ProductList.aspx.

  4. ItemTemplate Обновите элемент страницы ProductList.aspx, указав обновления, выделенные желтым цветом, чтобы разметка выглядела следующим образом:

    <ItemTemplate>
      <td runat="server">
        <table>
          <tr>
            <td>
              <a href="<%#: GetRouteUrl("ProductByNameRoute", new {productName = Item.ProductName}) %>">
                <image src='/Catalog/Images/Thumbs/<%#:Item.ImagePath%>'
                  width="100" height="75" border="1" />
              </a>
            </td>
          </tr>
          <tr>
            <td>
              <a href="<%#: GetRouteUrl("ProductByNameRoute", new {productName = Item.ProductName}) %>">
                <%#:Item.ProductName%>
              </a>
              <br />
              <span>
                <b>Price: </b><%#:String.Format("{0:c}", Item.UnitPrice)%>
              </span>
              <br />
              <a href="/AddToCart.aspx?productID=<%#:Item.ProductID %>">
                <span class="ProductListItem">
                  <b>Add To Cart<b>
                </span>
              </a>
            </td>
          </tr>
          <tr>
            <td>&nbsp;</td>
          </tr>
        </table>
        </p>
      </td>
    </ItemTemplate>
    
  5. Откройте код программной части файла ProductList.aspx.cs и добавьте следующее пространство имен, выделенное желтым цветом:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using WingtipToys.Models;
    using System.Web.ModelBinding;
    using System.Web.Routing;
    
  6. Замените GetProducts метод кода программной части (ProductList.aspx.cs) следующим кодом:

    public IQueryable<Product> GetProducts(
        [QueryString("id")] int? categoryId,
        [RouteData] string categoryName)
    {
        var _db = new WingtipToys.Models.ProductContext();
        IQueryable<Product> query = _db.Products;
    
        if (categoryId.HasValue && categoryId > 0)
        {
            query = query.Where(p => p.CategoryID == categoryId);
        }
    
        if (!String.IsNullOrEmpty(categoryName))
        {
            query = query.Where(p =>
                String.Compare(p.Category.CategoryName,
                categoryName) == 0);
        }
        return query;
    }
    

Добавление кода для сведений о продукте

Теперь обновите код программной части (ProductDetails.aspx.cs) для страницы ProductDetails.aspx , чтобы использовать данные маршрута. Обратите внимание, что новый GetProduct метод также принимает значение строки запроса для случая, когда у пользователя есть ссылка в закладке, использующая старый неуправляемый URL-адрес.

  1. Замените GetProduct метод кода программной части (ProductDetails.aspx.cs) следующим кодом:

    public IQueryable<Product> GetProduct(
            [QueryString("ProductID")] int? productId,
            [RouteData] string productName)
    {
        var _db = new WingtipToys.Models.ProductContext();
        IQueryable<Product> query = _db.Products;
        if (productId.HasValue && productId > 0)
        {
            query = query.Where(p => p.ProductID == productId);
        }
        else if (!String.IsNullOrEmpty(productName))
        {
            query = query.Where(p =>
                  String.Compare(p.ProductName, productName) == 0);
        }
        else
        {
            query = null;
        }
        return query;
    }
    

Запуск приложения

Теперь вы можете запустить приложение, чтобы просмотреть обновленные маршруты.

  1. Нажмите клавишу F5 , чтобы запустить пример приложения Wingtip Toys.
    Откроется браузер со страницей Default.aspx .
  2. Щелкните ссылку Продукты в верхней части страницы.
    Все продукты отображаются на странице ProductList.aspx . В браузере отображается следующий URL-адрес (с использованием номера порта):
    https://localhost:44300/ProductList
  3. Затем щелкните ссылку Категория Автомобили в верхней части страницы.
    На странице ProductList.aspx отображаются только автомобили. В браузере отображается следующий URL-адрес (с использованием номера порта):
    https://localhost:44300/Category/Cars
  4. Щелкните ссылку, содержащую имя первого автомобиля, указанного на странице ("Кабриолет"), чтобы отобразить сведения о продукте.
    В браузере отображается следующий URL-адрес (с использованием номера порта):
    https://localhost:44300/Product/Convertible%20Car
  5. Затем введите следующий ненаправимый URL-адрес (с помощью номера порта) в браузере:
    https://localhost:44300/ProductDetails.aspx?productID=2
    Код по-прежнему распознает URL-адрес, содержащий строку запроса, в случае, когда у пользователя есть закладка ссылки.

Сводка

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

Дополнительные ресурсы

ASP.NET Friendly URLs
Развертывание приложения secure ASP.NET Web Forms с членством, OAuth и База данных SQL в Служба приложений Azure
Microsoft Azure — бесплатная пробная версия