Skip Navigation Links



Translate this page now :



»Programação
»Programação.NET
»Banco de Dados
»Webdesign
»Office
» Certificações Microsoft 4
»Treinamentos4
»Programação 4
»Webdesign«
»Office & User Tips«
»Grupos de UsuĆ”rios
»CĆ©lulas AcadĆŖmicas«
intcontpiada : 118
O grande sƔbio
Você já está cadastrado e participa do grupo de usuários de sua cidade ? Se não, comente o porque.
 
 
FaƧa um pequeno teste com 10 questƵes de VB
.:.
Teste seus conhecimentos em Visual Basic, SQL Server e ASP 3.0 com nossas provas on-line
.:.
Aprimore seus conhecimentos em programaĆ§Ć£o com nosso treinamento on-line de lĆ³gica de programaĆ§Ć£o
.:.
Veja nosso calendƔrio de treinamentos
Gostou da PƔgina?
Então

para um amigo!

Pesquisa personalizada
Pesquisar Dicas:

 







Construindo uma Cesta de Compras com o ASP.NET MVC

O objetivo deste artigo é fazer a construção de uma cesta de compras, passo-a-passo, utilizando o ASP.NET MVC.

Como o passo-a-passo em si já será longo, não irei neste artigo fazer uma análise mais detalhada dos passos, apenas executa-los. No artigo Analisando uma aplicação ASP.NET MVC você encontra uma análise bem mais detalhada do resultado da construção, o que tem de bom e o que tem de ruim.

Este artigo está sendo construido para fins de análise da tecnologia, não recomendo que o sigam sem analisar todos os pontos levantados no conjunto de 3 artigos que estou publicando sobre este tópico. No primeiro artigo, encontrarão informações mais conceituais sobre o ASP.NET MVC

Requisitos

Para executar este exemplo você precisa do seguinte :

- SQL Server 2000 ou superior

- Banco de dados de exemplo - Northwind

- Visual Studio 2008 (não foi feito teste com a versão express, alguns passos podem ser ligeiramente diferentes)

- MVC Framework Preview 2 (não foi testado com o Preview 3, mas provavelmente não haverá diferença)

- Tabela "Cesta" criada no banco Northwind com a seguinte estrutura :

UserId varchar(50) not null primary key
ProductId int not null primary key
quant int not null
Preco smallmoney

Passo-a-Passo

1) Crie um projeto ASP.NET MVC Web Application

Após a criação do projeto, observe o solution explorer, todo o conteúdo é dividido em pastas : Models, Views, Controllers e Content. As 3 primeiras dispensam mais explicações, a pasta content é utilizada para imagens, arquivos css, enfim, outros arquivos de conteúdo do site

2) Na pasta models, crie um dataset chamado dsNorth

Poderia trabalhar com Linq, qualquer tipo de origem de dados pode ser utilizada na pasta models, mas para não inserir uma complexidade extra que está fora do que desejamos analisar, vou fazer o exemplo com um dataset.

3) Crie um tableAdapter e uma dataTable products, trazendo os campos productid, productname, unitprice e unitsinstock

4) Na pasta Controllers, clique com o botão direito e crie uma Controller Class chamada ProductsController

5) No productsController crie a sub listar com o seguinte código :

    Public Sub Listar()
        Dim ta As New dsNorthTableAdapters.ProductsTableAdapter()
        Dim dados As New dsNorth
        ta.Fill(dados.Products)
        RenderView("ListarProdutos", dados.Products)
    End Sub

A instrução RenderView é uma instrução para que uma página, que no conceito do MVC é uma view (algo mais amplo e versátil que uma página) seja renderizada para o client.

A instrução pode ser comparada com uma especie de Redirect, mas acontece entre a execução do Controller e a execução da view, ao invés de ser entre duas páginas como o caso do redirect.

Observe que na instrução RenderView nós transmitimos o conjunto de dados que a view irá utilizar. Também não usamos um nome de arquivo, apenas um nome de view. Isso permite uma mudança drástica na view, até mesmo em termos de tecnologia, sem afetar o controller.

6) Dentro da pasta views, crie a pasta Products

Para cada controller, criamos uma pasta dentro da pasta views e nesta pasta inserimos todas as views que o controller irá renderizar

7) Dentro da pasta Products crie uma nova view chamada ListarProdutos.aspx

A diferença de uma view para uma página comum é a herança que é utilizada no code-behind, ViewPage ao invés de Page

8) Altere a herança no code-behind da view para que fique da seguinte forma :

Public Partial Class ListarProdutos
    Inherits System.Web.Mvc.ViewPage(Of dsNorth.ProductsDataTable)
 
 
End Class

Utilizando Generics na herança da view esta restringe o tipo de informação que poderá receber, apenas aceitando productsDataTable.

Outro beneficio é o fato de trabalharmos de forma tipada com a productsdatatable

9) Utilizando a instrução Table->Insert Table, insira uma tabela com duas linhas e 4 colunas

Altere as seguintes características :

CellPadding : 0
CellSpacing : 0
Border : 2
Color : Black

As configurações criadas geram um style chamado style1 que é aplicado na table, porém ao contrário do que normalmente esperamos, o style só tem efeito na table como um todo e não em cada célula. Um exemplo claro disso é a borda, que fica apenas ao redor da tabela.

10) Através do menu view, abra a janela Apply Styles

11) Com o botão direito no estilo, selecione "Modify Style"

Observe que na janela que é exibida os elementos que foram aplicados nesta regra de estilo aparecem em destaque, em negrito.

12) Altere o nome do estilo para ".Tabela"

13) Na opção Table, altere o borderspacing para 0 (em CSS será equivalente ao cellspacing)

14) Altere o Border-collapse para collapse

15) Utilizando a barra de seleção (parte inferior da tela) clique na tabela que ainda está com o style1 aplicado

16) Clique no estilo ".Tabela" que está na janela Apply Styles.

Isso irá aplicar o estilo .Tabela para a nossa table que ainda estava com Style1 (que não existe mais, pois trocamos de nome)

17) Com o botão direito no estilo ".Tabela" selecione "New Style Copy..."

18) No novo estilo, indique ".Tabela tr td" para especificarmos características de cada célula

19) Em box, defina a Margin e o Padding como 0

20) Em table defina borderspacing como 0 e border-collapse como collapse

21) Preencha as colunas da 1a linha respectivamente com ProductID, ProductName, UnitPrice e Comprar

22) Selecione a linha e faça as seguintes formatações :

A) Defina o tipo de fonte como verdana

C) Centralize o conteúdo

D) Defina a cor de fundo como uma cor escura

E) Defina a cor da fonte como branco

F) Coloque a fonte em negrito

Neste ponto foi criado um novo estilo chamado style1 que pode ser observado na janela apply styles

23) Clique com o botão direito no Style1, utilize "Modify Style" e altere o nome do estilo para Titulo

24) Selecione a linha da tabela e clique no estilo Titulo da janela Apply Styles para fazer sua aplicação

25) Selecione a 2a linha e defina uma cor agradável no fundo

26) Altere o nome do estilo que é gerado (style1) para estiloLinha

27) Selecione novamente a mesma linha (que encontra-se novamente em branco)

28) Altere a cor de fundo para uma cor agradável e que contraste com a cor anterior

29) Altere o nome do style1 criado para estiloLinhaAlt

30) Altere a visualização para o modo source

31) Logo abaixo do fechamento do primeiro TR, abra um trecho de código ASP

<% %>

32) Defina as variáveis i, estiloLinha e estiloLinhaAlt :

Dim i As Integer, estiloLinha = "estilolinha", estiloLinhaAlt = "estilolinhaAlt"

33) Faça um laço (for each) para cada linha da tabela recebida pela View

        For Each d As siteCesta.dsNorth.ProductsRow In ViewData
 
        Next

Observe que a variável ViewData contém os dados transmitidos para a view a partir do Controller. Pode estar tipada (no caso do uso do generics) ou não.

34) Coloque a 2a linha da tabela em meio ao código ASP, intercalando ASP com HTML

   1: <%
   1:  
   2: Dim i As Integer, estiloLinha = "estilolinha", estiloLinhaAlt = "estilolinhaAlt"
   3:  
   4: For Each d As siteCesta.dsNorth.ProductsRow In ViewData
   5:  
%>
   2: <tr>
   3: <td>
   4: &nbsp;</td>
   5: <td>
   6: &nbsp;</td>
   7: <td>
   8: &nbsp;</td>
   9: <td>
  10: &nbsp;</td>
  11: </tr>
  12: <%
   1:  Next 
%>

 

35) Utilize a variável criada no for/each (d) para exibir os campos em seus devidos locais

   1: <tr>
   2: <td>
   3: <%= d.ProductID %></td>
   4: <td>
   5: <%= d.ProductName %></td>
   6: <td>
   7: <%= String.Format("{0:C}", d.UnitPrice) %></td>
   8: <td>
   9: &nbsp;</td>
  10: </tr>

 

O próximo passo será permitir que o usuário faça a compra. Para isso precisaremos preparar o Model para as tarefas envolvidas na compra, criar um novo método no controller para finalmente criar um formulário para executar este método na página.

36) Adicione um novo tableAdapter no dsNorth, apontando para a tabela "Cesta" no northwind, trazendo os campos UserID, ProductId, Preco, Quant

 

37) Ao montar o select, inclua um filtro por UserId, pois a cesta nunca será exibida por completo, sempre filtrada por usuário

38) Desmarque a opção GenerateDbDirectMethods

Cada elemento do dsNorth (Products, Cesta) é uma classe responsável por gerenciar um determinado assunto de negócios - Produtos e Cesta de compras. Desta forma, iremos inserir em cada uma dessas classes os métodos necessários para fazer o gerenciamento a nível de dados.

39) Crie um método no tableAdapter "Cesta" chamado InserirProduto e que execute um simples insert na tabela cesta

O processo de uma compra envolve verificar se o produto já encontra-se ou não na cesta de compras do usuário, caso já esteja, haverá uma atualização da quantidade, caso não esteja, uma inserção. A inserção acabamos de criar, falta a verificação se o produto já está na cesta de compra e uma atualização da quantidade para caso esteja

40) Adicione a seguinte query no tableAdapter de "Cesta" com o nome de ExisteProdutoCesta :

   1: SELECT 1
   2: FROM Cesta
   3: WHERE (UserId = @UserId) AND (ProductId = @ProductId)

 

O valor 1 equivale a um true indicando que o produto já existe na cesta de compras.

41) Monte um método de update chamado AdicionarQuantidade com a seguinte instrução SQL :

   1: UPDATE Cesta
   2: SET Quant = Quant + @Quant
   3: WHERE (UserId = UserId) AND (ProductId = ProductId)

 

42) No tableAdapter de Products, crie uma query scalar com o nome de ObterPrecoProduto e o seguinte SQL :

   1: SELECT UnitPrice
   2: FROM Products
   3: WHERE (ProductID = @ProductID)

 

43) No ProductsController crie uma função Comprar com o seguinte código :

    Public Function Comprar(ByVal idProduto As Integer, _ 
                ByVal idusuario As String) As Boolean
        Dim ta As New dsNorthTableAdapters.ProductsTableAdapter
        Dim ta2 As New dsNorthTableAdapters.CestaTableAdapter
        Dim qtd As Integer = Me.ReadFromRequest("txtquant")
        If ta2.ExisteprodutoCesta(idusuario, idProduto).HasValue Then
            ta2.AdicionarQuantidade(qtd, idusuario, idProduto)
        Else
            Dim preco As Decimal
            preco = ta.ObterPrecoProduto(idProduto)
            ta2.InserirProduto(idusuario, idProduto, qtd, preco)
        End If
 
        RedirectToAction("Listar")
    End Function

A) A função recebe parâmetros, idProduto e idUsuario. Essa função será chamada via método POST, a passagem de parâmetros para uma função chamada via POST é algo novo.

B) A função recupera a quantidade que o usuário pediu para adquirir através do método ReadFromRequest

C) A função usa um método de um dos objetos de negócio (Cesta) para verificar se existe o produto na cesta de compras

D) Se existe, é utilizado o método adicionar quantidade para fazer uma adição na quantidade existente

E) Se não existe, utilizamos o obterPrecoProduto para recuperar o preço e em seguida inserimos o produto na cesta

F) Redirecionamos para a listagem. Observe o uso da instrução específica RedirectToAction para fazer isso

Repare que o controller está fazendo o papel de um componente de processo, como costumo chamar

44) Voltando para a view, na última coluna da 2a linha (comprar), crie duas variáveis que serão utilizadas para fazer a chamada do método "comprar", conforme o código abaixo :

   1: <% 
   2: Dim id As Integer
   3: Dim usuario As String
   4:  
   5: id = d.ProductID
   6: usuario = Request.AnonymousID 
   7: %>

 

45) Estamos utilizando o AnonymousID para identificar o usuário, então precisaremos habilitar o anonymousID no web.config, além de mudar a autenticação para forms, da seguinte forma :

   1: <anonymousIdentification enabled="true" />
   2: <authentication mode="Forms"/>

 

46) Crie um formulário HTML, logo depois da declaração das variáveis :

   1: <% 
   2: Dim id As Integer
   3: Dim usuario As String
   4:  
   5: id = d.ProductID
   6: usuario = Request.AnonymousID
   7: Using Html.Form(Of siteCesta.ProductsController)(New Action(Of siteCesta.ProductsController)(Function(x As siteCesta.ProductsController) 
                       x.Comprar(id, usuario)))
   8:  
   9: End Using
  10: %>

 

Temos um elemento HTML que funciona como helper, nos auxilia na montagem de alguns elementos HTML para evitar que tenhamos que lidar diretamente com o código HTML.

Neste exemplo estou utilizando o método Form em seu formato genérico. Entre parêntesis indico o tipo do controller para o qual o form irá transmitir as informações : ProductsController.

Por fim, utilizamos o parâmetro x para chamar o método comprar passando como parâmetros o id e o usuário

47) Criar uma textbox para a quantidade com o trecho de código abaixo :

   1: <% Using Html.Form(Of siteCesta.ProductsController)(New Action(Of siteCesta.ProductsController)(Function(x As siteCesta.ProductsController) 
                       x.Comprar(id, usuario))) %>
   2: <%= Html.TextBox("txtQuant", 20) %>
   3: <% End Using %>

 

Mais uma vez o helper HTML nos ajuda na criação da textbox, evitando que tenhamos que nos preocupar especificamente com o HTML.

Observe cuidadosamente as intercalações entre código ASP.NET e código HTML

48) Crie um botão Submit, no qual o usuário irá clicar para efetivar a compra.

   1: <% Using Html.Form(Of siteCesta.ProductsController)(New Action(Of siteCesta.ProductsController)(Function(x As siteCesta.ProductsController) 
                      x.Comprar(id, usuario))) %>
   2: <%= Html.TextBox("txtQuant", 20) %>
   3: <%= Html.SubmitButton("cmdComprar", "Comprar") %>
   4: <% End Using %>

 

Mais uma vez usando o Helper, sem novidades.

49) Nas propriedades do projeto, na aba "Web", em "Specific Page" indique "products/listar" para que ao rodar o projeto a ação de listar dos produtos seja imediatamente executada

50) Execute a aplicação para testa-la. Você poderá observar a lista de produtos. Indique uma quantidade e faça uma compra.

51) Usando o server explorer, abra a tabela e confira os produtos adquiridos.

52) Na pasta controllers crie uma nova controller class chamada CestaController

53) No CestaController crie o método listar com o seguinte código :

    Function Listar()
        Dim ta As New dsNorthTableAdapters.CestaTableAdapter
        Dim dados As New dsNorth
        ta.Fill(dados.Cesta, Me.ControllerContext.HttpContext.Request.AnonymousID)
        RenderView("Cesta", dados.Cesta)
    End Function

Muito semelhante a ação de listar de produtos, a diferença neste ponto é que a listagem da cesta precisa de um parâmetro, o ID do usuário. Obtemos este parâmetro acessando o contexto HTTP da execução deste controller.

54) Na pasta views, crie uma nova pasta chamada Cesta

55) Na pasta cesta, insira uma nova view chamada cesta.aspx

56) Na pasta Content, crie um novo arquivo css cha mado cesta.css

57) Abra a view ListarProdutos.aspx

58) Arraste o arquivo Cesta.css da pasta Content para dentro da página ListarProdutos.aspx

Isso gera um vínculo da página com o arquivo CSS

58) Abra a janela Manage Styles (menu view)

59) Arraste todos os estilos de "Current Page" para o Cesta.css

Isso nos permitirá aplicar os mesmos estilos na view "Cesta"

60) Na view Cesta, crie uma tabela com 2 linhas e 4 colunas

61) Insira os seguintes títulos na 1a linha : Produto, Preço, Quantidade e Total

62) Pelo solution explorer, arraste o arquivo cesta.css para dentro da view cesta.aspx

63) Exiba a janela apply styles

64) Selecione e linha de título e aplique o estilo da linha de título

65) Na lista de objetos, selecione a tabela e clique no estilo "Tabela"

66) No code-behind, altere a herança para :

Public Partial Class Cesta
    Inherits System.Web.Mvc.ViewPage(Of dsNorth.CestaDataTable)
 
End Class

67) Reconfigure a query da cesta de compras (dentro do dataset dsNorth), criando um relacionamento com a tabela products e trazendo o nome do produto

68) Voltando para a view cesta.aspx, faça um for/each em torno da segunda linha da tabela, sendo a repetição para cada linha da dataTable cesta :

   1: <% For Each r As siteCesta.dsNorth.CestaRow In ViewData %>
   2: <tr>
   3: <td>
   4: <%= r.ProductName%></td>
   5: <td>
   6: <%= String.Format("{0:C}", r.Preco) %></td>
   7: <td>
   8: <%= r.Quant %></td>
   9: <td>
  10: <%= String.Format("{0:C}", r.Preco * r.Quant) %></td>
  11: </tr>
  12: <% Next %>

 

69) Preencha as células com os valores dos campos utilizando a variável r :

   1: <% For Each r As siteCesta.dsNorth.CestaRow In ViewData %>
   2: <tr>
   3: <td>
   4: <%= r.ProductName%></td>
   5: <td>
   6: <%= String.Format("{0:C}", r.Preco) %></td>
   7: <td>
   8: <%= r.Quant %></td>
   9: <td>
  10: <%= String.Format("{0:C}", r.Preco * r.Quant) %></td>
  11: </tr>
  12: <% Next %>

 

70) Voltando para a view listarprodutos.aspx, logo acima da tabela insira o seguinte código (através do source) :

   1: <%= Html.ActionLink(Of siteCesta.CestaController)(New Action(Of siteCesta.CestaController)(Function(x As siteCesta.CestaController) 
                            x.Listar), "Ver Cesta de Compras") %>

 

Mais uma vez estamos usando o helper, desta vez com o objetivo de construirmos um simples link para a página cesta de compras.

Por que o ActionLink genérico ? Para que ele esteja pronto para receber um action genérico..

Por que um Action genérico ? Para que a variável x seja tipada

Por que a variável x tipada ? Para que possamos fazer uma chamada ao método

Por que não usar simplesmente neste formato :

   1: <%= Html.ActionLink("Ver cesta de compras", "listar", "Cesta") %>

 

Porque neste formato se mudarmos o controller ou o nome da ação do controller isso não será identificado pelo compilador. No modo tipado o compilador identifica as mudanças e auxilia na manutenção

Uma observação importante : a ação listar da cesta de compras tem que ser transformada em function para que a instrução tipada seja válida

71) Execute para testar. Faça compras e visualize a cesta de compras

72) No dsNorth, tableAdapter de cesta, crie uma nova query com o nome de AtualizarQuantidade e a seguinte instrução SQL :

   1: UPDATE Cesta
   2: SET Quant = @Quant
   3: WHERE (ProductId = @ProductId) AND (UserId = @UserId)

 

73) No CestaController crie o método AtualizarQuantidade com o seguinte código :

    Function AlterarQuantidade(ByVal idusuario As String, ByVal idproduto As String)
        Dim ta As New dsNorthTableAdapters.CestaTableAdapter
        ta.AtualizarQuantidade(ReadFromRequest("txtquant"), idproduto, idusuario)
        RedirectToAction("Listar")
    End Function

Sem novidades em comparação com os exemplos anteriores, recebemos os parâmetros e executamos a atualização da quantidade

74) Na view Cesta.aspx, na coluna quantidade, crie um formulário preparado para disparar o método AlterarQuantidade :

   1: <td>
   2: <% Using Html.Form(Of siteCesta.CestaController)(New Action(Of siteCesta.CestaController)(Function(x As siteCesta.CestaController) 
                                   x.AlterarQuantidade(r.UserId, r.ProductId)))%>
   3: <%= r.Quant %>
   4: <% End Using %>
   5: </td>

 

75) Crie uma textbox para conter a quantidade :

   1: <td>
   2: <%  Using Html.Form(Of siteCesta.CestaController)(New Action(Of siteCesta.CestaController)(Function(x As siteCesta.CestaController) 
                     x.AlterarQuantidade(r.UserId, r.ProductId)))%>
   3:     <%= Html.TextBox("txtquant", r.Quant, 10, 5) %>
   4: <% End Using %>
   5: </td>

 

76) Crie um botão para que seja efetivada a alteração da quantidade

   1: <td>
   2: <%  Using Html.Form(Of siteCesta.CestaController)(New Action(Of siteCesta.CestaController)(Function(x As siteCesta.CestaController) 
                          x.AlterarQuantidade(r.UserId, r.ProductId)))%>
   3:     <%= Html.TextBox("txtquant", r.Quant, 10, 5) %>
   4:     <%= Html.SubmitButton("cmdAlterar", "Alterar Quantidade") %>
   5: <% End Using %>
   6: </td>

 

77) Teste o site e experimente alterar a quantidade de produtos na cesta de compras

78) Insira a imagem deletar.gif (nos downloads deste artigo) na pasta content

79) No dsNorth, tableAdapter de cesta, crie um método deletarItem com o seguinte SQL :

    Function Remover(ByVal idUsuario As String, ByVal idProduto As String)
        Dim ta As New dsNorthTableAdapters.CestaTableAdapter
        ta.DeletarItem(idUsuario, idProduto)
        RedirectToAction("Listar")
    End Function

80) Na view Cesta.aspx, na 2a linha, adicione uma coluna no inicio da linha com um formulário disparando a ação de remover :

   1: <td><% Using Html.Form(Of siteCesta.CestaController)(New Action(Of siteCesta.CestaController)(Function(x As siteCesta.CestaController) 
                   x.Remover(r.UserId, r.ProductId)))%>
   2:  
   3: <% End Using %>
   4: </td>

 

81) Crie um botão ImageSubmit para atuar como botão deletar da cesta :

   1: <td><% Using Html.Form(Of siteCesta.CestaController)(New Action(Of siteCesta.CestaController)(Function(x As siteCesta.CestaController) 
                      x.Remover(r.UserId, r.ProductId)))%>
   2:    <%= Html.SubmitImage("imgDeletar", "/Content/deletar.gif") %>
   3: <% End Using %>
   4: </td>

 

82) Na 1a linha da tabela, insira uma coluna adicional no inicio da linha, para igualar o número de colunas

83) Teste a deleção de um produto da cesta de compras


Com este projeto demonstramos o passo a passo de construção de uma cesta de compras utilizando o padrão ASP.NET MVC. Não entramos em detalhes, porém, sobre os beneficios ou maleficios das características deste projeto. Analisaremos este projeto em mais detalhes no artigo Analisando um projeto ASP.NET MVC

É claro que todo esse assunto poderá gerar longos debates, todos são muito bem vindos no grupo devASPNet para debater este tema, basta enviarem um e-mail para devaspnet-subscribe@yahoogrupos.com.br





Envie seus comentįrios sobre este artigo

Nome :

E-mail :

Comentários :


Avise-me quando houverem novos comentįrios nesta pįgina

Veja abaixo os comentários já enviados :

Nome : ALexander E-Mail : alexandermarcilio@yahoo.com.br
A aplicação foi feita usando como linguagem de programação visual basic ! correto? para se fazer a mesma aplicação usando cmo liguagem de programação C# muda muito? poderia disponibilizar codigo em C#?
Nome : E-Mail :
Nome : E-Mail :
Nome : Socador E-Mail : socador@gmail.com
Tu é muito fraco usando dataset que isso que vergonha. Isto é pré-histórico.
Nome : Dennes E-Mail : dennes@bufaloinfo.com.br
Prezado,

Primeiramente, você está lendo um artigo escrito no mês 6 de 2008.

Em segundo lugar, deveria saber que as modernas opções de acesso a dados nunca atendem 100% dos casos como os datasets.


Dennes

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Conheça mais sobre o nosso site :

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::



Quer saber mais?
Faça um curso na Búfalo Informática, Treinamento e Consultoria e
Prepare-se para o Mercado!
Veja o que a Búfalo tem para você.

ļæ½ BĆŗfalo InformĆ”tica, Treinamento e Consultoria - Rua Ɓlvaro Alvim, 37 Sala 920 - CinelĆ¢ndia - Rio de Janeiro / RJ
Tel.: (21)2262-1368 (21) 9240-5134 (21) 9240-7281 e-Mail:
contato@bufaloinfo.com.br