Utilizarei o Visual Studio 2008 com o SQL Server 2005 e o banco de dados Northwind, porém os mesmos passos podem ser seguidos no Visual Studio 2005 com o SQL Server 2000.

Crie um novo projeto Web no Visual Studio, logo em seguida clique com o botão direito sobre a solução e escolha Add / New Item.

Adicionar novo item

Na janela que se abrirá, selecione o Item DataSet e atribua o nome DsTerritorio.

Novo Dataset

Com o DataSet criado, clique com o botão direito dentro da janela do DataSet, escolha Add / TableAdapter, abrirá uma janela solicitando qual conexão com o banco de dados será utilizado para a construção do TableAdapter, crie a conexão com o SQL Server e salve com o nome NorthwindConn e clique em Next.

Adicionar Table Adapter

Selecionar conexãao

Na próxima janela selecione como o TableAdapter acessará o banco de dados, as opções possíveis são: SQL statements, criar nova Stored Procedure ou utilizar uma Stored Procedure já existente no banco de dados.

Deixe a opção Use SQL statements marcada e clique em Next.

Selecionar modo de acesso

A próxima janela é onde se insere o código SQL para o retorno dos dados, porém você pode utilizar o Query Builder, que é a ferramenta visual para construção de instruções SQL, portanto clique no botão Query Builder.

Entrada SQL

Após clicar no botão Query Builder, aparecerão duas janelas, a janela do próprio Query Builder e a janela de Add Table, a segunda janela já com as tabelas existentes no banco de dados.

Procure e selecione a tabela Region, em seguida, clique em Add. A tabela Region aparecerá no Query Builder.

Adicionar Tabela Query builder

Clique em Close, em seguida, selecione as duas colunas da tabela Region (RegionID e RegionDescription). Agora clique em Execute Query.

Query builder Region

Se o resultado do Execute Query for igual à figura acima, clique em Ok. A próxima janela solicitará nomes para os métodos de Fill e Return que por padrão são Fill e GetData respectivamente.

Para a tabela Region, deixe os nomes sugeridos e clique em Next. A próxima janela exibirá o sumário da criação do TableAdapter. Clique em Finish.

Definir nome do método

Table adapter criado

Agora já é possível visualizar o TableAdapter dentro do DataSet dsTerritorio.

Dataset Territorio

Ainda dentro do DataSet dsTerritorio, crie outro TableAdapter. Novamente, clique com o botão direito dentro do DataSet, escolha Add / TableAdapter, escolha a conexão com a base de dados, também escolha Use SQL statements.

Na janela do Query Builder, adicione a tabela Territories, selecione todas as colunas. Na linha RegionID, insira o parâmetro @RegionID na coluna Filter. O parâmetro será responsável por aplicar o filtro de qual região o SQL retornará os territórios.

Query builder territories

Na janela de definições dos métodos, acrescente a expressão ByRegionID, após Fill e GetData. Dessa maneira apenas pelo nome do método é possível saber que um parâmetro chamado RegionID é esperado.

Definir nome método Territories

Dataset Territorio completo

Agora que concluiu a criação do DataSet dsTerritorio, crie o DataSet dsVendedor, e dentro dele crie um TableAdapter com o SQL abaixo.

SELECT 	EmployeeTerritories.EmployeeID,
	Employees.FirstName + ' ' + Employees.LastName AS FullName,
	EmployeeTerritories.TerritoryID
FROM Employees INNER JOIN EmployeeTerritories
	ON Employees.EmployeeID = EmployeeTerritories.EmployeeID
WHERE (EmployeeTerritories.TerritoryID = @TerritoryID)

Entrada SQL employees

Acrescente ByTerritoryID na definição dos métodos Fill e GetData.

Após clicar em Finish, o TableAdapter criado estará com os nomes DataTable1 e DataTable1TableAdapter, altere-os para Employee e EmployeeTableAdapter.

Table Adapter employee

Crie um novo DataSet chamado dsCliente, e também crie um novo TableAdapter com o código abaixo.

SELECT  Customers.CustomerID, Customers.CompanyName, CustomerEmployee.EmployeeID
FROM (SELECT CustomerID, EmployeeID
	FROM Orders
	GROUP BY CustomerID, EmployeeID) AS CustomerEmployee INNER JOIN
	Customers ON CustomerEmployee.CustomerID = Customers.CustomerID
WHERE (CustomerEmployee.EmployeeID = @EmployeeID)

Para os nomes dos métodos Fill e GetDate, não esqueça de adicionar ByEmployeeID em ambos.

Como no TableAdapter de vendedores, os nomes deste TableAdapter também não estão corretos, altere-os para Customers e CustomersTableAdapter respectivamente.

Para concluir a construção dos DataSets, crie mais um chamado dsPedido e também crie um novo TableAdapter com o código abaixo.

SELECT OrderID, CustomerIR, EmployeeID, OrderDate, ShippedDate,
	ShipName, ShipAddress, ShipCity, Shipcountry
FROM Orders
WHERE (CustormerID = @CustomerID) AND
	(EmployeeID = @EmployeeID)

Acrescente ByCustomerIDEmployeeID aos métodos Fill e GetData e clique em Finalizar.

Agora crie o último TableAdapter chamado OrderDetails conforme a figura abaixo.

SQL orderdetails

Após a criação de todos os DataSets (Território, Vendedor, Cliente e Pedido) o projeto deve estar conforme a figura abaixo.

Arquivos projeto

Copie os seguintes arquivos do diretório de instalação do WebOrb (por padrão em c:inetpubwwwrootweborb30) para o diretório do projeto .NET.

/weborb.config
/bin/weborb.dll
/WEB-INF

Adicione o código XML abaixo ao web.config do projeto .NET.

[like-gate]

 
   
     
     
   
 

É preciso referenciar o weborb.dll ao projeto, para isso no Solution Explorer do Visual Studio, clique duas vezes sobre a opção My Project, em seguida clique em References e depois em Add / References…

My project

Clique na aba Browse, localize o diretório Bin do projeto, selecione o arquivo weborb.dll e clique em OK, salve o projeto e feche a janela My Project.

Weborb.dll

Clique com o botão direito sobre a solução e escolha Add / New Item, porém escolha Class e dê o nome de csFlex.vb.

Nesta classe serão criados os métodos de chamada e retorno dos DataSets e TableAdapters criados anteriormente, através desses métodos é que a comunicação entre o .NET e o Flex ocorrerá.

Insira o código abaixo ao arquivo csFlex.vb

Imports Weborb.Service

Public Class csFlex

    Public Function getRegion() As DataTable
        Return New dsTerritorioTableAdapters.RegionTableAdapter().GetData()
    End Function

    Public Function getTerritories(ByVal RegionID As String) As DataTable
        Return New dsTerritorioTableAdapters.TerritoriesTableAdapter().GetDataByRegionID(RegionID)
    End Function

    Public Function getEmployee(ByVal TerritoryID As String) As DataTable
        Return New dsVendedorTableAdapters.EmployeeTableAdapter().GetDataByTerritoryID(TerritoryID
    End Function

    Public Function getCustomers(ByVal EmployeeID As String) As DataTable
        Return New dsClienteTableAdapters.CustomersTableAdapter().GetDataByEmployeeID(EmployeeID)
    End Function

    Public Function getOrders(ByVal CustomerID As String, ByVal EmployeeID As String) As DataTable
        Return New dsPedidoTableAdapters.OrdersTableAdapter().GetDataByCustomerIDEmployeeID(CustomerID, EmployeeID)
    End Function

    Public Function getOrderDetails(ByVal OrderID As String) As DataTable
        Return New dsPedidoTableAdapters.OrderDetailsTableAdapter().GetDataByOrderID(OrderID)
    End Function

End Class

Salve e feche o arquivo csFlex, agora compile o projeto. Caso o Visual Studio sinalize algum erro, volte e execute os passos novamente.

Antes de criar a interface no Adobe Flex, crie a aplicação Web no Internet Information Services (IIS) com o nome do projeto, verifique se ao acessar o endereço através do navegador uma página em branco é exibida.

Agora já com a aplicação web configurada no IIS, abra o Adobe Flex Builder 3, adicione um novo projeto (File / New / Flex Project).

Agora defina o nome do Projeto, se a opção Use default location estiver marcada, desmarque-a e localize o endereço do projeto .NET e dentro da pasta do projeto crie uma nova pasta chamada FlexSrc. O Project location do Flex deve ficar como a figura abaixo. A opção de Application type deixe marcado Web Application, e em Server technology selecione ASP.NET. Clique em Next.

Definir nome projeto

Na próxima janela, na opção Server selecione Use Internet Information Services (IIS), em Web application root informe o diretório raiz da aplicação web definida no IIS e no campo Web application URL informe o endereço da aplicação no IIS. Após clicar no botão Validate Configuration, na parte superior da janela o Flex Builder deve ser informar: “The web application root and URL are valid”, caso apareça outra mensagem, os endereços informados não estão corretos, corrija antes de prosseguir.

Na mesma janela, um pouco abaixo está definida a pasta bin-debug como local a serem salvos os arquivos Flex compilados, deixe o nome que o Builder sugeriu e clique Next.

Definir servidor

Na última janela de configuração do projeto Flex, é possível definir qual a pasta onde o Flex Builder salvará os arquivos fontes, bem como qual o nome do primeiro arquivo do projeto a ser criado.

Deixe os campos preenchidos como o Builder sugeriu e clique em Finish. Após alguns segundos o Adobe Flex Builder 3 exibirá o arquivo ArtigoFlex.mxml pronto para o início da construção da interface da aplicação.

Adobe Flex Builder

Porém antes começar a codificar é necessário incluir um argumento de compilação ao projeto, pois sem esse argumento o Flex não conseguirá acessar os métodos construídos na classe csFlex. Para incluir o argumento, clique com o botão direito sobre o nome do projeto no Flex Navigator e em seguida clique em Properties. Com a janela de propriedades aberta, clique sobre a opção Flex Compiler, e insira o argumento após o argumento –locale en_US

-services c:Inetpubwwwrootweborb30web-infflexservices-config.xml

Proprieda do Flex Compiler

Após inserir o argumento services, clique em OK.

Agora com o projeto corretamente configurado e pronto para comunicar com o .NET é possível iniciar a construção da interface, para tanto crie um painel, entre as tags , com o título Painel de Vendas, esse painel terá um tamanho ajustável conforme as dimensões do navegador do cliente, para isso configure as propriedades left, right, top e bottom, todos com o valor 10.



É possível verificar como o projeto está ficando, bastar clicar no Play.

Executar aplicação Flex

Dentro do painel, crie um canvas na cor cinza.




Dentro do canvas coloque os labels e comboboxs que serão utilizados para selecionar região, território, vendedor e cliente, coloque também dentro do canvas o botão consultar.










A propriedade horizontalCenter define qual a distância em pixel que um objeto está do centro da página, valores negativos representam objetos a esquerda do centro da tela e valores positivos representam objetos a direita, os valores definidos garantem que os objetos estarão sempre centralizados.

labelField é a propriedade que define qual o campo que será exibido como label do combobox. O Adobe Flex trabalha de maneira diferente do .NET quando o assunto é combobox ou dropdownlist, pois no .NET é possível definir apenas dois valores ao dropdownlist, o datatextfield e o datavalueFfeld, já no Adobe Flex só se define qual será o valor de exibição do combobox, labelField, pois cada linha de opção do combobox é um objeto com propriedades. Essas propriedades são as colunas que retornaram do banco de dados, logo você não tem acesso a somente duas colunas como dropdownlist, você tem acesso a todas as colunas que retornaram do banco de dados.

A propriedade Y define qual a distância que o objeto tem do topo do componente ao qual ele está pertencendo, neste caso, y=”12” diz ao Flex que o label está a 12 pixel do topo do canvas.

Após o canvas inclua um datagrid onde serão exibidos os pedidos resultantes da consulta ao banco de dados.



	
	
	
	
	
	
	


Para fazer a comunicação entre a interface Flex e a aplicação server-side .NET utilize o componente RemoteObject do Adobe Flex 3.



	
	
	
	
	
	


A propriedade destination deve sempre ser “GenericDestination” para a comunicação através do weborb, a propriedade source deve ser preenchida com o nome do projeto .NET e a classe que será acessada, então neste caso será “ArtigoFlex.csFlex”.

A propriedade showBusyCursor seta se será exibido ou não o relógio como cursor do mouse enquanto alguma requisição ao .NET estiver sendo feita. E finalmente, fault define qual função será disparada caso algum erro ocorra durante alguma requisição do .NET.

Os métodos (

A propriedade result define qual função será disparada após o retorno da requisição ao .NET.

É necessário agora construir as funções, faultHandler, gotRegion, gotTerritories, gotEmployee, gotCustomers, gotOrders e gotOrderDetails. As funções são escritas na linguagem Action Script 3.0


	

Nesta parte do código além do bloco das tags de inicio e fim de script, também estão declaradas as importações das bibliotecas ResultEvent, Alert e FaultEvent que serão utilizadas logo mais.

Agora crie a função faultHandler

private function faultHandler(event:FaultEvent):void
{
	Alert.show(event.fault.faultString, "Erro");
}

A função faultHandler recebe um parâmetro do tipo FaultEvent que será exibido para o usuário através do Alert.show quando algum erro ocorrer durante a requisição ao .NET.

Agora crie os métodos de preenchimento dos valores do combobox região.

private function bindRegion():void
{
	roNet.getRegion();
}

private function gotRegion(event:ResultEvent):void
{
	cbRegion.dataProvider = event.result;
	cbRegion.selectedIndex = 0;
	bindTerritories();
}

No código acima foram criadas duas funções, bindRegion e gotRegion. A função bindRegion chama o método getRegion do remote object roNet.

Após o retorno da requisição ao método roNet.getRegion, a função gotRegion é disparada recebendo um parâmetro do tipo ResultEvent que contém o retorno do método getRegion, o retorno é associado como dataProvider do combobox cbRegion, em seguida é selecionado o índice zero dos dados retornados. Após a seleção do índice, a função bindTerritories() é disparada.

private function bindTerritories():void
{
	roNet.getTerritories(cbRegion.selectedItem.RegionID);
}

private function gotTerritories(event:ResultEvent):void
{
	cbTerritory.dataProvider = event.result;
	cbTerritory.selectedIndex = 0;
	bindEmployee();
}

Assim como a função bindRegion, bindTerritories chama um método do remote object roNet, porém agora o método chamado é o getTerritories, esse método espera como parâmetro o código da região, por isso o parâmetro informado é o cbRegion.selectedItem.RegionID. RegionID é uma propriedade que o dataProvider do cbRegion passou a ter após a atribuição do event.result. Abaixo estão as demais funções para a preparação dos comboboxs.

private function bindEmployee():void
{
	roNet.getEmployee(cbTerritory.selectedItem.TerritoryID);
}

private function gotEmployee(event:ResultEvent):void
{
	cbEmployee.dataProvider = event.result;
	cbEmployee.selectedIndex = 0;
	bindCustomers();
}

private function bindCustomers():void
{
	roNet.getCustomers(cbEmployee.selectedItem.EmployeeID);
}

private function gotCustomers(event:ResultEvent):void
{
	cbCustomer.dataProvider = event.result;
	cbCustomer.selectedIndex = 0;
}

Para que quando o usuário acesse a aplicação os comboboxs já sejam preenchidos é necessário definir a propriedade creationComplete na tag mx:Application.

Com essa propriedade definida, depois de criada a aplicação, a função bindRegion será disparada iniciando assim a população de todos os comboboxs, pois eles estão aninhados.

Também é preciso configurar os comboboxs para que depois de alterada a seleção de um dos filtros, os outros sejam alterados também, para isso será utilizada a propriedade change.




Agora faça a população da datagrid,

private function bindOrders():void
{
	roNet.getOrders(cbCustomer.selectedItem.CustomerID,cbEmployee.selectedItem.EmployeeID);
}

private function gotOrders(event:ResultEvent):void
{
	dgPedido.dataProvider = event.result;
}

Para que a função bindOrders seja disparada ao clicar o botão Consultar, defina a propriedade click do botão btConsultar.

Para finalizar o projeto, crie a estrutura para exibir os detalhes dos pedidos. Para isso crie uma TitleWindow, em File / New / MXML Component, defina o nome de orderDetails, baseado em TitleWindow

Criar novo componente

Utilize o código abaixo para a TitleWindow orderDetails.




	


	
	
	
	
	
	



Crie as funções para a população da TitleWindow orderDetails dentro do script do arquivo ArtigoFlex.mxml

import mx.managers.PopUpManager;

public function bindOrderDetails():void
{
	roNet.getOrderDetails(dgPedido.selectedItem.OrderID);
}

private function gotOrderDetails(event:ResultEvent):void
{
	var popUp:orderDetails = orderDetails(PopUpManager.createPopUp(this, orderDetails, true));
	PopUpManager.centerPopUp(popUp);
	popUp.dgOrderDetails.dataProvider = event.result;
}

Altere a primeira coluna da datagrid dgPedido para o código abaixo para inserir o botão para exibir os detalhes do pedido.




	
		
	



Salve o projeto e execute, o resultado deve ser como o das figuras abaixo.

Datagrid preenchida

Datagrid orderDetails preenchida

Baixe o código fonte completo.

[/like-gate]

Divirta-se.

About Author

You may also like

16 Response Comments

  • Daniel Schmitz  26/01/2009 at 08:18

    Muito legal! Bem explicado com muitas imagens, gostei !! Como fica o deploy disso? só upar para o server ?

    • Igor Musardo  04/02/2009 at 23:15

      @Daniel,
      Basicamente é só fazer o upload para o servidor dos arquivos do .NET e do Flex compilados.

  • Leandro Medeiros  06/02/2009 at 11:00

    Olá Igor!!! Primeiramente, parabéns pelo artigo! Está ótimo.
    Estou enfrentando um problema em meu caso. Estou criando uma interface que acessa uma DLL, porém qdo o método na interface é invocado, tenho esse erro:

    Channel.Security.Error error Error #2048: Security sandbox violation: http://seginf06/flex/FlexSrc/bin-debug/FlexTeste.swf cannot load data from https://seginf06/flex/FlexSrc/bin-debug/weborb.aspx. url: ‘https://seginf06/flex/FlexSrc/bin-debug/weborb.aspx’

    sabe o q pode ser?

    Obrigado!

    • Igor Musardo  09/02/2009 at 07:03

      @Leandro,

      Você já fez o teste de copiar a DLL do seu projeto .NET para a pasta BIN do WebOrb no Inetpub (c:inetpubwwwrootweborb30bin)?
      Ao copiar a DLL para a pasta BIN, você deve acessar a aplicação (http://localhost/weborb30/). Na aba Management, no lado esquerdo da tela deve ser exibida a sua DLL, ao clicar no [+] as classes e métodos públicos da sua DLL ficam visíveis e disponíveis para serem invocadas.

      Faça o teste se nesta tela o invocar dos métodos estão funcionando.

      Se puder me enviar um printscreen ou até mesmo o código-fonte acho que poderei ajudar um pouco mais.

      Abraços,
      Igor Musardo

  • Vinícius Sandim  24/03/2009 at 21:14

    Olá Igor, boa noite…

    Esses dias estou tentando configurar o serviço de mensageria do Flex usando o FluorineFx, com as classes Consumer e Producer.

    Porém todos exemplos que encontrei, usam o Live Cycle Data Services, aparentemente o FluorineFx não tem essa feature implementada.

    Gostaria de saber se com o WebOrb for .Net Community Edition consigo utilizar este serviço sem a necessidade do LCDS?

    Desde já agradeço a atenção.

    Att,

    Vinícius Sandim

  • roger  06/04/2009 at 22:37

    Oi Igor!
    Estou tentando enteder seu exemplo e tem um componente chamado ArtigoFlex.dll que não consigo recriá-lo.Pode me ajudar? Seu artigo é ótimo!

    • Igor Musardo  07/04/2009 at 07:24

      Roger,
      Primeiramente obrigado pelo Feedback.
      O arquivo ArtigoFlex.dll é gerado automaticamente pelo Visual Studio durante a compilação do projeto .NET, visto que o nome do projeto é ArtigoFlex, caso tenha dado outro nome ao projeto .NET, o mesmo nome será atribuída a DLL.
      Qualquer dúvida por favor entre em contato.
      Abraços,
      Igor Musardo

  • Junior  19/04/2009 at 01:07

    Valeu Cara Otimo Artigo,

    Meu nome é Junior,
    estou iniciando em Flex
    Gostaria de saber onde posso encontrar material para estudo

    Att. Junior

  • Paulo Fernando  03/05/2009 at 03:03

    amigos alguém poderia me ajudar? tenho uma aplicação feita em flex q está hospedada em um servidor windows q possui um banco de dados SQL mas porém nao está logando no sistema… ocorre que penso ser a string de conexão mas ja tentei tudo q podia e tudo q meu suporte do server informou e nao tem jeito… por acaso alguém se dispoe a ajudar ou indicar quem poderia?
    obrigado

  • Rick  19/05/2009 at 12:06

    Muito bom.
    A falta de livros e referencias nas novas tecnologias da adobe é irritante, rsrs.

  • Igor Musardo  09/11/2009 at 12:20

    @Emerson,

    Não precisa ter o WebOrb instalado no servidor, basta apenas deixar a dll do Weborb na pasta bin do projeto.

    Qualquer dúvida, entre em contato.

    Abs,
    Igor Musardo

  • Lobo Jr  13/01/2010 at 15:50

    Gostaria de ver um exemplo usando DTO para trafegar dados, sem uso de DataSet. alguém já viu por aí?

  • Igor Brito  23/02/2010 at 17:04

    Olá Igor,

    Começei a trabalhar com projetos Flex a partir deste e seu post e inclusive até pude participar do Flex for Kids para acompanhar as palestras sobre este assunto. Estou com uma dúvida técnica a respeito da integração Flex com .NET. Gostaria de saber se posso dentro do Flex percorrer um DataSet e não apenas um DataTable conforme mostra o seu exemplo? Minha necessidade é carregar vários combos e grids porém eu não queria fazer várias requisições ao servidor e sim apenas uma para trazer um DataSet com todos os DataTables necessários para popular meus combos e grids da página. Isso é possível? Caso não seja, você sabe de alguma outra solução que não seja ficar chamando os DataTables do servidor de forma separada para cada componente?

    Desde já muito obrigado!

  • Igor Brito  23/02/2010 at 17:16

    OBS: Na verdade no seu exemplo não percorre um DataTable, apenas popula no DataGrid, porém consigo percorrer os dados dele no event.result. Gostaria de saber se consigo fazer um loop em um Data Set dentro do flex para não ter que fazer várias chamadas ao servidor!

    • Igor Musardo  24/02/2010 at 12:05

      Bom dia chará!

      Imagino que seja possível sim receber o DataSet apenas mudando o tipo de retorno do método no .NET, porém o Flex imagino irá converter para um grande ArrayCollection.

      Porém, você irá trazer uma grande quantidade de informação que justifique esse acomplamento e aumento de complexidade para manutenção?

      Eu em todos os sistemas que desenvolvi em Flex e .NET, mesmo trazendo vários dados, nunca tive problemas de performance por causa do tráfego dos dados, e sim por causa de um itemrenderer mal utilizado, um efeito sobrando, uma consulta ao SQL Server mal construída o que a tornava lenta. Enfim todos problemas foram referentes à outros pontos que a transferência entre o .NET e Flex que é de forma binária se utilizar o WebOrb ou Fluorine.

      A minha dica é: Não se preocupe em EXCESSO com performance (diferente de não se preocupar) antes de efetivamente você ter um problema de performance. Pois esse tipo de preocupação em um estágio inicial do desenvolvimento sempre te leva à uma arquitetura rígida e pouco escalável (mesmo ela sendo pensada para conseguir escalabilidade).

      Exemplos reais deste modelo: Orkut, você se lembra das mensagens: Bad server no donuts for you, ou então o próprio Twitter com suas famosas baleiadas.

      Espero ter ajudado!