ASP .NET - Web Forms e a vinculação de dados (C#) (revisão)


Hoje eu vou escrever um pouco sobre Web Forms e os controles de servidor usados para vinculação e acesso a dados.

Os controles com capacidade de vinculação de de dados, são mais conhecidos como controles de dados, e são controles especiais que fornecem uma maneira rápida de exibir dados provenientes de diferentes fontes.

A partir da perspectiva do controle, a fonte deve implementar uma interface de IList, IEnumerable, ou uma interface ICollection. Este requisito é verdadeiro para coleções personalizadas, dados provenientes de um banco de dados usando ADO.NET e também para expressões LINQ.

Pela definição da propriedade DataSource de esses controles, você pode especificar via código a fonte de dados a ser exibida.

Para evitar erros e simplificar o seu trabalho, esses controles geralmente executam muitas das tarefas relacionadas com a exibição de dados para você. Eles verificam se há dados, percorrem os itens, e fornecem uma saída.

Esses controles são baseados em templates diferentes que renderizam partes distintas. Esses modelos fornecem uma maneira simples de personalizar a marcação a ser gerada.

A vinculação de dados esta embutida nos controles ASP .NET e quando ela é invocada a fonte de dados é enumerada e o seu conteúdo é associado com o controle correspondente. O esquema abaixo representa este comportamento:

Para entender melhor vamos ver como funciona a ligação bem simples.

Exibindo dados com o controle Repeater

O controle Repeater é um controle de lista vinculado a dados que permite criar um layout personalizado, repetindo um modelo especificado para cada item exibido na lista.

O DataRepeater é o controle de dados mais simples que temos e seu objetivo é repetir o template especificado. Os templates geralmente são definidos usando tags de marcação(Markup) e no caso do controle DataRepeater temos:

<asp:Repeater id="MyView" runat="server">
  <HeaderTemplate>
      
   [Header markup]
  </HeaderTemplate>
  <FooterTemplate>
      
  [Footers markup]
  </FooterTemplate>
  <ItemTemplate>
         
[Items markup]
  </ItemTemplate>
</asp:Repeater>

Quando o Parser (analisador) de páginas ASP.NET encontra um desses templates, ele os converte automaticamente em tempo de execução para uma instância de System.Web.UI.CompiledTemplateBuilder. (Note-se que templates são implementados por uma interface ITemplate genérica.)

Para simplificar a vinculação de dados, a ASP.NET apresenta uma sintaxe específica, que é automaticamente convertida para incluir um manipulador de eventos para o evento DataBinding. A sintaxe é: <%# "Macoratti"%>

Essa seqüência de caracteres é interpretada pelo analisador de página de form aque a função é chamada quando ocorre o evento DataBinding. Este evento é chamado apenas quando o método DataBind é chamado explicitamente sobre o controle de recipiente.

Em um formulário simples você vai usar o método Eval para extrair dados sendo que este método é exposto pela própria página via classe TemplateControl; <%#Eval("Minha_Propriedade")%>

Eval é um método de atalho que mapeia para o DataBinder.Eval cuja sintaxe vemos a seguir:

<%#DataBinder.Eval(Container.DataItem, "Minha_Propriedade")%>

Ambos os métodos recuperam a propriedade MinhaPropriedade da fonte de origem associada via propriedade Container do tipo IDataItemContainer;

Por convenção a interface IDataItemContainer é implementada por todos os templates. As propriedades desta interface são:

Membro Descrição
DataItem Um objeto que contém uma referência para o elemento atual que foi tomado do datasource.
DataItemIndex O índice do elemento atual no data source;
DisplayIndex O índice do elementu atual na renderização.

Se você precisar exibir uma propriedade a partir de uma classe específica você pode usar esta sintaxe:

<%#((Classe)Container.DataItem).Minha_Property%>
<%#DirectCast(Container.DataItem, Classe).Minha_Propriedade%>

C#:

VB .NET

Você deve escolher esta sintaxe em relação à anterior (Eval/DataBinder.Eval) na maior parte do tempo.

Ela não usa a reflexão (reflection) e tem um melhor desempenho. Você não precisa realizar a conversão forçada(casting), pois está acessando o objeto diretamente.

Esta sintaxe tem uma verificação de sintaxe em tempo de compilação, enquanto a outra sintaxe será controlada apenas em tempo de execução,e, erros em tempo de execução são um problema porque você tem menos controle sobre sua testabilidade.

Você pode adaptar o código acima para exibir os clientes em uma lista não ordenada usando o controle DataRepeater da seguinte forma:

<asp:Repeater id="CustomerView" runat="server">
<HeaderTemplate>
    <ul>
</HeaderTemplate>
<FooterTemplate>
   </ul>
</FooterTemplate>
<ItemTemplate>
 
  <li><%#((Customer)Container.DataItem).ContactName %></li>  C#
  
 <li><%#DirectCast(Container.DataItem, Customer).ContactName%></li> VB .NET
</ItemTemplate>
</asp:Repeater>

Usando o Repeater na prática

Abra o Visual Web Developer 2010 Express Edition e crie um novo projeto do tipo ASP .NET Web Application com o nome Repeater;

Abra a página Default.aspx e inclua o código abaixo no modo Design:

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="DataRepeater._Default" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
   <h2>Usando Repeater</h2>
   <table width="600" border="0" align="center" cellpadding="5" cellspacing="1" bgcolor="#cccccc">
    <tr>
    <td width="100" align="right" bgcolor="#eeeeee" class="header1">Funcionários:</td>
     <td bgcolor="#FFFFFF">
   
  <asp:Repeater ID="repeaterExemplo" runat="server">
        <ItemTemplate>
           <br /><%# DataBinder.Eval(Container, "DataItem.firstname") %><br />
        </ItemTemplate>
      </asp:Repeater>

      <asp:Label ID="lblStatus" runat="server"></asp:Label>
    </td>
    </tr>
    </table>
</asp:Content>

Estamos usando o controle Repeater em uma tabela e também um controle Label para exibir mensagens.

Abra o arquivo Default.aspx.cs e defina o seguinte código:

using System;
using System.Data.SqlClient;

namespace DataRepeater
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            SqlCommand cmd = new SqlCommand("SELECT * FROM EMPLOYEES", new SqlConnection("Server=.\\SQLEXPRESS;Database=Northwind;Trusted_Connection=True;"));
            try
            {
                cmd.Connection.Open();
                repeaterExemplo.DataSource = cmd.ExecuteReader();
                repeaterExemplo.DataBind();
                cmd.Connection.Close();
                cmd.Connection.Dispose();
            }
            catch (Exception ex)
            {
                lblStatus.Text = ex.Message;
            }
        }
    }
}

Este código acessa a tabela Employees do banco de dados Northwind.mdf na máquina local;

Executando o projeto iremos obter o seguinte resultado:

Podemos melhorar a aparência da exibição dos dados.

Para isso vamos definir os templates: HeaderTemplate, ItemTemplate, AlternatingItemTemplate e FooterTemplate alterando o código do arquivo Default.aspx conforme o código abaixo:

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="DataRepeater._Default" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
   <h2>Usando Repeater</h2>
    
<asp:Repeater id="repeaterExemplo" runat="server">
       <HeaderTemplate>
          <table border="1">
             <tr bgcolor="#ffcc77">
                <th>ID</th>
                <th>Nome</th>
                <th>Sobrenome</th>
                <th>Endereço</th>
             </tr>
       </HeaderTemplate>
       <ItemTemplate>
          <tr bgcolor="#fffccc">
       
    <td><%# DataBinder.Eval(Container.DataItem, "EmployeeID") %></td>
            <td><%# DataBinder.Eval(Container.DataItem, "LastName") %></td>
            <td><%# DataBinder.Eval(Container.DataItem, "FirstName") %></td>
            <td><%# DataBinder.Eval(Container.DataItem, "Address") %></td>

          </tr>
       </ItemTemplate>
       <AlternatingItemTemplate>
          <tr bgcolor="#ccff88">
           
<td><%# DataBinder.Eval(Container.DataItem, "EmployeeID") %></td>
            <td><%# DataBinder.Eval(Container.DataItem, "LastName") %></td>
            <td><%# DataBinder.Eval(Container.DataItem, "FirstName") %></td>
            <td><%# DataBinder.Eval(Container.DataItem, "Address") %></td>

          </tr>
       </AlternatingItemTemplate>
       <FooterTemplate>
       </table>
       </FooterTemplate>
    </asp:Repeater>
    <br />
    <asp:Label ID="lblStatus" runat="server"></asp:Label>
</asp:Content>

Executando o projeto agora teremos:

Pegue o projeto completo aqui: DataRepeater.zip

Gál 3:10 Pois todos quantos são das obras da lei estão debaixo da maldição; porque escrito está: Maldito todo aquele que não permanece em todas as coisas que estão escritas no livro da lei, para fazê-las.
Gál 3:11
É evidente que pela lei ninguém é justificado diante de Deus, porque: O justo viverá da fé;
Gál 3:12
ora, a lei não é da fé, mas: O que fizer estas coisas, por elas viverá.

Referências:


José Carlos Macoratti