Desenvolvimento - ASP. NET

Otimizando a paginação do ASP.NET para SEO usando LINQ

Utilizando o ASP.NET temos diversos caminhos a otimizar fazendo com que a aplicação exposta na web de forma pública seja melhor entendida e um deles é a paginação de registros que vamos implementar nesse artigo.

por Ramon Durães



Artigo recomendado para Visual Studio 2008, SQLServer 2005/2008.

A internet não é mais a mesma desde o lançamento dos primeiros cadastros de sites que deram inicio aos grandes portais de busca que temos hoje. Em função dos poderosos indexadores precisamos otimizar o conteúdo e links da aplicação web de forma que ela seja melhor entendida e indexada. A esse conjunto de técnicas de marketing focado em indexação de conteúdo que deu-se origem ao termo SEO (Search engine optimization). Utilizando o ASP.NET temos diversos caminhos a otimizar fazendo com que a aplicação exposta na web de forma pública seja melhor entendida e um deles é a paginação de registros que vamos implementar nesse artigo.

Vale ressaltar que essa técnica de paginação utilizara o LINQ (Language Integrated Query) para o melhor desempenho e SQLServer 2005 ou 2008 com numeração de linhas. Você também pode substituir o LINQ por uma Stored Procedure e adaptar o mesmo exemplo para uso no Visual Studio 2005 com tableAdapter.

Após criação do novo projeto web o próximo passo é criar o diagrama de classe do LINQ para o mapeamento da tabela Produtcs do banco de dados exemplo 'Northwind' conforme Figura 01. Lembrando que esse banco de dados deve está rodando no servidor SQLServer.



Figura 01 - Tabela Products mapeada como classe Product no LINQ.

Agora para completar o projeto adicione um webform Produtos.aspx e um usercontrol chamado de ucPaginacao.ascx que usaremos para conter a interface de paginação. Durante a implementação desse exemplo utilizaremos um Repeater para exibir os dados, porém como o mesmo não possui paginação estamos justamente desenvolvendo nesse artigo.

Retornando ao nosso formulário adicione um Repeater e configure conforme o código HTML da Listagem 01.

Produtos.aspx
   1:  <asp:Repeater ID="Repeater1" runat="server">
   2:          <ItemTemplate>
   3:          <%#Eval("Codigo")%>
   4:          <%#Eval("Descricao")%>
   5:          <br />
   6:          
   7:          </ItemTemplate>
   8:  </asp:Repeater>
Listagem 01 - Configurando controle Repeater.

O Próximo passo é arrastar o controle ucPaginacao para pagina produtos.aspx. Em seguida criaremos o método Carregar() dentro do nosso WebForm 'Produtos'. Esse método será o responsável pela consulta no banco de dados usando o LINQ e trará apenas um bloco especifico de registros otimizando a paginação ao máximo. Confira na Listagem 02.

Carregar()
   1:  /// <summary>
   2:  /// Obter dados do banco de dados
   3:  /// Traz apenas um grupo especifico de registros.
   4:  /// </summary>
   5:  private void Carregar()
   6:  {
   7:              var pagina = 0;
   8:              var db = new PaginacaoDBDataContext();
   9:              var totalRegistros = (from p in db.Products
  10:                           select p).Count();
  11:              if (PaginaAtual != 0)
  12:              { pagina = PaginaAtual * MaximoRegistrosPagina; }
  13:  
  14:  
  15:            var dados = (from p in db.Products
  16:                           orderby p.ProductID 
  17:                           select new
  18:                           {  
  19:                               Codigo = p.ProductID,
  20:                               Descricao = p.ProductName
  21:                           }
  22:  
  23:                    ).Skip(pagina).Take(MaximoRegistrosPagina);
  24:  
  25:              this.Repeater1.DataSource = dados;
  26:              this.Repeater1.DataBind();
  27:              ConfiguraPaginacao(totalRegistros);
  28:  }
Listagem 02 - Implementando método Carregar().

Conforme você está observando nessa listagem usando a linguagem de consulta do LINQ estamos obtendo um conjunto especifico de registros que estão determinados pelo parâmetro Skip() e Take(). Confira na Listagem 03 um exemplo de código T-SQL gerado automaticamente.

T-SQL Paginação
   1:  SELECT [t1].[ProductID] AS [Codigo], [t1].[ProductName] AS
 [Descricao]
   2:  FROM (
   3:      SELECT ROW_NUMBER() OVER (ORDER BY [t0].[ProductID]) AS
 [ROW_NUMBER], [t0].[ProductID], [t0].[ProductName]
   4:      FROM [dbo].[Products] AS [t0]
   5:      ) AS [t1]
   6:  WHERE [t1].[ROW_NUMBER] BETWEEN 10 + 1 AND 10 + 10
   7:  ORDER BY [t1].[ROW_NUMBER]
Listagem 03 - Código T-SQL gerado pelo LINQ

A lógica implementada na Listagem 02 tem objetivo de extrair do banco de dados a pagina atual calculada pela quantidade de registros no banco de dados (Listagem 02 - Linha 09), mais o tamanho da pagina (padrão 10 registros) e o parâmetro pagina atual que será usado para determinar os parâmetros do método Skip().

Para criar o link de avançar e retornar pelos registros foi implementado uma regra dentro do controle ucPaginacao onde configuramos pelo método ConfiguraPaginacao() apresentado na Listagem 04.

ConfiguraPaginacao()
   1:  /// <summary>
   2:  /// Configurando controle de paginação
   3:  /// </summary>
   4:  /// <param name="total"></param>
   5:  private void ConfiguraPaginacao(int totalRegistros)
   6:  {
   7:              
   8:       PaginacaoParametros parametros = new PaginacaoParametros();
   9:       parametros.TotalRegistros = totalRegistros;
  10:       parametros.PaginaAtual = PaginaAtual;
  11:       parametros.MaximoRegistrosPagina = MaximoRegistrosPagina;
  12:       ucPaginacao1.Carregar(parametros);
  13:  }
Listagem 04 - Implementação do método ConfiguraPaginacao().

Conforme Listagem 04 nesse método estamos usando a classe PaginacaoParametros criada dentro do UserControl com objetivo de passar parâmetros para o controle por meio do método Carregar() apresentado na linha 12.

Examinando o controle ucPaginacao na Listagem 05 perceba que adicionamos dois controles HyperLink justamente para utilizarmos os links em HTML de forma que as ferramentas de busca possam navegar por todas as paginas automaticamente. Como elas navegam em todos links html que encontram vão avançar todas as paginas até o final registrando em suas bases de dados todo o conteúdo.

ucPaginacao.ascx
   1:  <%@ Control Language="C#" AutoEventWireup="true"
   2:   CodeBehind="ucPaginacao.ascx.cs"
   3:    Inherits="PaginacaoSEOLinq.ucPaginacao" %>
   4:  <br style="clear: both;" />
   5:  <div id="Navigation" runat="server">
   6:  <div id="navegacao">
   7:  <a id="PreviousPageNav" runat="server"> &lt;&lt; Voltar</a>             
   8:  <asp:Label ID="PagerLocation" runat="server" />
   9:  <asp:HyperLink ID="Link1" runat="server"></asp:HyperLink>
  10:  <a id="NextPageNav" runat="server">Avançar &gt;&gt;</a>
  11:  </div>       
  12:  </div>
Listagem 05 -Código html do ucPaginacao.

Numa rápida visão dentro do código do controle ucPaginacao apresentado na Listagem 06 estamos implementando os métodos necessários para configurar o controle conforme os dados recebidos e exibir as informações para mostrar os links através do método UpdateNextPrevLinks. Parte do código fonte foi suprimido por está disponível para download junto com o código fonte.

ucPaginacao.ascx
   1:  public partial class ucPaginacao : System.Web.UI.UserControl
   2:  {
   3:   private PaginacaoParametros configuracao;
   4:   protected void Page_Load(object sender, EventArgs e)
   5:   {
   6:   }
   7:   public void Carregar(PaginacaoParametros config)
   8:   {
   9:   }
  10:   void UpdatePagerLocation(int pageIndex, int 
pageSize, int productCount)
  11:   {
  12:   }
  13:   void UpdateNextPrevLinks(int pageIndex,
 int pageSize, int productCount)
  14:   {          
  15:   }
  16:  }
Listagem 06 - Implementação do controle ucPaginacao.

A idéia principal de usar esse UserControl é reutilizar o mesmo em todas as paginas bastando arrastar e configurar os parâmetros. Confira o mesmo em ação na Figura 02 e acompanhe também o parâmetro da pagina atual passado na url.


Figura 02 - Paginação em ação.

Durante esse artigo você observou uma implementação usando LINQ com objetivo de realizar paginação atendendo aos critérios do SEO (Search engine optimization) que atingimos pela paginação usando Hyperlink. Esse artigo foi preparado também de forma que você possa substituir o código do LINQ por uma paginação usando TableAdapter ou código manual diretamente usando ADO.NET para ser compatível com Visual Studio 2005.

Código Fonte:
[Download]
Esse artigo foi baseado no banco de dados ""NorthWind".


Referência:
ASP.NET 2.0 - Paginando dados com SQLServer (2000/2005)
Linq para iniciantes - Visual Studio 2008
Efficient Data Paging with the ASP.NET 2.0 DataList Control and ObjectDataSource

Ramon Durães

Ramon Durães - Especialista em desenvolvimento de software e Microsoft Most Valuable Professional (MVP) em Visual Studio Team System. Realiza treinamentos de .NET Framework em empresas, consultoria em arquitetura de software e implantação de Visual Studio Team System. Palestrante nos principais eventos da Microsoft no Brasil (Tech-Ed 2005, Tech-Ed 2006, Tech-Ed 2007, Tech-Ed 2008, Tech-ED 2009), Microsoft Innovation Days 2007 (Salvador, Brasília, Recife, Goiânia, Natal, Maringá), Microsoft Innovation Days 2009 (Salvador) , Campus Party Brasil 2009 e eventos regionais relacionados a grupos de usuários e universidades. Conhecido autor de artigos para os principais portais de conteúdo e autor de 10 publicações eletrônicas em CD (Video-Aula) pela editora Linha de Código além dos livros "Desenvolvendo para web usando o Visual Studio 2008" e "Gerenciando projetos de software usando Visual Studio Team System" pela editora Brasport. Pode ser encontrado em seu blog http://www.ramonduraes.net e @ramonduraes no Twitter.