ASP .NET- Trabalhando em camadas com o ObjectDataSource
Se você tem acompanhado meus artigos recentemente deve ter notado que eu não me canso de escrever sobre como criar aplicações em camadas.
Além de ser uma prática recomendada e de lhe permitir criar aplicações mais escaláveis e mais fáceis de testar, o seu código fica mais limpo e mais fácil de manter.
Você já deve ter percebido que existem diversas formas de criar aplicações em camadas e hoje eu vou mostrar como fazer isso usando o ObjectDataSource da ASP .NET.
Se você não lembra, o ObjectDataSource é um dos controles para acesso a dados existentes na guia Data da ToolBox do Visual Studio ou Visual Web Developer.
Ele fornece acesso à um determinado método de uma alguma classe. Estas classes geralmente encapsulam o acesso à base de dados, ou qualquer repositório, retornando uma coleção de objetos que deve ser apresentada ao usuário. para uma camada intermediária como uma camada de acesso a dados ou um componente de negócio.
Como eu já escrevi muito sobre o assunto, neste artigo vou recordar a utilização deste recursos em uma aplicação ASP .NET usando o Visual Web Developer 2010 Express Edition e o SQL Server 2008 Express de uma forma mais objetiva.
Abaixo vemos a figura que representa o um exemplo de arquitetura em camadas usando o ObjectDataSource, onde você pode ver que o controle serve como uma interface entre os controles de dados vinculados da camada de apresentação e as classes de acesso a dados na camada do meio.
É óbvio que este modelo não é o mais otimizado mas já é um avanço e podemos usá-lo em algumas ocasiões para aplicações mais simples.
Vamos direto ao exemplo prático de como usar o ObjectDataSource em uma aplicação ASP .NET com uma classe de acesso a dados.
Vamos criar uma página que permite exibir uma relação de produtos com opção para filtrar por categoria de produto, um exemplo bem simples e recorrente.
Vou usar o banco de dados Northwind.mdf do SQL Server e trabalhar com as tabelas Products e Categories que possuem a seguinte estrutura:
Abra o Visual Basic 2010 Express Edition e crie um novo projeto do tipo ASP .NET Empty Web Application com o nome ListaProdutos:
Inclua um novo WebForm (menu Project -> Add New Item) com o nome Default.aspx no projeto.
Agora no menu Project -> Add Class inclua uma classe com o nome ProdutoDAL.vb;
Vamos definir o código da classe ProdutoDAL.vb com 3 métodos estáticos (Shared) :
Imports System.ComponentModel Imports System.Data Imports System.Data.SqlClient / <DataObject(True)> Public Class Produtos <DataObjectMethod(DataObjectMethodType.Select)> Public Shared Function GetTodasCategorias() As IEnumerable Dim con As New SqlConnection(GetConnectionString) Dim sel As String = "SELECT CategoryID, CategoryName " & "FROM Categories ORDER BY CategoryName" Dim cmd As New SqlCommand(sel, con) con.Open() Dim rdr As SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection) Return rdr End Function <DataObjectMethod(DataObjectMethodType.Select)> Public Shared Function GetProdutosPorCategoria(ByVal categoryID As String) As IEnumerable Dim con As New SqlConnection(GetConnectionString) Dim sel As String = "SELECT ProductID, ProductName, UnitPrice FROM Products " & "WHERE CategoryID = @CategoryID ORDER BY ProductID" Dim cmd As New SqlCommand(sel, con) cmd.Parameters.AddWithValue("CategoryID", categoryID) con.Open() Dim rdr As SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection) Return rdr End Function Private Shared Function GetConnectionString() As String Return ConfigurationManager.ConnectionStrings("MacorattiConnectionString").ConnectionString End Function End Class |
Estamos usando os namespaces System.Data e System.Data.SqlClient para acessar o banco de dados SQL Server.
Definimos instruções SQL do tipo SELECT para obter os dados das tabelas Products e Categories.
A segunda consulta usa o parâmetro CategoryID para filtrar os produtos por Categoria.
Como não estamos realizando atualizações na tabela estamos trabalhando com um objeto DataReader.
Note que estamos usando os atributos DataObject e DataObjectMethod na definição dos métodos.
Os atributos são uma forma de declarar informação para uma classe, métodos, etc. Eles não são obrigatórios e são usados apenas para ajudar o assistente de configuração a reconhecer os métodos das classes de acesso a dados.
Vamos definir a string de conexão no arquivo Web.Config conforme abaixo:
<?xml version="1.0"?> <!-- For more information on how to configure your ASP.NET application, please visit http://go.microsoft.com/fwlink/?LinkId=169433 --> <configuration> <connectionStrings> <add name="MacorattiConnectionString" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <compilation debug="true" strict="false" explicit="true" targetFramework="4.0"/> </system.web> </configuration> |
A string de conexão esta sendo obtida usando o ConfigurationManager:
A classe ConfigurationManager é uma nova classe que permite o acesso de forma programática ao arquivo de configuração e suas seções. Podemos destacar as seguintes funcionalidades desta classe.
A seguir temos os principais métodos e propriedades da classe ConfigurationManager:
Propriedade\Método | Descrição |
AppSettings | Obtêm os dados da seção <appSettings> do arquivo de configuração da aplicação. |
ConnectionStrings | Obtêm os dados da seção <ConnectionStrings> do arquivo de configuração da aplicação. |
OpenExeConfiguration | Abre o arquivo de configuração cliente especificado com um objeto. |
OpenMachineConfiguration | Abre o arquivo de configuração machine especificado com um objeto |
OpenWebConfiguration | Abre o arquivo de configuração da aplicação web especificado com um objeto. |
Para dar uma aparência mais suave a nossa página Defaut.aspx vamos incluir um arquivo de estilo (.css).
No menu Project-> Add New Item selecione o template Style Sheet e informe o nome Estilo.css
A seguir defina o código abaixo para definir o estilo neste arquivo:
body { font-family: Verdana, Helvetica, Sans-Serif; font-size: 85%; margin: 0; padding: 0; background-color: #d3d3d3; } p { margin-top: 15px; margin-bottom: 20px; } #page { width: 800px; margin: 0 auto; background-color: White; } #header { margin-bottom: 0; } #main { padding: 10px; margin-top: 0; } #ddlCategoria { width: 150px; } #ddlProdutos { color: #000000; background-color: #FFFFFF; border: 1px solid #999999; } .col1 { width: 100px; } .col2 { width: 200px; } .col3 { width: 100px; text-align: right; } |
Para podermos usar este arquivo de estilo temos que definir entre as tags head da página Default.aspx o seguinte código:
<style
type="text/css">
<link href="Estilo.css"
rel="stylesheet" type="text/css" />
</style>
Vamos agora definir o leiaute da nossa página Default.aspx a qual conterá os seguintes controles:
O dropdownlist ddlCategoria será vinculado ao controle ObjectDataSource1 que retorna uma lista de todas a categorias;
O controle DataList será vinculado ao controle ObjectDataSource2 que usa uma consulta parametrizada para retornar os produtos para uma categoria selecionada. O parãmetro CategoryID é obtido do controle ddlCategoria a partir da propriedade SelectedValue;
Ambos os controles ObjectDataSource utilizam a classe Produtos que contém métodos Shared que retorna as categorias e os produtos por categoria;
No controle DataList definimos um ItemTemplate para exibir os valores das colunas da tabela Products em uma tabela HTML definida no HeaderTemplate;
O código completo da Página Default.aspx pode ser vista abaixo:
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" runat="server"> <title>Lista de Produtos</title> <style type="text/css"> </style> <link href="Estilo.css" rel="stylesheet" type="text/css" /> </head> <body> <form id="form1" runat="server"> <div id="page"> <div id="header"> <asp:Image ID="Image1" runat="server" ImageUrl="~/maco10.gif" /> </div> <div id="main"> <p> Escolha uma Categoria: <asp:DropDownList ID="ddlCategoria" runat="server" DataSourceID="ObjectDataSource1" DataTextField="CategoryName" DataValueField="CategoryID" AutoPostBack="True"> </asp:DropDownList> <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GetTodasCategorias" TypeName="ListaProdutos.Produtos"> </asp:ObjectDataSource> </p> <asp:DataList ID="dlProdutos" runat="server" DataSourceID="ObjectDataSource2" CellPadding="3" GridLines="Vertical"> <HeaderTemplate> <table> <tr> <td class="col1">Código</td> <td class="col2">Produto</td> <td class="col3">Preço</td> </tr> </table> </HeaderTemplate> <ItemTemplate> <table> <tr> <td class="col1"> <asp:Label ID="lblID" runat="server" Text='<%# Eval("ProductID") %>' /> </td> <td class="col2"> <asp:Label ID="lblName" runat="server" Text='<%# Eval("ProductName") %>' /> </td> <td class="col3"> <asp:Label ID="lblUnitPrice" runat="server" Text='<%# Eval("UnitPrice", "{0:C}") %>' /> </td> </tr> </table> </ItemTemplate> <AlternatingItemStyle BackColor="#CCCCCC" /> <HeaderStyle BackColor="Black" Font-Bold="True" ForeColor="White" /> </asp:DataList> <asp:ObjectDataSource ID="ObjectDataSource2" runat="server" SelectMethod="GetProdutosPorCategoria" TypeName="ListaProdutos.Produtos" OldValuesParameterFormatString=""> <SelectParameters> <asp:ControlParameter ControlID="ddlCategoria" Name="CategoryID" PropertyName="SelectedValue" Type="String" /> </SelectParameters> </asp:ObjectDataSource> </div> </div> </form> </body> </html> |
Executando o projeto iremos obter:
Pegue o projeto completo aqui: ListaProdutos.zip
"E ele lhes disse: Na verdade vos digo que ninguém há , que tenha deixado casa, ou pais, ou irmãos, ou mulher, ou filhos, pelo reino de Deus, e não haja de receber muito mais neste mundo, e na idade vindoura a vida eterna." Lucas 18:29-30
Referências: