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.Referências: