Roteamento de URL
por Erik Reitan
Baixar o Projeto de Exemplo de Brinquedos wingtip (C#) ou baixar e-book (PDF)
Esta série de tutoriais ensinará os conceitos básicos da criação de um aplicativo ASP.NET Web Forms usando ASP.NET 4.5 e Microsoft Visual Studio Express 2013 para Web. Um projeto Visual Studio 2013 com código-fonte C# está disponível para acompanhar esta série de tutoriais.
Neste tutorial, você modificará o aplicativo de exemplo Wingtip Toys para dar suporte ao roteamento de URL. O roteamento permite que seu aplicativo Web use URLs amigáveis, mais fáceis de lembrar e com melhor suporte por mecanismos de pesquisa. Este tutorial se baseia no tutorial anterior "Associação e Administração" e faz parte da série de tutoriais Wingtip Toys.
- Como registrar rotas para um aplicativo ASP.NET Web Forms.
- Como adicionar rotas a uma página da Web.
- Como selecionar dados de um banco de dados para dar suporte a rotas.
O roteamento de URL permite configurar um aplicativo para aceitar URLs de solicitação que não são mapeadas para arquivos físicos. Uma URL de solicitação é simplesmente a URL que um usuário insere no navegador para encontrar uma página em seu site. Você usa o roteamento para definir URLs semanticamente significativas para os usuários e que podem ajudar com a SEO (otimização do mecanismo de pesquisa).
Por padrão, o modelo de Web Forms inclui urls ASP.NET amigáveis. Grande parte do trabalho básico de roteamento será implementada usando URLs amigáveis. No entanto, neste tutorial, você adicionará recursos de roteamento personalizados.
Antes de personalizar o roteamento de URL, o aplicativo de exemplo Wingtip Toys pode vincular a um produto usando a seguinte URL:
https://localhost:44300/ProductDetails.aspx?productID=2
Ao personalizar o roteamento de URL, o aplicativo de exemplo Wingtip Toys será vinculado ao mesmo produto usando uma URL mais fácil de ler:
https://localhost:44300/Product/Convertible%20Car
Um rota é um padrão de URL mapeado para um manipulador. O manipulador pode ser um arquivo físico, como um arquivo .aspx em um aplicativo Web Forms. Um manipulador também pode ser uma classe que processa a solicitação. Para definir uma rota, crie uma instância da classe Route especificando o padrão de URL, o manipulador e, opcionalmente, um nome para a rota.
Adicione a rota ao aplicativo adicionando o Route
objeto à propriedade estática Routes
da RouteTable
classe . A propriedade Routes é um RouteCollection
objeto que armazena todas as rotas para o aplicativo.
Um padrão de URL pode conter valores literais e espaços reservados variáveis (conhecidos como parâmetros de URL). Os literais e espaços reservados estão localizados em segmentos da URL delimitados pelo caractere de barra (/
).
Quando uma solicitação para seu aplicativo Web é feita, a URL é analisada em segmentos e espaços reservados e os valores de variável são fornecidos ao manipulador de solicitação. Esse processo é semelhante à maneira como os dados em uma cadeia de caracteres de consulta são analisados e passados para o manipulador de solicitação. Em ambos os casos, as informações de variável são incluídas na URL e passadas para o manipulador na forma de pares chave-valor. Para cadeias de caracteres de consulta, as chaves e os valores estão na URL. Para rotas, as chaves são os nomes de espaço reservado definidos no padrão de URL e apenas os valores estão na URL.
Em um padrão de URL, você define espaços reservados colocando-os entre chaves ( {
e }
). Você pode definir mais de um espaço reservado em um segmento, mas os espaços reservados devem ser separados por um valor literal. Por exemplo, {language}-{country}/{action}
é um padrão de rota válido. No entanto, {language}{country}/{action}
não é um padrão válido, pois não há nenhum valor literal ou delimitador entre os espaços reservados. Portanto, o roteamento não pode determinar onde separar o valor do espaço reservado do idioma do valor para o espaço reservado do país.
Antes de incluir rotas para páginas do aplicativo de exemplo Wingtip Toys, você deve registrar as rotas quando o aplicativo for iniciado. Para registrar as rotas, você modificará o Application_Start
manipulador de eventos.
No Gerenciador de Soluções do Visual Studio, localize e abra o arquivo Global.asax.cs.
Adicione o código realçado em amarelo ao arquivo Global.asax.cs da seguinte maneira:
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" ); } } }
Quando o aplicativo de exemplo Wingtip Toys é iniciado, ele chama o Application_Start
manipulador de eventos. No final desse manipulador de eventos, o RegisterCustomRoutes
método é chamado. O RegisterCustomRoutes
método adiciona cada rota chamando o MapPageRoute
método do RouteCollection
objeto . As rotas são definidas usando um nome de rota, uma URL de rota e uma URL física.
O primeiro parâmetro ("ProductsByCategoryRoute
") é o nome da rota. Ele é usado para chamar a rota quando ela é necessária. O segundo parâmetro ("Category/{categoryName}
") define a URL de substituição amigável que pode ser dinâmica com base no código. Você usa essa rota quando está preenchendo um controle de dados com links gerados com base em dados. Uma rota é mostrada da seguinte maneira:
routes.MapPageRoute(
"ProductsByCategoryRoute",
"Category/{categoryName}",
"~/ProductList.aspx"
);
O segundo parâmetro da rota inclui um valor dinâmico especificado por chaves ({ }
). Nesse caso, o categoryName
é uma variável que será usada para determinar o caminho de roteamento adequado.
Nota
Opcional
Talvez seja mais fácil gerenciar seu código movendo o RegisterCustomRoutes
método para uma classe separada. Na pasta Lógica , crie uma classe separada RouteActions
. Mova o método acima RegisterCustomRoutes
do arquivo Global.asax.cs para a nova RoutesActions
classe. Use a RoleActions
classe e o createAdmin
método como um exemplo de como chamar o RegisterCustomRoutes
método do arquivo Global.asax.cs .
Talvez você também tenha notado a chamada de RegisterRoutes
método usando o RouteConfig
objeto no início do Application_Start
manipulador de eventos. Essa chamada é feita para implementar o roteamento padrão. Ele foi incluído como código padrão quando você criou o aplicativo usando o modelo de Web Forms do Visual Studio.
Conforme mencionado acima, as rotas podem ser definidas. O código que você adicionou ao Application_Start
manipulador de eventos no arquivo Global.asax.cs carrega as rotas definíveis.
As rotas exigem que você adicione código adicional. Neste tutorial, você usará a associação de modelo para recuperar um RouteValueDictionary
objeto usado ao gerar as rotas usando dados de um controle de dados. O RouteValueDictionary
objeto conterá uma lista de nomes de produtos que pertencem a uma categoria específica de produtos. Um link é criado para cada produto com base nos dados e na rota.
Em seguida, você atualizará o aplicativo para usar o ProductsByCategoryRoute
para determinar a rota correta a ser incluída para cada link de categoria de produto. Você também atualizará a página ProductList.aspx para incluir um link roteado para cada produto. Os links serão exibidos como eram antes da alteração, no entanto, os links agora usarão o roteamento de URL.
Em Gerenciador de Soluções, abra a página Site.Master se ela ainda não estiver aberta.
Atualize o controle ListView chamado "
categoryList
" com as alterações realçadas em amarelo, para que a marcação apareça da seguinte maneira:<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>
Em Gerenciador de Soluções, abra a página ProductList.aspx.
Atualize o
ItemTemplate
elemento da página ProductList.aspx com as atualizações realçadas em amarelo, para que a marcação apareça da seguinte maneira:<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> </td> </tr> </table> </p> </td> </ItemTemplate>
Abra o code-behind de ProductList.aspx.cs e adicione o seguinte namespace, conforme realçado em amarelo:
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;
Substitua o
GetProducts
método do code-behind (ProductList.aspx.cs) pelo seguinte código: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; }
Agora, atualize o code-behind (ProductDetails.aspx.cs) para a página ProductDetails.aspx para usar dados de rota. Observe que o novo GetProduct
método também aceita um valor de cadeia de caracteres de consulta para o caso em que o usuário tem um link marcado que usa a URL não amigável e não roteada mais antiga.
Substitua o
GetProduct
método do code-behind (ProductDetails.aspx.cs) pelo seguinte código: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; }
Agora você pode executar o aplicativo para ver as rotas atualizadas.
- Pressione F5 para executar o aplicativo de exemplo Wingtip Toys.
O navegador é aberto e mostra a página Default.aspx . - Clique no link Produtos na parte superior da página.
Todos os produtos são exibidos na página ProductList.aspx . A SEGUINTE URL (usando o número da porta) é exibida para o navegador:
https://localhost:44300/ProductList
- Em seguida, clique no link categoria Carros próximo à parte superior da página.
Somente os carros são exibidos na página ProductList.aspx . A SEGUINTE URL (usando o número da porta) é exibida para o navegador:
https://localhost:44300/Category/Cars
- Clique no link que contém o nome do primeiro carro listado na página ("Carro Conversível") para exibir os detalhes do produto.
A SEGUINTE URL (usando o número da porta) é exibida para o navegador:
https://localhost:44300/Product/Convertible%20Car
- Em seguida, insira a seguinte URL não roteada (usando o número da porta) no navegador:
https://localhost:44300/ProductDetails.aspx?productID=2
O código ainda reconhece uma URL que inclui uma cadeia de caracteres de consulta, para o caso em que um usuário tem um link marcado.
Neste tutorial, você adicionou rotas para categorias e produtos. Você aprendeu como as rotas podem ser integradas aos controles de dados que usam a associação de modelo. No próximo tutorial, você implementará o tratamento de erros global.
URLs amigáveis do ASP.NET
Implantar um aplicativo de ASP.NET Web Forms seguro com associação, OAuth e Banco de Dados SQL para Serviço de Aplicativo do Azure
Microsoft Azure – Avaliação gratuita