dotnet42-final.pdf

68
Edição 42 - .NET Magazine 1 TIPO DO ARTIGO

Upload: robson-rodrigues-freitas

Post on 16-Jan-2016

56 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: dotNET42-Final.pdf

Edição 42 - .NET Magazine 1

Tipo do arTigo

Page 2: dotNET42-Final.pdf

Edição 42 - .NET Magazine 3

Page 3: dotNET42-Final.pdf

Edição 42 - .NET Magazine 3

A revista .net Magazine é parte integrante da assinatura .NET PLUS. Para mais informações sobre o pacote .NET PLUS, acesse: http://www.devmedia.com.br/dotnet

Ano 4 - 42ª Edição 2007 - ISSN 1980-3931 - Impresso no Brasil

Atendimento ao Leitor

A DevMedia conta com um departamento

exclusivo para o atendimento ao leitor. Se você

tiver algum problema no recebimento do seu

exemplar ou precisar de algum esclarecimento

sobre assinaturas, exemplares anteriores,

endereço de bancas de jornal, entre outros,

entre em contato com:

Carmelita Mullin – Atendimento ao Leitorwww.devmedia.com.br/central/default.asp(21) 2220-5375

Kaline DolabellaGerente de Marketing e [email protected]

(21) 2220-5375

Publicidade

Para informações sobre veiculação de

anúncio na revista ou no site entre em

contato com:

Kaline [email protected]

Para fechar parcerias ou ações específicas

de marketing com a DevMedia, entre em

contato com:

Jeff [email protected]

Corpo Editorial

É muito importante para a equipe saber o

que você está achando da revista: que tipo

de artigo você gostaria de ler, que artigo você

mais gostou e qual artigo você menos gostou.

Fique a vontade para entrar em contato com

os editores e dar a sua sugestão!

Se você estiver interessado em publicar um

artigo na revista ou no site .NET Magazine,

entre em contato com os editores, informando o título e mini-resumo do tema que você gostaria de publicar:

Guinther Pauli - Editor da Revista

[email protected]

Luciano Pimenta - Editor do Site

[email protected]

Fale com o Editor!

Apoio

Diretor Editorial e AdministrativoGladstone Matos

[email protected]

Direção de ArteVinicius O. Andrade

[email protected]

CapaAntonio Xavier

[email protected]

RevisãoRafael de Castro

[email protected]

Na Webwww.devmedia.com.br/.NET

Articulistas desta ediçãoRodrigo Sendin, Guilherme A Vieira, Ciniro Nametala, Nilton Pinheiro,

Luiz Gonzaga Filho, Eduardo Carvalho, José Antonio Thomaz

Editor GeralGuinther Pauli

[email protected]

Editor TécnicoLuciano Pimenta

[email protected]

DistribuiçãoFernando Chinaglia Dist. S/A

Rua Teodoro da Silva, 907

Grajaú - RJ - 206563-900

Na DevMedia, o leitor de banca também ganha!

Na compra dessa edição, ganhe essas 10 aulas do curso de C#:

http://www.devmedia.com.br/articles/listcomp.asp?keyword=net42videos&codigobanca=sylar

Page 4: dotNET42-Final.pdf

4 .NET Magazine

EDITORIALO AJAX representa a segunda geração dos aplicativos para Web, focados na colaboração entre pessoas, um dos pilares da Web 2.0. Não falamos apenas de uma evolução na plataforma Web, mas de uma mudança profunda em como os aplicativos são escritos. Tecnicamente falando, o AJAX permite a comunicação assíncrona de páginas com o servidor Web, permitindo ainda a atualização parcial de pequenas porções da tela, ao invés do refresh total. Aliado a uma série de novos recursos baseados em AJAX (como por exemplo o AJAX Control Tool Kit para ASP.NET), suas aplicações vão ser semelhantes a aplicações Desktop e agora sim, cada vez mais veremos sistemas sendo escritos para Web e não mais para Desktop. A partir desta edição, entre nesse novo mundo e faça seu conceito de desenvolvimento também mudar de versão, porque o AJAX não só veio para ficar, mas para revolucionar, como vai comprovar o Rogério em sua série de artigos.Outra tecnologia que veio para revolucionar, presente no .NET 3.0, é o que chamamos de LINQ (Language Integrated Query). Trata-se de uma linguagem, que você pode usar no C# 3.0 (ou VB.NET) e permite de uma única forma consultar dados vindos de diferentes tipos de fontes: banco de dados, XML e até mesmo objetos! Exato, você pode tratar suas coleções como tabelas e usar o LINQ (que age como uma espécie de SQL) para obter dados, fazendo selects com from, where, join e ainda mais. Conheça esse projeto no artigo do Diego e construa suas primeiras aplicações com essa revolucionária linguagem, criada por Anders Hejlsberg (o mesmo personagem que criou o Turbo Pascal, Delphi e C#).Falando em melhorias, o ASP.NET contém uma variedade muito grande de componentes. Mas algumas vezes sentimos falta de um controle personalizado, que realize uma tarefa específica não suprida pelo framework. O Sendin mostra em seu artigo alguns excelentes componentes para incrementar suas páginas ASP.NET: FreeTextBox, ASPNetVideo e um super grid da DevExpress.Ainda sobre Web, vamos falar em integração. É muito fácil usar SOAP para trocar dados em XML ou usar serviços de sistemas rodando em diferentes plataformas. Mas e quando o XML e SOAP ficam de fora, como você faria para obter informações e trocar dados com um sistema baseado somente em páginas? No artigo que preparei para esta edição, mostro uma interessante técnica para permitir a obtenção de dados a partir de páginas Web, fazendo requisições HTTP programaticamente.Ainda nesta edição, o Thiago mostra como aumentar a produtividade da equipe de desenvolvimento criando templates de projeto e StarterKits. Com esses recursos, é possível definir um projeto (ou mesmo solução) que funciona como modelo para todas as aplicações da empresa, de forma que quando um desenvolvedor inicie um novo projeto, ele não comece do “zero”, mas do código e design já implementados no template.Falando em facilidades do Visual Studio, que tal fazer um check-up no seu código-fonte para ver como ele anda? Você usa corretamente os padrões definidos pela Microsoft para o estilo de código? O Code Analysis do Visual Studio permite fazer uma auditoria completa no seu código-fonte, observando não só o item que comentei anteriormente, mas fazendo uma verificação nas mais diversas áreas. Para finalizar a edição, Luciano Pimenta mostra super dicas para turbinar o seu GridView. Para finalizar, confira um artigo sobre Microsoft Solutions Framework, por Fábio Câmara.

Boa leitura e muito sucesso com o ASP.NET AJAX!

Guinther Pauli

[email protected] GeralMicrosoft Certified: MCP, MCAD, MCSD.NETBorland Certified: Delphi 6, 7, 2005, 2006, Web, Kylix

ÍNDICE

10 - Mini-curso de AJAX – Parte 1Rogério Moraes de Carvalho

22 - LINQ - A revolução do .NET 3.0Diego Dias

28 - Componentes de terceiros para ASP.NET Rodrigo Sendin

36 - Preenchendo formulários Web programaticamenteGuinther Pauli

42 - Criando Templates e StarterKit de projetosThiago Miranda

50 - Utilizando o Code Analysis do Visual StudioPenihel Roosewelt

60 - Dicas de GridViewLuciano Pimenta

56 - Microsoft Solutions FrameworkFábio Camara

Page 5: dotNET42-Final.pdf

Crie um site de Notícias – Partes I a VIIIFabio Galante apresenta mais um excelente mini curso onde mostra como criar um site de notícias em ASP.NET.

Utilizando AJAX no ASP.NET – Parte I a IXEuclides Chuma apresenta vários controles AJAX para utilização em aplicação ASP.NET.

Criando Master/Detail com dataGridViewVeja nessa vídeo aula de Luciano Pimenta, como criar um relacionamento master/detail no dataGridView.

AJAX – PopupsVeja nessa vídeo aula de Guinther Pauli, como exibir popups em aplicação ASP.NET com AJAX.

Não perca o mini curso de C#Pedro Bajotto Filho continua com a série de aulas sobre a linguagem C#.

Caro Leitor,

Temos uma novidade: Agora, o assinante da revista .net Magazine possui uma assinatura de conteúdo .net PLUS.

O pacote .net PLUS inclui:

1) Recebimento da revista .net Magazine;

2) Acesso, durante 1 ano, ao portal .net PLUS, contendo artigos, mini-cursos e vídeo aulas;

O portal .net PLUS recebe um conteúdo novo todo dia e hoje conta com: I) mais de 300 vídeo-aulas; II) 6 cursos online gratuitos; III) artigos exclusivos (que não foram publicados na revista)!;

Acesse o portal .net PLUS e receba muito mais conteúdo sobre tecnologias Microsoft!

Basta utilizar o seu login e senha pessoais. Confira a seguir as últimas novidades .net PLUS!

Boa leitura e sucesso!

Equipe DevMediaNa DevMedia, o leitor de banca também ganha!

Na compra dessa edição, ganhe essas 10 aulas do curso de C#:

• Introdução a linguagem C#;

• Funções básicas da linguagem;

• Rotinas de condição (if );

• Trabalhar com rotinas Switch;

• Tratamento de exceções (Exception);

• Uso de arrays e ArrayList;

• Uso de Listas (List<>);

• Cast e Boxing;

• Criação de classes;

• Conceitos básicos de Orientação a Objetos. Acesse agora mesmo o link:http://www.devmedia.com.br/articles/listcomp.asp?keyword=net42videos&codigobanca=sylar

Últimas Vídeo-Aulas (Somente para assinantes)

Edição 42 - .NET Magazine 5

o portal .net pLus conta com 6 cursos online, confira:

• Crie uma loja virtual completa com ASP.NET [Autor: Fábio Galante]

• Tudo sobre a linguagem C# (em andamento) [Autor: Pedro Filho]

• Aprenda a criar um Blog com ASP.NET [Autor: Fábio Galante]

• Criando uma aplicação client/server [Autor: Luciano Pimenta]

• Criando uma aplicação Web completa [Autor: Luciano Pimenta]

• Construindo relatórios com Crystal Reports [Autor: Luciano Pimenta]

Cursos Online

4 .NET Magazine

Novidades do portal .net PLUSwww.devmedia.com.br/dotnet

+330 vídeo aulas!6 cursos online

Page 6: dotNET42-Final.pdf

6 .NET Magazine - .NET Brasil

Visual Studio Orcas

Rodrigo Sendin([email protected])

é tecnólogo formado pela FATEC de Americana, mas é Piracicabano e torcedor do XV de Pira-cicaba! Recomenda que você visite Piracicaba e não deixe de conhecer a Rua do Porto, onde pode desfrutar do maravilhoso filhote (peixe) assado no Tambor.

.NET Brasil

No último mês de maio foi lan-çada a primeira versão Beta do Orcas. Para quem ainda não

sabe, Orcas é o codinome da nova versão do Visual Studio, que está em desenvol-vimento. Caso tenha interesse em testar essa versão Beta, dê uma olhada no se-guinte link: msdn2.microsoft.com/en-us/vstudio/aa700831.aspx.

Você encontrará os downloads neces-sários para instalação ou o download de uma máquina virtual com ele instalado. Independente da sua escolha, sugiro utilizar o Orcas em uma máquina virtual. Lembre-se que essa é a versão Beta 1!

Resumidamente as novidades que o Orcas trará são as seguintes:

Windows Vista A nova versão do Visual Studio deverá

estar totalmente integrada à nova pla-taforma de desenvolvimento, que hoje conhecemos como .NET Framework 3.0. Principalmente as features que atendem às necessidades de desenvolvimento para o Windows Vista. Ou seja, o WPF (Windows Presentation Foundation) estará totalmente incorporado ao Orcas, onde também teremos uma nova versão do .NET Framework, a 3.5.

VSTO e Office 2007O VSTO (Visual Studio Tools for Office)

será totalmente integrado ao Orcas Profes-sional Edition. Além disso, o mote princi-pal nesse quesito será o desenvolvimento para o Office 2007 e SharePoint 2007.

Uma novidade bem interessante para quem trabalha com o VSTO, será o novo

recurso de distribuição de aplicações Office, que promete ser compatível com o conceito Click Once.

LINQ Essa talvez seja a novidade mais signifi-

cativa que virá. Para quem não conhece, o LINQ (Language Integrated Query) é um projeto da Microsoft que estende as lin-guagens C# e VB.NET, para simplificar o modo como escrevemos queries de acesso a dados (banco de dados ou XML).

Liderado por Anders Hejlsberg (criador do Turbo Pascal, Delphi e C#), o LINQ é um projeto que deve revolucionar o modo como escrevemos queries em nosso código. É óbvio que há muito mais sobre o projeto LINQ, portanto sugiro que você dê uma boa olhada no site oficial: msdn2.microsoft.com/en-us/netframework/aa904594.aspx.

Novidades para WebApesar de não ser novidade há um bom

tempo, o ASP.NET AJAX deverá estar incorporado ao Orcas, e não será mais um pacote a parte. Além disso, deveremos ter novidades como: Novas features XHTML e CSS para o design surface dos WebForms, JScript IntelliSense para o ASP.NET AJAX e Multi-Targeting para .NET Framework 2.0, 3.0 e 3.5.

Melhorias no Gerenciamento do Ciclo de Vida da Aplicação (ALM)

Basicamente teremos melhorias nos recursos do Visual Studio Team System, como: Integração do banco no ciclo de vida do software, melhorias nas capaci-

dades do Unit Testing do Visual Studio e diversas melhorias de performance.

Segundo a Microsoft, as novidades do Orcas estão concentradas para atender as necessidades dos desenvolvedores em três grandes pilares: Produtividade, Gerenciamento do Ciclo de Vida da Aplicação e Integração das Novas Tec-nologias.

De forma prática, esse último “pilar” é o mais significativo, haja vista a quanti-dade de tecnologias de desenvolvimento que surgiram no último ano (AJAX, WPF, WF, WCF etc.), e que finalmente precisam estar integradas em único “pacote”.

Se você quiser saber mais detalhes sobre essas e outras novidades do Or-cas, dê uma olhada no White Paper: www.microsoft.com/downloads/details.aspx?familyid=17319EB4-299C-43B8-A360-A1C2BD6A421B&displaylang=en . Nele você vai encontrar um apêndice com uma lista enorme de funcionalidades que deverão estar incorporadas ao Orcas.

Mas é claro que estamos falando de uma versão Beta, e muita coisa ainda pode mudar.

Page 7: dotNET42-Final.pdf

6 .NET Magazine - .NET Brasil

Page 8: dotNET42-Final.pdf

8 .NET Magazine - Encarando o Desenvolvedor

Eu vejo a Luz

Mauro Sant’Anna ([email protected])é um crente de primeira hora na tecnologia SmartClient, mas que foi repetidamente traído por ela.

““o Silverlight teve uma divulgação excelente, dentro e fora da Microsoft.

Encarando o Desenvolvedor

Em 2001 durante sua palestra de abertura no PDC, o principal evento para desenvolvedores da

Microsoft, Bill Gates citou a reunificação das interfaces com usuário como uma das principais razões por trás do desen-volvimento da plataforma .NET, depois da cisão causada pelo aparecimento da Web.

Efetivamente, a Web oferece enormes vantagens de alcance, distribuição e atu-alização, mas à custa de uma experiência com o usuário pobre. Já os aplicativos grá-ficos tinham boa interface com usuário, mas traziam problemas de distribuição e atualização. A idéia de unir as vantagens das duas plataformas na tecnologia então batizada de Smart Client sempre me pare-ceu uma ótima idéia.

Não só eu, mas também o Gartner Group ficou entusiasmado com a no-vidade e previu que em 2006 a maioria dos novos aplicativos na plataforma Microsoft seria Smart Client e não Web. Lógico que o apoio do Bill Gates tornaria a tecnologia imbatível!

No início, por volta de 2002, Smart Client significava colocar em páginas Web con-troles .NET e tags “href” referenciando executáveis. Essa tecnologia evoluiu para o Click Once no .NET 2.0 em 2005. Infeliz-mente nenhuma das duas teve grande re-percussão. Elas sofreram dois problemas, um técnico e outro de marketing.

Tecnicamente, o modelo de segurança chamado “CAS” (Code Access Security) é difícil de entender e implantar. Do ponto de vista de divulgação, ninguém de fora do grupo que cuidava da própria tecnologia jamais deu a menor bola para o Smart Client. Por exemplo, a Microsoft jamais criou um aplicativo de uso amplo para funcionar como demonstração da nova tecnologia.

Eu mesmo sugeri para várias pessoas da Microsoft idéias de aplicativos que mostrassem as vantagens do Smart Client, como por exemplo, um cliente alternativo para o Hotmail ou então uma melhor interface de busca no site MSDN.

Onde estava Bill Gates para fazer essas coisas acontecerem? Será que ele não se importava mais? Teríamos que nos con-tentar com o Flash da Adobe ou com o “Java Script” turbinado / AJAX?

Em 2005, Bill Gates anunciou sua apo-sentadoria e em 2006 nomeou Ray Ozzie como seu sucessor. Ozzie seria a pessoa responsável pela “visão tecnológica” em uma empresa cada vez mais dominada por executivos de vendas extremamente preocupados com os números de curto prazo.

Eu já estava convencido que teria que me conformar com uma mistura de AJAX

e Flash quando Ray Ozzie anunciou, com bandas e fanfarras no evento “MIX”, o SilverLight 1.1, uma nova implementa-ção da tecnologia Smart Client sem seus tradicionais problemas.

Em termos de marketing, o Silverlight teve uma divulgação excelente, incluindo um bom tempo nas principais home pa-ges dos sites Microsoft. Em todo mundo, Silverlight é considerado algo “quente”.

Do ponto de vista técnico ele também não decepciona. O beta que está no ar desde fevereiro e corresponde ao Silver-light 1.0 permite a criação de interfaces com usuário mais bonitas através do uso

do WPF (Windows Presentation Foundation) misturado com Java Script.

Mas é o alfa da versão 1.1, colocado no ar depois do MIX, que traz a grande novidade: uma versão “light”do .NET Framework. Essa versão é pequena, estará disponível para plataformas não-Microsoft como MacOS e traz um modelo de segurança bastante simplificado.

Ou seja: o SilverLight 1.1 promete entre-gar as promessas do Smart Client, unindo a distribuição e alcance da Web com uma interface com usuário bem mais rica e semelhante aos aplicativos “GUI”.

É claro que “o diabo está nos detalhes”. Embora seja uma versão simplificada, o Silverlight deve ser capaz de atender a maioria das necessidades de negócio de seus usuários. A versão atual tem limita-ções, por exemplo, falta um mecanismo declarativo de “controles vinculados”, o que facilita bastante o desenvolvimento de aplicativos de negócios que lidam com bancos de dados.

Mas ainda é cedo para emitir um pare-cer completo. Tecnicamente não acredito ser difícil para a Microsoft produzir um produto ao mesmo tempo simples e pode-roso em um curto espaço de tempo.

O mais importante é que com o apoio do Ray Ozzie, o novo “homem de visão” da Microsoft, o Silverlight deve ter um futuro brilhante à sua frente.

Curso em destaque

Crie uma loja virtual completa Confira neste curso Online como construir uma loja virtual completa no Visual studio 2005. Aprenda como criar obanco de dados, carrinho de compras, profile, página de erros e muito mais .

Outros cursos disponíveis: www.devmedia.com.br/curso

Curso de C#

* Curso em andamento

Construindo relatórios

com Crystal Reports e

Visual Studio 2005

Criando uma aplicação

Web Completa

Criando uma aplicação client/server

no Visual Studio 2005

Aprenda a criar um

blog com ASP.NET

Assine a .net Magazine e comece já seu treinamento!www.devmedia.com.br/assine

Confira o plano de aula completo:www.devmedia.com.br/lojavirtual

Mais Informações: www.devmedia.com.br/central - Tel.: 2220-5375 / 2220-5435

A revista .net Magazine oferece para seus assinantes uma série de Cursos Online de alto padrão de qualidade . Conheça abaixo os cursos já disponíveis.

Mais conteúdo .NET por muito menos!

Assinatura

Page 9: dotNET42-Final.pdf

Cursos Online

Curso em destaque

Crie uma loja virtual completa Confira neste curso Online como construir uma loja virtual completa no Visual studio 2005. Aprenda como criar obanco de dados, carrinho de compras, profile, página de erros e muito mais .

Outros cursos disponíveis: www.devmedia.com.br/curso

Curso de C#

* Curso em andamento

Construindo relatórios

com Crystal Reports e

Visual Studio 2005

Criando uma aplicação

Web Completa

Criando uma aplicação client/server

no Visual Studio 2005

Aprenda a criar um

blog com ASP.NET

Assine a .net Magazine e comece já seu treinamento!www.devmedia.com.br/assine

Confira o plano de aula completo:www.devmedia.com.br/lojavirtual

Mais Informações: www.devmedia.com.br/central - Tel.: 2220-5375 / 2220-5435

A revista .net Magazine oferece para seus assinantes uma série de Cursos Online de alto padrão de qualidade . Conheça abaixo os cursos já disponíveis.

Mais conteúdo .NET por muito menos!

Assinatura

Page 10: dotNET42-Final.pdf

10 .NET Magazine - Mini-curso de AJAX – Parte 1 Edição 42 - .NET Magazine 11

Mini-curso de AJAX – Parte 1Conhecendo os bastidores

Rogério Moraes de Carvalho ([email protected])

é Consultor e Instrutor de Tecnologia da Infor-mação. Trabalha com consultorias e treinamen-tos nas plataformas .NET e Java.

Este é o primeiro de uma série de artigos sobre ASP.NET AJAX. O objetivo deste primeiro artigo é

apresentar os bastidores do AJAX, inde-pendente do framework ASP.NET AJAX da Microsoft.

A idéia é fornecer uma base consistente de como trabalhar com várias das tecno-logias usadas no AJAX para desenvolver uma infra-estrutura que permita criar aplicações Web mais interativas.

Nota: Para um bom entendimento

deste artigo, é ideal que o leitor tenha

um nível de conhecimento de básico

a intermediário em HTML/XHTML, CSS,

XML, ASP.NET 2.0 e C# 2.0 (ou Visual Ba-

sic 2005) e um nível de intermediário a

avançado em JavaScript e DOM.

Os artigos posteriores estarão focados nas funcionalidades do framework gratuito ASP.NET AJAX, que foi dispo-nibilizado pela Microsoft como uma

extensão ao ASP.NET 2.0. Os leitores que entenderem os conceitos apresentados neste artigo, terão um domínio maior sobre o que acontece nos bastidores do framework ASP.NET AJAX, como em qualquer outro framework AJAX.

Esse conhecimento é muito importante para um maior domínio do assunto, prin-cipalmente para aqueles desenvolvedores Web que pretendem criar componentes não visuais do lado do cliente ou contro-les ASP.NET AJAX personalizados.

O que é AJAX?AJAX, acrônimo de Asynchronous Java

Script and XML, é uma técnica de desen-volvimento Web que permite a criação de aplicações mais interativas. Um dos principais objetivos é tornar as respostas das páginas Web mais rápidas pela troca de pequenas quantidades de informações com o servidor Web, nos bastidores.

Além disso, evita-se que a página Web inteira tenha que ser recarregada cada vez

Page 11: dotNET42-Final.pdf

10 .NET Magazine - Mini-curso de AJAX – Parte 1 Edição 42 - .NET Magazine 11

MiNi-curso – aJaX

que alguma nova informação precisa ser consultada no servidor. Em geral, isso sig-nifica que páginas Web com recursos AJAX permitem maior interatividade, velocidade de processamento e usabilidade.

Tecnologias usadas no AJAXAJAX utiliza uma combinação de várias

tecnologias padronizadas e não padro-nizadas de desenvolvimento para Web, conforme apresentado a seguir:•HTML (HyperText Markup Language)/

XHTML (Extensible HyperText Markup Language): linguagem para criação de documentos Web;•CSS (Cascade Style Sheets): mecanismo

para adicionar estilos aos documentos Web;•XML (Extensible Markup Language): for-

mato que permite a criação de documen-tos estruturados com dados hierárquicos, sendo muito usado para troca de dados na Web;•ECMAScript: padrão de linguagem de

script, cujas principais implementações são o JavaScript e o JScript;•XMLHttpRequest: objeto que define

uma API com funcionalidades para scripts do lado do cliente para comuni-cação entre um cliente e um servidor usando o protocolo HTTP;•DOM (Document Object Model) para

manipular a estrutura e o estilo de do-cumentos Web dinamicamente;•JSON (JavaScript Object Notation): for-

mato leve para intercâmbio de dados;•XSLT (Extensible Stylesheet Language for

Transformation): linguagem para transfor-mação de documentos XML;•dentre outras tecnologias possíveis de

serem utilizadas.Todas as tecnologias citadas anterior-

mente, com exceção de XSLT, serão descri-tas em maiores detalhes e utilizadas para construir um exemplo prático completo.

Será apresentado um breve histórico do AJAX, uma explicação do termo Web 2.0, que tem sido muito utilizado atualmente e uma descrição da aplicação Web de exemplo a ser desenvolvida.

Um breve histórico do AJAXAssim como DHTML (Dynamic Hyper-

Text Markup Language) e SPA (Single Page Application), o AJAX não é uma tecnolo-gia, mas sim um termo que representa

o uso de um grupo de tecnologias de desenvolvimento para Web.

Antes da introdução do termo AJAX, um grande número de páginas já utili-zava recursos do DHTML. O DHTML corresponde a um grupo de tecnologias usadas em conjunto para a criação de sites interativos e animados pela combinação de HTML, JavaScript, CSS e DOM.

Apesar de usar um subconjunto das tec-nologias utilizadas pelo AJAX, o DHTML afeta dinamicamente a aparência de uma página com conteúdo HTML depois que ela foi completamente carregada e está sendo visualizada. Porém, sempre que há a necessidade de comunicação com o servidor Web, a página deve ser recarre-gada como um todo.

Uma das principais tecnologias nos bas-tidores do AJAX é o objeto XMLHttpRe-quest, que torna possível a característica mais atraente do AJAX: a sua natureza as-síncrona. Esse objeto pode ser usado pelo JavaScript para transferir XML e outros dados textuais de um servidor Web para uma página Web, usando o protocolo HTTP por meio do estabelecimento de um canal de comunicação independente entre páginas Web do lado do cliente e do lado do servidor.

Apesar de, anteriormente, alguns de-senvolvedores terem utilizado frames ocultos ou elementos IFRAME para co-municar com o servidor nos bastidores de forma assíncrona, atualmente o XMLHt-tpRequest é mais amplamente utilizado por ser suportado pelos browsers mais modernos do mercado e por permitir um maior controle na comunicação entre o cliente e o servidor.

O termo AJAX foi introduzido recen-temente para designar um conjunto de tecnologias que permitem tornar a inte-ração de usuários com a interface de uma aplicação Web mais rica e produtiva.

Conforme foi citado anteriormente, o acrônimo AJAX significa Assyncronous JavaScript and XML. Ele foi introduzido por Jesse James Garrett, presidente e fundador da empresa Adaptive Path, no artigo “Ajax: A New Approach to Web Appli-cations”, que foi publicado há pouco mais de 2 anos, em 18 de fevereiro de 2005.

O artigo não apresentou nenhuma téc-nica revolucionária de desenvolvimento para Web, mas introduziu um novo

termo simples e representativo para um conjunto de tecnologias que já estavam sendo utilizadas.

Além disto, Garret explicou de forma clara e sucinta como essas tecnologias melhoravam a experiência dos usuários com aplicações Web, inclusive citando as seguintes aplicações pioneiras como exemplo: Google Suggest e Google Maps.

No final deste artigo são apresentados links para essas aplicações e para o texto que introduziu o termo AJAX.

Web 2.0O termo Web 2.0 não possui uma defini-

ção formal, mas é comumente usado para se referir a aplicações Web que encorajam interação social e contribuição coletiva para o bem comum. O termo também é usado para se referir a técnicas de pro-gramação Web que têm como principal objetivo fornecer uma interface rica e amigável. Atualmente, o conjunto dessas técnicas de programação Web tem sido comumente denominado AJAX.

Descrição da aplicação Web de demonstração

Durante a apresentação teórica do arti-go, uma aplicação Web de demonstração será desenvolvida para ilustrar várias das tecnologias usadas no AJAX. A interface será desenvolvida com XHTML 1.1 e uso de CSS 2 para sua formatação.

ASP.NET 2.0 e ADO.NET 2.0, com a lin-guagem C# 2.0 (uma versão com a lingua-gem Visual Basic 2005 estará disponível para download), e outros recursos do .NET Framework 2.0 serão usados para consultar o SQL Server 2005 e construir respostas dinâmicas para o cliente.

A comunicação entre o browser e o servidor Web será estabelecida com uso do objeto XMLHttpRequest, sendo que os dados serão transportados nos formatos: XML e JSON. O JavaScript 1.5 será usa-do do lado do cliente nos bastidores, de modo a funcionar nos principais browsers atuais, com a função de estabelecer a comunicação com o servidor Web e atu-alizar a interface com os dados recebidos como resposta. A tecnologia DOM será usada nos códigos JavaScript do lado do cliente.

Com o objetivo de tornar o artigo acessível a um maior número de de-

Page 12: dotNET42-Final.pdf

12 .NET Magazine - Mini-curso de AJAX – Parte 1 Edição 42 - .NET Magazine 13

senvolvedores da plataforma .NET, na elaboração do exemplo serão utilizados somente softwares e recursos disponíveis gratuitamente.

Porém, as versões comerciais também podem ser usadas. •Browsers: Internet Explorer 5.0 ou su-

perior, Firefox 1.0 ou superior, Opera 8.0 ou superior, Netscape 7.0 ou superior;•Servidor de banco de dados: SQL Server

2005 Express Edition SP2;•Banco de dados: AdventureWorks;•IDE para desenvolvimento: Visual Web

Developer 2005 Express Edition SP1.Os endereços para baixar os softwares

e o banco de dados estão colocados no final do artigo.

Criando o exemploNo Visual Web Developer 2005 Express

Edition SP1, crie um novo Web Site ASP.NET selecionado o menu (File>New Web Site). No quadro de diálogo New Web Site, em Template selecione ASP.NET Web Site, em Location selecione File System e uma localização para os arquivos do Web Site e em Language selecione Visual C#.

Apague o arquivo Default.aspx, jun-tamente com o arquivo Default.aspx.cs.

Por uma questão de espaço, o artigo apresenta todo o código do lado do servidor somente na linguagem C# 2.0. Porém, a versão em Visual Basic 2005 ficará disponível para download, sendo que o Web Site desenvolvido em C# 2.0 estará na pasta AdvWorksAjaxWebCS e o desenvolvido em Visual Basic 2005 na pasta AdvWorksAjaxWebVB.

Antes de continuarmos o exemplo, va-mos examinar mais alguns fundamentos importantes.

O que é o W3C?O World Wide Web Consortium (W3C),

que foi fundado em 1994, é um consórcio internacional em que membros de organi-zações, equipes com dedicação em tempo integral e o público trabalham juntos para desenvolver padrões para a Web.

Atualmente, o W3C é composto por, aproximadamente, 450 membros. O con-sórcio conta com membros de algumas das principais empresas e organizações de TI do mundo, incluindo as desen-volvedoras dos principais browsers do mercado, empresas de telecomunicações, universidades etc.

Segue uma breve relação com alguns

dos mais notórios membros: Adobe, AOL, Apple, Canon, Cisco, Fujitsu, Google, HP, IBM, Intel, Lexmark, Microsoft, Motorola, Mozilla, Nokia, Nortel, Oracle, RealNe-tworks, Samsung, Sun, Symbian, Toshiba, VeriSign, Xerox e Yahoo, dentre outros.

HTML 4.01 e XHTML 1.0/1.1A especificação HTML (HyperText Ma-

rkup Language) 4.01, recomendada pelo W3C assim como a maioria das demais vistas neste artigo, define a linguagem de marcação de hipertexto para publicação na rede de alcance mundial, a World Wide Web (WWW).

A especificação XHTML (Extensible HyperText Markup Language) 1.0 - Second Edition, corresponde a uma reformulação do HTML 4 como XML 1.0.

A especificação XHTML 1.1 corres-ponde a uma reformulação do XHTML 1.0 para dividir o XHTML em módulos. Atualmente, o W3C está trabalhando nas especificações XHTML 1.1 (Second Edition) e XHTML 2.0.

A interface da aplicação de demonstra-ção será feita com XHTML 1.1. O layout da página será definido com recursos de CSS para posicionamento e formatação dos elementos, ao invés de utilizar tabe-las HTML para esse fim. Essa técnica é denominada Tableless Layout.

Adicione uma página HTML ao Web Site nomeando-a “Pedidos.htm”. A Listagem 1 apresenta o código XHTML 1.1 da pá-gina Pedidos.htm.

A Figura 1 mostra o documento Pedidos.htm visualizado no browser Opera 9.10 sem a aplicação de CSS.

Figura 1. Documento XHTML sem CSS apresentado no browser Opera 9.10

Listagem 1. Código XHTML 1.1 da página Pedidos.htm

<?xml version=”1.0” encoding=”ISO-8859-1”?><!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.1//EN”“http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd”><html xmlns=”http://www.w3.org/1999/xhtml” xml:lang=”pt-BR” ><head> <title>Adventure Works - Pedidos por empregado</title></head><body> <div class=”quadroPrincipal”> <div class=”tituloPrincipal”> Adventure Works - Pedidos por empregado </div> <div class=”conteudoPrincipal”> <div class=”quadro”> <div class=”titulo”>Filtragem dos pedidos</div> <div class=”conteudo”> <div style=”margin-bottom:10px;”> Selecione o empregado responsável pelos pedidos:<br /> <select id=”selectEmpregados” class=”larguraTotal”></select> </div> <div> Selecione o mês e ano dos pedidos: <span id=”spanEmpregadoPedidos” class=”info”></span><br /> <select id=”selectMesesAnosPedidos” class=”larguraTotal”></select> </div> </div> </div> <div class=”quadro”> <div class=”titulo”> Pedidos do mês <span id=”spanMesAnoPedidos” class=”info”></span> </div> <div class=”conteudo” id=”divMesAnoPedidos”> </div> </div> </div> </div> <div id=”divMensagem”> </div></body></html>

Page 13: dotNET42-Final.pdf

12 .NET Magazine - Mini-curso de AJAX – Parte 1 Edição 42 - .NET Magazine 13

MiNi-curso – aJaX

Listagem 2. Código CSS 2 do arquivo Estilos.css

body, select { background-color: White; font-family: Verdana, Arial, Helvetica, Sans-Serif; font-size: 9pt;}

select { border: solid 1px #00460A;}

div#divMensagem { position: absolute; visibility: hidden; top: 100px; left: 50%; width: 500px; margin-left: -260px; z-index: 1; font-size: 11pt; text-align: center; padding: 20px 10px 20px 10px; border: solid 1px #8A6F28; background-color: #F9D52C; color: #8A6F28;}

span.info { font-style: italic;}

div.quadroPrincipal { border: solid 2px #00460A; background-color: #77B75D; padding: 1px; width: 560px; margin: auto;}

div.tituloPrincipal { background-color: #00460A; color: White; font-size: 16pt; font-weight: bold; text-align: center; padding: 3px;}

div.quadro { border: solid 1px #00460A; background-color: #D4E5CB; margin: 5px;}

div.titulo { background-color: #00460A; color: White; font-size: 12pt; padding: 3px;}

div.conteudo { padding: 10px;}

.larguraTotal { width: 100%;}

table.dados { border: solid 1px #00460A; border-collapse: collapse; width: 100%;}

table.dados tr th, table.dados tr td { border: solid 1px #00460A; padding: 3px;}

table.dados tr th { background-color: #228A11; color: White;}

table.dados tr.alt td { background-color: #B7D5AB;}

Figura 2. Documento XHTML formatado com CSS apresentado no Firefox 2.0

CSS 2A especificação CSS (Cascade Style Sheet)

2 é uma linguagem de folha de estilo que permite anexar estilos a documentos estruturados, como HTML e XML. CSS 2 simplifica a autoria e a manutenção de Web Sites pela separação dos estilos de apresentação do conteúdo dos docu-mentos.

Atualmente, o W3C está trabalhando nas especificações CSS 2.1 e CSS 3. A interface da aplicação Web de demons-tração, elaborada com XHTML 1.1, será formatada com CSS 2 utilizando a técnica Tableless Layout, descrita anteriormente.

Adicione uma folha de estilo CSS ao Web Site nomeando-a “Estilos.css” (item Style-Sheet). A Listagem 2 apresenta o código CSS 2 do arquivo Estilos.css. O arquivo CSS contém estilos para formatação de elementos presentes na página XHTML Pedidos.htm e de outros que serão gerados dinamicamente, como tabelas de dados.

A Listagem 3 apresenta a sintaxe do ele-mento <link> que deve ser acrescentado ao cabeçalho da página Pedidos.htm para vinculá-la aos estilos definidos na folha de estilo CSS 2 do arquivo Estilos.css.

A Figura 2 mostra o documento XHTML 1.1 Pedidos.htm visualizado no Firefox 2.0 com a aplicação da folha de estilo CSS 2 Estilos.css.

Comparando as Figuras 1 e 2, pode-se notar o poder dos estilos CSS para forma-tar páginas Web.

XML 1.0A especificação XML (Extensible Markup

Language) 1.0 corresponde a um subcon-junto da SGML (Standard Generalized Markup Language) usado para descrever uma classe de objetos de dados chamados documentos XML e descrever parcial-mente o comportamento de programas de computador que os processa.

A especificação XML 1.0 (Fourth Edi-tion) substitui a especificação XML 1.0, descrita anteriormente. A especificação XML 1.1 (Second Edition) corresponde a uma atualização da especificação XML 1.0 para não depender de versões es-pecíficas do Unicode, além de adicionar verificações de normalização e seguir regras Unicode de finalização de linha mais rigidamente.

A relação de empregados responsáveis por pedidos da empresa Adventure Works será montada a partir de uma consulta no banco de dados AdventureWorks num servidor SQL Server 2005. Sendo que o resultado da consulta será construído em formato XML 1.0 com os seguintes dados: código, primeiro nome, sobrenome do meio, sobrenome final e quantidade de pe-didos atendidos por todos os empregados ativos que atenderam a pelo menos um pedido de cliente até a sua conclusão.

Adicione um arquivo de configuração Web.config ao Web Site e configure a string de conexão com o banco de dados, como apresentado na Listagem 4.

Page 14: dotNET42-Final.pdf

14 .NET Magazine - Mini-curso de AJAX – Parte 1 Edição 42 - .NET Magazine 15

Listagem 3. <Link> para vincular Pedidos.htm a Estilos.css

...<head> <title>Adventure Works - Pedidos por empregado</title> <link href=”Estilos.css” rel=”stylesheet” type=”text/css” /></head>...

Listagem 4. Arquivo de configuração Web.config

<?xml version=”1.0”?><configuration> <connectionStrings> <add name=”cnAdventureWorks” connectionString=”Data Source=localhost\SQLExpress; Initial Catalog=AdventureWorks; Integrated Security=True” providerName=”System.Data.SqlClient”/> </connectionStrings></configuration>

Listagem 5. Arquivo code-behind Empregados.aspx.cs

...using System.Data.SqlClient;using System.Text;using System.Xml;public partial class Empregados : System.Web.UI.Page{ protected void Page_Load(object sender, EventArgs e) { Response.ContentType = “text/xml”; XmlWriter xwEmpregadosPedidos = null; SqlConnection cnAdventureWorks = null; SqlDataReader drEmpregadosPedidos = null; try { xwEmpregadosPedidos = new XmlTextWriter(Response.OutputStream, Encoding.GetEncoding(“ISO-8859-1”)); cnAdventureWorks = new SqlConnection(); cnAdventureWorks.ConnectionString = ConfigurationManager. ConnectionStrings[ “cnAdventureWorks”].ConnectionString; SqlCommand cmEmpregadosPedidos = new SqlCommand(); cmEmpregadosPedidos.Connection = cnAdventureWorks; cmEmpregadosPedidos.CommandText = @”SELECT E.EmployeeID AS Codigo , C.FirstName AS PrimeiroNome , C.MiddleName AS SobrenomeMeio , C.LastName AS SobrenomeFinal , COUNT(*) AS QuantidadePedidos FROM Purchasing.PurchaseOrderHeader AS POH INNER JOIN HumanResources.Employee AS E ON POH.EmployeeID = E.EmployeeID INNER JOIN HumanResources.EmployeeDepartmentHistory AS EDH ON E.EmployeeID = EDH.EmployeeID AND EDH.EndDate IS NULL -- Empregado em atividade INNER JOIN Person.Contact AS C ON E.ContactID = C.ContactID WHERE POH.Status = 4 -- Pedido finalizado (Complete) GROUP BY E.EmployeeID, C.FirstName, C.MiddleName, C.LastName ORDER BY C.FirstName, C.MiddleName, C.LastName”; cnAdventureWorks.Open(); drEmpregadosPedidos = cmEmpregadosPedidos.ExecuteReader(); xwEmpregadosPedidos.WriteStartDocument(); xwEmpregadosPedidos.WriteStartElement(“Empregados”); while (drEmpregadosPedidos.Read()) { xwEmpregadosPedidos.WriteStartElement(“Empregado”); for (int campo = 0; campo < drEmpregadosPedidos.FieldCount; campo++) { xwEmpregadosPedidos.WriteElementString(drEmpregadosPedidos.GetName(campo), drEmpregadosPedidos[campo].ToString()); } xwEmpregadosPedidos.WriteEndElement(); } xwEmpregadosPedidos.WriteEndElement(); } catch (Exception ex) { Response.Clear(); Response.Write(string.Format(“<Erro>{0}</Erro>”, ex.Message)); } finally { if (drEmpregadosPedidos != null) { drEmpregadosPedidos.Close(); } if (cnAdventureWorks != null) { cnAdventureWorks.Close(); } if (xwEmpregadosPedidos != null) { xwEmpregadosPedidos.Close(); } } }}

A string de conexão considera que o servidor de banco de dados SQL Server 2005 Express Edition esteja instalado na instância SQLExpress da máquina local e que o banco de dados AdventureWorks esteja instalado nesse servidor. Se neces-sário, modifique a string de conexão para refletir a sua configuração.

Adicione um Web Form nomeando-o “Empregados.aspx” e selecionando a op-ção Place code in separate file. Apague todo o código HTML do arquivo Empregados.aspx, deixando somente a diretiva @Page. Codifique o arquivo Empregados.aspx.cs como apresentado na Listagem 5.

Observe na Listagem 5, que um objeto da classe SqlDataReader é utilizado para navegar pelos registros do resultado de uma consulta SQL para obter dados de empregados em atividade e a quantidade de pedidos por eles atendidos no banco de dados AdventureWorks num servidor SQL Server 2005.

Durante a navegação, um objeto do tipo XmlTextWriter é usado para montar o documento XML dinamicamente. A Listagem 6 apresenta um fragmento de documento XML gerado dinamicamente pela página Empregados.aspx.

Ainda na Listagem 5, pode-se verificar que se ocorrer algum erro durante o processamento, então a exceção lançada será capturada e a mensagem de erro será enviada em uma estrutura XML para o browser cliente.

A Listagem 7 apresenta um documento XML com uma mensagem de erro gerada quando o serviço do servidor de banco de dados do SQL Server 2005 está para-do durante o processamento da página Empregados.aspx.

JavaScript 1.5, 1.6 e 1.7JavaScript é uma linguagem de script

fundamentada no conceito de progra-mação baseada em protótipos que foi de-senvolvida pela Netscape Communications Corporation e introduzida em 1995.

A linguagem JavaScript foi padronizada pela Ecma International em 1997, sendo denominada ECMAScript e, atualmente, seu desenvolvimento é conduzido pela Mozilla Foundation. A implementação do ECMAScript no Internet Explorer é denominada JScript.

Porém, atualmente é comum utilizar o

Page 15: dotNET42-Final.pdf

14 .NET Magazine - Mini-curso de AJAX – Parte 1 Edição 42 - .NET Magazine 15

MiNi-curso – aJaX

nome JavaScript de forma generalizada, incluindo a implementação no browser da Microsoft. A linguagem é mais co-nhecida pelo seu uso extensivo em Web Sites como JavaScript do lado do cliente, mas também é usada em scripts para acesso a objetos incorporados em outras aplicações.

A linguagem JavaScript 1.5 segue o pa-drão ECMA-262, 3a edição do ECMAScript Language Specification de dezembro de 1999, criado pela comitê técnico TC39 do Ecma International.

O JavaScript 1.6 introduz novas carac-terísticas ao JavaScript 1.5: E4X (ECMAS-cript for XML), novos métodos do Array, dentre outras novidades.

O JavaScript 1.7 introduz novas ca-racterísticas ao JavaScript 1.6: iterators, expressões let, dentre outras novidades. Por uma questão de compatibilidade com uma quantidade maior de browsers, atualmente é interessante se limitar aos recursos da linguagem JavaScript 1.5.

O JavaScript 2.0 será a próxima revisão principal da linguagem JavaScript. Ela está sendo padronizada pelo Ecma Inter-national como a 4a edição do ECMAScript Language Specification.

Objeto XMLHttpRequestO XMLHttpRequest define uma API

que fornece funcionalidades para scripts do lado do cliente para transferência de dados entre o browser e o servidor Web. O objeto suporta qualquer formato base-ado em texto, incluindo XML e JSON. Ele pode ser utilizado para fazer requisições ao servidor Web usando os protocolos HTTP e HTTPS e representa uma das partes mais importantes do AJAX.

O conceito por trás do XMLHttpRequest foi desenvolvido originalmente pela Microsoft como parte do Outlook Web Access 2000. A implementação inicial da Microsoft era chamada XMLHTTP e foi disponibilizada no Internet Explorer 5.0 como um ActiveX, sendo acessível via JScript, VBScript ou outra linguagem de script cliente suportada pelo browser via plug-ins.

Do Internet Explorer 5.0 ao 6.0, o XM-LHTTP foi implementado como um ActiveX fornecido pelo MSXML. Baseado no objeto XMLHTTP da Microsoft, a Fun-dação Mozilla incorporou a primeira im-

Listagem 6. Fragmento do documento XML de empregados gerado dinamicamente

<?xml version=”1.0” encoding=”iso-8859-1”?><Empregados> <Empregado> <Codigo>264</Codigo> <PrimeiroNome>Annette</PrimeiroNome> <SobrenomeMeio>L</SobrenomeMeio> <SobrenomeFinal>Hill</SobrenomeFinal> <QuantidadePedidos>340</QuantidadePedidos> </Empregado> ...</Empregados>

Listagem 7. Fragmento de documento XML com um erro de processamento

<Erro> An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)</Erro>

Listagem 8. Arquivo JavaScript AJAX.js

var READY_STATE_UNINITIALIZED = 0;var READY_STATE_LOADING = 1;var READY_STATE_LOADED = 2;var READY_STATE_INTERACTIVE = 3;var READY_STATE_COMPLETE = 4;

var req = null;

function criarXMLHTTPRequest() { var xRequest = null;

if (window.XMLHttpRequest) { //Mozilla 1.0+, Netscape 8.0+, Firefox 1.0+, Safari 1.2+, Internet Explorer 7.0+ xRequest = new XMLHttpRequest(); } else if (window.ActiveXObject) { //Internet Explorer 5.0, 5.5, 6.0 var progIDs = [“MSXML2.XMLHTTP.6.0”, “MSXML2.XMLHTTP.4.0”, “MSXML2.XMLHTTP.3.0”, “MSXML2.XMLHTTP”, “Microsoft.XMLHTTP”]; for (var i = 0; xRequest == null && i < progIDs.length; i++) { xRequest = new ActiveXObject(progIDs[i]); } } return xRequest;}

function enviarRequisicaoHTTP(url, parametros, metodoHTTP, metodoCallback) { if (!metodoHTTP) { metodoHTTP = “GET”; } req = criarXMLHTTPRequest();

if (req) { req.onreadystatechange = metodoCallback; req.open(metodoHTTP, url, true); req.setRequestHeader(“Content-Type”, “application/x-www-form-urlencoded”); req.send(parametros); } else { alert(“Objeto XMLHttpRequest não suportado pelo “+“browser.”); }}

Listagem 9. Script para vincular Pedidos.htm ao script AJAX.js

...<head>

<title>Adventure Works - Pedidos por empregado</title> <link href=”Estilos.css” rel=”stylesheet” type=”text/css” /> <script type=”text/javascript” src=”Scripts/AJAX.js”></script>

</head>...

Page 16: dotNET42-Final.pdf

16 .NET Magazine - Mini-curso de AJAX – Parte 1 Edição 42 - .NET Magazine 17

plementação nativa do XMLHttpRequest no browser Mozilla 1.0 em 2002.

Posteriormente, o suporte nativo ao XMLHttpRequest foi implementado em outros browsers: Apple Safari desde a versão 1.2, Opera desde a versão 8.0, Kon-queror, dentre outros. A própria Micro-soft resolveu incluir o XMLHttpRequest como um objeto nativo de script a partir do Internet Explorer 7.0.

A linguagem JavaScript do lado do cliente e o XMLHttpRequest serão utili-zados para estabelecer uma comunicação HTTP assíncrona entre o browser e o servidor Web.

No projeto do Web Site, crie uma pasta com nome “Scripts” e dentro dela acres-cente um arquivo JScript com o nome “AJAX.js”.

A Listagem 8 apresenta um código Ja-vaScript para criar um XMLHttpRequest de modo cross-browser e utilizá-lo para fazer uma requisição HTTP assíncrona para o servidor Web a partir do brow-ser.

No início do script, cinco variáveis auxi-liares são definidas com os estados mo-nitorados pelo XMLHttpRequest durante uma comunicação HTTP assíncrona entre o browser e o servidor Web. A variável req é definida para conter uma referência a um XMLHttpRequest. O método criarXM-LHTTPRequest é responsável por criar um XMLHttpRequest de modo cross-browser, funcionando em versões variadas de diversos browsers.

Finalmente, o método enviarRequisica-oHTTP recebe informações sobre como enviar uma requisição HTTP assíncrona do browser para o servidor Web. Obser-ve que um argumento metodoCallback permite definir um método JavaScript de retorno da chamada assíncrona, que será responsável pelo processamento da resposta enviada pelo servidor Web.

A Listagem 9 apresenta o elemento <script> que deve ser acrescentado ao cabeçalho da página Pedidos.htm para vinculá-la ao código JavaScript definido no arquivo AJAX.js.

DOM Level 3O DOM (Document Object Model) Level 3

Core Specification define um conjunto de objetos e interfaces para acessar e mani-pular documentos HTML e XML.

Listagem 10. Arquivo JavaScript AvdWorks.js

var TIPO_INFO_SELECIONAR_EMPREGADO = 1;var TIPO_INFO_SELECIONAR_MES_ANO_PEDIDOS = 2;

function apresentarMensagemProgresso(mensagem) { var divMensagem = document.getElementById(“divMensagem”); with (divMensagem) { innerHTML = mensagem; style.visibility = “visible”; }}

function esconderMensagemProgresso() { var divMensagem = document.getElementById(“divMensagem”); with (divMensagem) { innerHTML = “”; style.visibility = “hidden”; }}

function apresentarInfo(tipoInfo) { var selectEmpregados = document.getElementById(“selectEmpregados”); var selectMesesAnosPedidos = document.getElementById(“selectMesesAnosPedidos”); var spanEmpregadoPedidos = document.getElementById(“spanEmpregadoPedidos”); var spanMesAnoPedidos = document.getElementById(“spanMesAnoPedidos”); var divMesAnoPedidos = document.getElementById(“divMesAnoPedidos”); switch (tipoInfo) { case TIPO_INFO_SELECIONAR_EMPREGADO: selectMesesAnosPedidos.options.length = 0; selectMesesAnosPedidos.options[0] = new Option( “Selecione um empregado para obter os meses “+“e anos com pedidos...”, “”); spanEmpregadoPedidos.innerHTML = “”; spanMesAnoPedidos.innerHTML = “”; divMesAnoPedidos.innerHTML = “Selecione um “+ “empregado e um mês e ano para obter os “+“pedidos do mês...”; break; case TIPO_INFO_SELECIONAR_MES_ANO_PEDIDOS: spanMesAnoPedidos.innerHTML = “”; divMesAnoPedidos.innerHTML = “Selecione um mês “+“e ano para obter os pedidos do mês...”; }}

function preencherListaEmpregados() { if (req.readyState == READY_STATE_COMPLETE) { var selectEmpregados = document.getElementById(“selectEmpregados”); selectEmpregados.options.length = 0; selectEmpregados.options[0] = new Option(“”, “”); var docEmpregados = req.responseXML; var eleRaiz = docEmpregados.documentElement; switch (eleRaiz.nodeName) { case “Empregados”: var nodeListEmpregados = eleRaiz.getElementsByTagName(“Empregado”); for (var i = 0; i < nodeListEmpregados.length; i++) { var nodeEmpregado = nodeListEmpregados.item(i); var obterValor = function(elemento) { return nodeEmpregado.getElementsByTagName( elemento).item(0).firstChild.nodeValue; }; var codigo = obterValor(“Codigo”); var primeiroNome = obterValor(“PrimeiroNome”); var sobrenomeMeio = obterValor(“SobrenomeMeio”); var sobrenomeFinal = obterValor(“SobrenomeFinal”); var quantidadePedidos = parseInt(obterValor(“QuantidadePedidos”)); var textoOpcaoSelect = primeiroNome + “ “ + sobrenomeMeio + “ “ + sobrenomeFinal + “ (“ + quantidadePedidos + “ pedido” + (quantidadePedidos > 1 ? “s” : “”) + “)”; var valorOpcaoSelect = codigo; selectEmpregados.options[i + 1] = new Option(textoOpcaoSelect, valorOpcaoSelect); } break; case “Erro”: var erro = eleRaiz.firstChild.nodeValue; alert(“Ocorreu um erro no processo de carga “+“dos empregados.\n(“ + erro + “)”); } req = null; esconderMensagemProgresso(); }}

window.onload = function() { apresentarMensagemProgresso(“Carregando os “+“empregados responsáveis pelos pedidos...”); enviarRequisicaoHTTP(“Empregados.aspx”, null, null, preencherListaEmpregados); apresentarInfo(TIPO_INFO_SELECIONAR_EMPREGADO);};

Page 17: dotNET42-Final.pdf

16 .NET Magazine - Mini-curso de AJAX – Parte 1 Edição 42 - .NET Magazine 17

MiNi-curso – aJaX

Listagem 11. Script para vincular Pedidos.htm ao script AdvWorks.js

...<head> <title>Adventure Works - Pedidos por empregado</title> <link href=”Estilos.css” rel=”stylesheet” type=”text/css” /> <script type=”text/javascript” src=”Scripts/AJAX.js”></script> <script type=”text/javascript” src=”Scripts/AdvWorks.js”></script></head>...

Listagem 12. Arquivo code-behind PedidosPorEmpregado.aspx.cs

...using System.Collections.Generic;using System.Data.SqlClient;using System.IO;using System.Text;

public partial class PedidosPorEmpregado : System.Web.UI.Page{ protected void Page_Load(object sender, EventArgs e) { Response.ContentType = “application/json”; string codigoEmpregado = Request.Form[“CodigoEmpregado”]; int employeeID = (codigoEmpregado == null) ? 0 : int.Parse(codigoEmpregado); TextWriter twPedidosMesAno = null; SqlConnection cnAdventureWorks = null; SqlDataReader drPedidosMesAno = null; try

{ cnAdventureWorks = new SqlConnection(); cnAdventureWorks.ConnectionString = ConfigurationManager.ConnectionStrings[ “cnAdventureWorks”].ConnectionString; SqlCommand cmPedidosMesAno = new SqlCommand(); cmPedidosMesAno.Connection = cnAdventureWorks; cmPedidosMesAno.CommandText = @” SELECT MONTH(OrderDate) AS mesPedidos, YEAR(OrderDate) AS anoPedidos, COUNT(*) AS quantidade FROM Purchasing.PurchaseOrderHeader WHERE EmployeeID = @EmployeeID GROUP BY MONTH(OrderDate), YEAR(OrderDate) ORDER BY anoPedidos DESC, mesPedidos DESC”; cmPedidosMesAno.Parameters.Add(“@EmployeeID”, SqlDbType.Int).Value = employeeID; cnAdventureWorks.Open(); drPedidosMesAno = cmPedidosMesAno.ExecuteReader(); List<string> arrayObjetosJson = new List<string>();

while (drPedidosMesAno.Read()) { string[] objetoJson = new string[drPedidosMesAno.FieldCount]; for (int campo = 0; campo < drPedidosMesAno.FieldCount; campo++) { objetoJson[campo] = string.Format(“\”{0}\”:{1}”, drPedidosMesAno.GetName( campo), drPedidosMesAno[campo].ToString()); } arrayObjetosJson.Add(string.Format(“{{{0}}}”, string.Join(“,”, objetoJson))); }

twPedidosMesAno = new StreamWriter(Response.OutputStream, Encoding.GetEncoding(“ISO-8859-1”));

twPedidosMesAno.Write(string.Format(“[{0}]”, string.Join(“,\n”, arrayObjetosJson.ToArray()))); }

catch (Exception ex) { Response.Clear(); Response.Write(string.Format(“{{\”erro\”:\”{0}\”}}”, ex.Message)); }

finally {

if (drPedidosMesAno != null) { drPedidosMesAno.Close(); }

if (cnAdventureWorks != null) { cnAdventureWorks.Close(); }

if (twPedidosMesAno != null) { twPedidosMesAno.Close(); } } }}

O DOM Level 3 Load and Save Specifica-tion define um conjunto de interfaces para carregar e salvar documentos HTML e XML.

Com o objetivo de tornar o código Ja-vaScript do lado do cliente compatível com um maior número de browsers, somente serão usados recursos do DOM Level 1. Acrescente um arquivo JScript com o nome de “AdvWorks.js” dentro da pasta Scripts.

A Listagem 10 apresenta código JavaS-cript para, entre outras tarefas, enviar uma requisição HTTP ao servidor Web para receber a relação de empregados no formato XML de forma assíncrona.

Segue uma breve descrição das fun-cionalidades presentes no arquivo Ad-vWorks.js.•apresentarMensagemProgresso: mostra

uma mensagem de progresso de uma chamada assíncrona ao servidor Web para o usuário;•esconderMensagemProgresso: oculta

uma mensagem de progresso após a finalização de uma chamada assíncrona ao servidor Web;•apresentarInfo: apresenta informa-

ções explicativas, de acordo com o tipo escolhido, sobre como o usuário deve proceder para consultar informações de pedidos atendidos por empregados da empresa Adventure Works;•preencherListaEmpregados: método

callback de uma chamada assíncrona ao servidor Web para receber a relação de empregados em formato XML e preen-cher o quadro de listagem apropriado com uso de DOM;•evento onload do objeto window: execu-

ta uma chamada assíncrona ao servidor Web para obter a relação de empregados que atenderam a pedidos de clientes, dei-xando o usuário informado do progresso e de como proceder.

A Listagem 11 apresenta o elemento <script> que deve ser acrescentado ao cabeçalho da página Pedidos.htm para vinculá-la ao código JavaScript definido no arquivo AdvWorks.js.

JSONO JSON (JavaScript Object Notation) é um

formato leve para troca de dados baseado em um subconjunto da linguagem de programação JavaScript, padrão ECMA-

Page 18: dotNET42-Final.pdf

18 .NET Magazine - Mini-curso de AJAX – Parte 1 Edição 42 - .NET Magazine 19

262 3a edição. Na notação JSON:•objetos são considerados um conjunto

não ordenado de pares nome/valor. Um objeto é delimitado por chaves. Cada nome é separado do valor por dois pontos e os pares nome/valor são separados por vírgulas;

Listagem 13. Fragmento de texto no formato JSON gerado dinamicamente

[{“mesPedidos”:9,”anoPedidos”:2004,”quantidade”:4}, {“mesPedidos”:8,”anoPedidos”:2004,”quantidade”:39}, {“mesPedidos”:7,”anoPedidos”:2004,”quantidade”:35},... {“mesPedidos”:2,”anoPedidos”:2002,”quantidade”:5}, {“mesPedidos”:1,”anoPedidos”:2002,”quantidade”:1}]

Listagem 14. Fragmento de texto com um erro de processamento

{“erro”:”An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)”}

Listagem 15. Acrescentando código ao arquivo AvdWorks.js

window.onload = function() { ... //código anterior var selectEmpregados = document.getElementById(“selectEmpregados”); selectEmpregados.onchange = function() { if (selectEmpregados.selectedIndex == 0) { apresentarInfo(TIPO_INFO_SELECIONAR_EMPREGADO); } else { var spanEmpregadoPedidos = document.getElementById(“spanEmpregadoPedidos”); var codigoEmpregado; with (selectEmpregados) { spanEmpregadoPedidos.innerHTML = options[selectedIndex].text; codigoEmpregado = options[selectedIndex].value; } var parametroEmpregado = “CodigoEmpregado=” + codigoEmpregado; apresentarMensagemProgresso(“Carregando os meses e os anos dos pedidos...”); enviarRequisicaoHTTP(“PedidosPorEmpregado.aspx”, parametroEmpregado, “POST”, preencherListaMesesAnosPedidos); apresentarInfo(TIPO_INFO_SELECIONAR_MES_ANO_PEDIDOS); } };};var meses = [“Janeiro”, “Fevereiro”, “Março”, “Abril”, “Maio”, “Junho”, “Julho”, “Agosto”, “Setembro”, “Outubro”, “Novembro”, “Dezembro”];function preencherListaMesesAnosPedidos() { if (req.readyState == READY_STATE_COMPLETE) { var selectMesesAnosPedidos = document.getElementById(“selectMesesAnosPedidos”); selectMesesAnosPedidos.options.length = 0; selectMesesAnosPedidos.options[0] = new Option(“”, “”); var arrJSONMesesAnosPedidos = eval(“(“ + req.responseText + “)”); if (arrJSONMesesAnosPedidos.constructor.toString().indexOf(“function Array()”) != -1) { for (var i = 0; i < arrJSONMesesAnosPedidos.length; i++) { with (arrJSONMesesAnosPedidos[i]) { var textoOpcaoSelect = meses[ mesPedidos - 1] + “ de “ + anoPedidos + “ (“ + quantidade + “ pedido” + (quantidade > 1 ? “s” : “”) + “)”; var valorOpcaoSelect = mesPedidos + “,” + anoPedidos; selectMesesAnosPedidos.options[i + 1] = new Option(textoOpcaoSelect, valorOpcaoSelect); } } } else if (arrJSONMesesAnosPedidos.erro) { alert(“Ocorreu um erro no processo de carga dos meses e anos dos pedidos.\n(“ + arrJSONMesesAnosPedidos.erro + “)”); } req = null; esconderMensagemProgresso(); }}

•arrays são considerados uma coleção ordenada de valores. Um array é deli-mitado por colchetes. Os valores são separados por vírgulas.

O uso do formato JSON como mecanis-mo de transporte de dados tem algumas

implicações de segurança. Um método de ataque a aplicações Web denomina-do JavaScript Hijacking permite o envio de dados não autorizados para um site remoto, iludindo a política de mesma origem (Same Origin Policy) garantida pelos browsers mais modernos.

Para obter informações detalhadas sobre esse tipo de ataque e técnicas de proteção, leia o artigo JavaScript Hijacking publicado pela empresa Fortify Software, cujo link pode ser encontrado no final deste artigo.

O artigo cita a análise de 12 frameworks AJAX populares, incluindo o Microsoft ASP.NET AJAX, concluindo que somente o DWR 2.0 (Direct Web Remoting) imple-menta mecanismos para prevenir esse tipo de ataque.

Porém, o artigo analisou uma versão anterior à versão 1.0 final do Microsoft ASP.NET AJAX, quando o mesmo ainda era conhecido pelo codinome Microsoft “Atlas”. Em 4 de abril de 2007, o Scott Gu-thrie (um gerente geral da Divisão de De-senvolvimento da Microsoft) postou em seu blog o artigo “JSON Hijacking and How ASP.NET AJAX 1.0 Avoids these Attacks” que contesta a informação de que o ASP.NET AJAX não implementa mecanismos para prevenir ataques JavaScript Hijacking. Veja o endereço da postagem no blog do Scott Guthrie no final deste artigo.

Adicione um Web Form nomeando-o “PedidosPorEmpregado.aspx” e selecio-nando a opção Place code in separate file. Apague todo o código HTML da página PedidosPorEmpregado.aspx, deixando so-mente a diretiva @Page. Codifique o ar-quivo PedidosPorEmpregado.aspx.cs como apresentado na Listagem 12.

Observe na Listagem 12 que um objeto da classe SqlDataReader é utilizado para navegar pelos registros do resultado de uma consulta SQL, usada para obter a quantidade de pedidos por mês e ano de um determinando empregado no banco de dados AdventureWorks no servidor SQL Server 2005.

Durante a navegação, uma coleção genérica List<string>, arrays de strings e um objeto StreamWriter são usados para montar um texto no formato JSON. A Listagem 13 apresenta um fragmento de texto no formato JSON gerado dinamica-mente pela página PedidosPorEmpregado.

Page 19: dotNET42-Final.pdf

18 .NET Magazine - Mini-curso de AJAX – Parte 1 Edição 42 - .NET Magazine 19

MiNi-curso – aJaX

aspx quando o parâmetro CodigoEmpre-gado, passado pelo método HTTP POST, é igual a 264.

Ainda na Listagem 12, pode-se verifi-car que se ocorrer algum erro durante o processamento, então a exceção lançada será capturada e a mensagem de erro será enviada no formato JSON para o browser cliente.

A Listagem 14 apresenta um texto com uma mensagem de erro gerada quando o serviço do servidor de banco de dados do SQL Server 2005 está parado durante o processamento da página Web Pedidos-PorEmpregado.aspx.

Acrescente mais JavaScript ao código de manipulação do evento onload do objeto window no arquivo AdvWorkd.js, um array nomeado meses e um outro método callback nomeado preencherLista-MesesAnosPedidos, conforme apresentado na Listagem 15.

Segue uma breve descrição das fun-cionalidades acrescentadas no arquivo AdvWorks.js.•evento onload do objeto window: acres-

centa código para manipular o evento onchange do objeto Select com id igual a selectEmpregados. Se o usuário selecionar um empregado diferente, então é execu-tada uma chamada assíncrona ao servi-dor Web para obter a relação de meses e anos com as respectivas quantidades de pedidos atendidos pelo empregado sele-cionado, deixando o usuário informado do progresso e de como proceder;•array meses: armazena os nomes dos

meses do ano em idioma português bra-sileiro;•preencherListaMesesAnosPedidos: méto-

do callback de uma chamada assíncrona ao servidor Web para receber a relação de meses e anos com as respectivas quantidades de pedidos atendidos pelo empregado selecionado em formato JSON e preencher o quadro de listagem apropriado com uso de DOM.

Finalização da aplicação de demonstração

Para finalizar a aplicação Web AJAX de demonstração, vamos criar uma página Web ASP.NET para gerar o código de uma tabela HTML com os pedidos de um dado empregado, num determinado mês e ano.

Listagem 16. Arquivo PedidosPorEmpregadoMesAno.aspx

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”PedidosPorEmpregadoMesAno.aspx.cs” Inherits=”PedidosPorEmpregadoMesAno” EnableViewState=”false” %><form runat=”server”> <asp:gridview id=”gvPedidosPorEmpregadoMesAno” runat=”server” autogeneratecolumns=”False” CssClass=”dados”> <Columns> <asp:BoundField DataField=”Codigo” HeaderText=”C&#243;digo”> <ItemStyle HorizontalAlign=”Center” /> </asp:BoundField> <asp:BoundField HtmlEncode=”False” DataFormatString=”{0:d}” DataField=”DataPedido” HeaderText=”Data do pedido”> <ItemStyle HorizontalAlign=”Center” /> </asp:BoundField> <asp:BoundField HtmlEncode=”False” DataFormatString=”{0:C}” DataField=”Subtotal” HeaderText=”Subtotal”> <ItemStyle HorizontalAlign=”Right” /> </asp:BoundField> <asp:BoundField HtmlEncode=”False” DataFormatString=”{0:C}” DataField=”Taxa” HeaderText=”Taxa”> <ItemStyle HorizontalAlign=”Right” /> </asp:BoundField> <asp:BoundField HtmlEncode=”False” DataFormatString=”{0:C}” DataField=”Frete” HeaderText=”Frete”> <ItemStyle HorizontalAlign=”Right” /> </asp:BoundField> <asp:BoundField HtmlEncode=”False” DataFormatString=”{0:C}” DataField=”Total” HeaderText=”Total”> <ItemStyle HorizontalAlign=”Right” /> </asp:BoundField> </Columns> <AlternatingRowStyle CssClass=”alt” /> </asp:gridview> <asp:label id=”lblErro” runat=”server”></asp:label></form>

Adicione um Web Form nomeando-o “PedidosPorEmpregadoMesAno.aspx” selecionando a opção Place code in separate file. Apague todo o código HTML da pá-gina PedidosPorEmpregado.aspx, deixando somente a diretiva @Page e acrescentando o elemento <form runat=”server”></form>, pois Web Server Controls somente podem ser hospedados em páginas ASPX que são Web Forms.

Acrescente um GridView e um Label ao Web Form ASPX e defina as propriedades como apresentado na Listagem 16.

Codifique o arquivo PedidosPorEmpre-gadoMesAno.aspx.cs como apresentado na Listagem 17.

O código da Listagem 17 recebe os pa-râmetros com o código do empregado, o mês e o ano dos pedidos enviados pelo método HTTP POST. Depois, executa uma consulta no banco de dados Adventu-reWorks que retorna um SqlDataReader.

Esse objeto é passado para a proprie-dade DataSource do GridView para gerar o código XHTML de uma tabela forma-tando os dados. Caso ocorra algum erro de processamento, a exceção lançada é capturada e a mensagem de erro é colo-cada no Label.

Com uso das tecnologias do AJAX, parte deste código XHTML será embu-

tido numa parte da página Pedidos.htm, conforme apresentado no código da Listagem 18 a seguir.

Segue uma breve descrição das fun-cionalidades acrescentadas no arquivo AdvWorks.js.•evento onload do objeto window: acres-

centa código para manipular o evento onchange do objeto Select com id igual a selectMesesAnosPedidos. Se o usuário sele-cionar um par mês/ano diferente, então é executada uma chamada assíncrona ao servidor Web para obter a relação de pedidos do empregado no mês e ano selecionados;•apresentarTabelaPedidosEmpregadoMe-

sAno: método callback de uma chamada assíncrona ao servidor Web para rece-ber a relação de pedidos do empregado no mês e ano selecionados em formato XHTML e atualizar a interface com a tabela gerada dinamicamente pelo Grid-View.

A Figura 3 apresenta a interface da página Web Pedidos.htm visualizada no Internet Explorer 7.0 após o usuário se-lecionar opções disponíveis nos quadros de seleção.

O que é o ASP.NET AJAX 1.0?O ASP.NET AJAX 1.0 é um framework

Page 20: dotNET42-Final.pdf

20 .NET Magazine - Mini-curso de AJAX – Parte 1 Edição 42 - .NET Magazine 21

Listagem 17. Arquivo code-behind PedidosPorEmpregadoMesAno.aspx.cs

...using System.Data.SqlClient;using System.Web.UI.WebControls;

public partial class PedidosPorEmpregadoMesAno : System.Web.UI.Page{ protected void Page_Load(object sender, EventArgs e) { Response.ContentType = “text/xml”; int employeeID = (Request.Form[“CodigoEmpregado”] == null) ? 0 : int.Parse(Request.Form[“CodigoEmpregado”]); int mesPedidos = (Request.Form[“MesPedidos”] == null) ? 0 : int.Parse(Request.Form[“MesPedidos”]); int anoPedidos = (Request.Form[“AnoPedidos”] == null) ? 0 : int.Parse(Request.Form[“AnoPedidos”]); SqlConnection cnAdventureWorks = null; SqlDataReader drPedidosPorEmpregadoMesAno = null;

try { cnAdventureWorks = new SqlConnection(); cnAdventureWorks.ConnectionString = ConfigurationManager. ConnectionStrings[ “cnAdventureWorks”].ConnectionString; SqlCommand cmPedidosPorEmpregadoMesAno = new SqlCommand(); cmPedidosPorEmpregadoMesAno.Connection = cnAdventureWorks; cmPedidosPorEmpregadoMesAno.CommandText = @” SELECT PurchaseOrderID AS Codigo , OrderDate AS DataPedido , SubTotal AS Subtotal , TaxAmt AS Taxa , Freight AS Frete , TotalDue AS Total FROM Purchasing.PurchaseOrderHeader AS PedidoMesAno WHERE EmployeeID = @EmployeeID AND MONTH(OrderDate) = @MesPedidos AND YEAR(OrderDate) = @AnoPedidos

ORDER BY OrderDate”;

cmPedidosPorEmpregadoMesAno.Parameters.Add( “@EmployeeID”, SqlDbType.Int).Value = employeeID;

cmPedidosPorEmpregadoMesAno.Parameters.Add( “@MesPedidos”, SqlDbType.Int).Value = mesPedidos;

cmPedidosPorEmpregadoMesAno.Parameters.Add( “@AnoPedidos”, SqlDbType.Int).Value = anoPedidos;

cnAdventureWorks.Open(); drPedidosPorEmpregadoMesAno = cmPedidosPorEmpregadoMesAno.ExecuteReader(); gvPedidosPorEmpregadoMesAno.DataSource = drPedidosPorEmpregadoMesAno; gvPedidosPorEmpregadoMesAno.DataBind(); }

catch (Exception ex) { lblErro.Text = ex.Message; }

finally {

if (drPedidosPorEmpregadoMesAno != null) { drPedidosPorEmpregadoMesAno.Close(); } if (cnAdventureWorks != null) { cnAdventureWorks.Close(); } } }}

gratuito, fornecido pela Microsoft, que permite a criação rápida de uma nova ge-ração de aplicações Web mais eficientes, mais interativas e altamente personaliza-das que funciona em todos os browsers mais populares da atualidade.

Seguem algumas das características do ASP.NET AJAX:•Corresponde a uma extensão do ASP.

NET 2.0, tendo integração com o Visual Studio 2005;•Permite a criação de interfaces Web ricas

com componentes AJAX reutilizáveis;•Fornece recursos para sofisticar as

páginas ASP.NET 2.0 existentes usando poderosos controles AJAX com suporte para todos os principais browsers mais modernos;•Possui recursos para acesso a serviços

e dados remotos diretamente do browser sem a necessidade de escrever uma gran-de quantidade de scripts;•Fornece os benefícios de um fra-

mework gratuito com suporte técnico fornecido pela Microsoft.

ConclusãoO AJAX permite criar aplicações Web

muito mais ricas, interativas e com res-postas mais rápidas para os usuários. Os recursos do AJAX e da Web 2.0 começa-ram a ser utilizados em diversos sites e corresponde a uma tendência real no desenvolvimento Web atualmente.

O objetivo deste primeiro artigo do mini-curso de ASP.NET AJAX foi apre-sentar e ilustrar as principais tecnologias que compõem o AJAX. A aplicação Web de demonstração mostrou como desen-volver toda a infra-estrutura de uma aplicação AJAX a partir do zero.

Desse modo, os desenvolvedores Web podem ter uma visão clara dos bastidores

Page 21: dotNET42-Final.pdf

20 .NET Magazine - Mini-curso de AJAX – Parte 1 Edição 42 - .NET Magazine 21

MiNi-curso – aJaX

Listagem 18. Acrescentando código ao arquivo AvdWorks.js

window.onload = function() { ... selectMesesAnosPedidos.onchange = function() { if (selectMesesAnosPedidos.selectedIndex == 0) { apresentarInfo(TIPO_INFO_SELECIONAR_MES_ANO_PEDIDOS); } else { var spanMesAnoPedidos = document.getElementById(“spanMesAnoPedidos”); var mesAnoPedidos, mesPedidos, anoPedidos; with (selectMesesAnosPedidos) { spanMesAnoPedidos.innerHTML = “ de “ + options[selectedIndex].text.toLowerCase(); mesAnoPedidos = options[selectedIndex].value.split(“,”); } mesPedidos = parseInt(mesAnoPedidos[0]); anoPedidos = parseInt(mesAnoPedidos[1]); var parametrosEmpregadoMesAno = “CodigoEmpregado=” + codigoEmpregado + “&MesPedidos=” + mesPedidos + “&AnoPedidos=” + anoPedidos; apresentarMensagemProgresso( “Carregando os pedidos do empregado no mês e ano...”); enviarRequisicaoHTTP(“PedidosPorEmpregadoMesAno.aspx”, parametrosEmpregadoMesAno, “POST”, apresentarTabelaPedidosEmpregadoMesAno); } } } };};

function apresentarTabelaPedidosEmpregadoMesAno() { if (req.readyState == READY_STATE_COMPLETE) { var xhtml = req.responseText; var indiceInicial = xhtml.indexOf(“<table”); if (indiceInicial >= 0) { var indiceFinal = xhtml.lastIndexOf(“</table>”) + 8; var xhtmlTabela = xhtml.substring(indiceInicial, indiceFinal); var divMesAnoPedidos = document.getElementById(“divMesAnoPedidos”); divMesAnoPedidos.innerHTML = xhtmlTabela; } else { var erro = req.responseXML.getElementsByTagName(“span”)[0].firstChild.nodeValue; alert(“Ocorreu um erro no processo de carga dos pedidos de um mês e ano.\n(“ + erro + “)”); } req = null; esconderMensagemProgresso(); }}

Figura 3. Resultado de uma consulta na página Pedidos.htm no IE 7.0

AJAX: The Official Microsoft ASP.NET AJAX Site

ajax.asp.net

Artigo “Ajax: A New Approach to Web Applications”, escrito

por Jesse James Garrett

www.adaptivepath.com/publications/essays/archives/

000385.php

Artigo “JavaScript Hijacking”

www.net-security.org/dl/articles/JavaScript_Hijacking.pdf

Artigo “JSON Hijacking and How ASP.NET AJAX 1.0 Avoids

these Attacks”

weblogs.asp.net/scottgu/archive/2007/04/04/json-hijacking-

and-how-asp-net-ajax-1-0-mitigates-these-attacks.aspx

Artigo “Tableless layout HOWTO”

www.w3.org/2002/03/csslayout-howto

Ecma International

www.ecma-international.org

Firefox 2.x

www.mozilla.com

Internet Explorer 7

www.microsoft.com/windows/downloads/ie

Google Maps

maps.google.com

Google Suggest

www.google.com/webhp?complete=1

JSON (JavaScript Object Notation)

www.json.org

Netscape Browser 8.x (está em desenvolvimento a versão 9

para várias plataformas)

browser.netscape.com

Opera 9.x

www.opera.com

SQL Server 2005 Express Edition SP2 e o banco de dados

AdventureWorks

msdn.microsoft.com/vstudio/express/sql/download

Visual Web Developer 2005 Express Edition SP1

msdn.microsoft.com/vstudio/express/downloads

World Wide Web Consortium (W3C)

www.w3.org

Links

do AJAX e compreender melhor como utilizar frameworks AJAX disponíveis, como o Microsoft ASP.NET AJAX.

Apesar de se ter utilizado o ASP.NET 2.0 para gerar os dados XML e JSON dinamicamente do lado do servidor, qualquer outra tecnologia do lado do servidor poderia ter sido utilizada, como: PHP, Servlets/JSP/JSF, ASP legado, CGI, ISAPI, dentre outras.

Nos próximos artigos do mini-curso se-rão abordados os recursos do framework Microsoft ASP.NET AJAX que tornam o de-senvolvimento de aplicações ASP.NET 2.0 com recursos de AJAX muito simples.

Page 22: dotNET42-Final.pdf

22 .NET Magazine - LINQ - A revolução do .NET 3.0 Edição 42 - .NET Magazine 23

LINQ - A revolução do .NET 3.0

Diego Dias ([email protected])

22 anos, desenvolvedor C# e Visual Basic .NET desde 2002. Fundador do site 2dSolucoes.NET (www.2dsolucoes.net) e atualmente é ana-lista de sistemas da Ciatech Soluções Digitais empresa do segmento de e-learning (www.ciatech.com.br).

A plataforma .NET passou por uma grande evolução, por exemplo na versão 2.0 tivemos o conceito

de Generics, como mais uma alternativa muito interessante diga-se de passagem, para trabalhar com mais flexibilidade na criação e na manipulação de objetos e coleções genéricas.

Então para os que achavam que não ha-via mais o que ser implementado no Fra-mework, ao menos em um curto período de tempo, estou aqui pra dizer que para nossa felicidade, a versão 3.0 veio com muitos outros recursos tão interessantes quanto o Generics:•Inferência do tipo de variáveis locais;•Tipos anônimos;•Expressões Lambda;•Métodos de extensão;•Propriedades automáticas;•Expressions Trees;•LINQ (Language Integrated Query);•Inicialização de objetos e coleções.Apesar de tantos recursos novos e

interessantes, este artigo vai focar prin-cipalmente na linguagem LINQ, que particularmente considero uma das mais interessantes inovações criadas para a plataforma .NET, assim como outros conceitos que são necessários para o seu entendimento.

O que é LINQ?A linguagem LINQ é basicamente uma

forma de unificar querys de consultas a bancos de dados, a documentos XML e consultas a coleções utilizando uma sintaxe única e muito flexível.

Isso com certeza facilita muito o dia a dia do desenvolvedor, pois não é difícil encontrar pessoas que já tiveram proble-mas para manipular, por exemplo, um documento XML no qual alguns nodes específicos deveriam ser capturados, por não conhecerem a XPATH. O mesmo acontece com as consultas ao banco de dados e a coleções de objetos, devido não haver uma sintaxe padrão que possibilite

Page 23: dotNET42-Final.pdf

22 .NET Magazine - LINQ - A revolução do .NET 3.0 Edição 42 - .NET Magazine 23

.NET 3.0

um resultado idêntico em situações bem distintas, como nos casos mencionados.

Quando se fala da linguagem LINQ, podemos subdividi-la em três módulos, sendo:•DLinq: Permite que sejam feitas con-

sultas em banco de dados (ADO.NET);•XLinq: Permite que sejam feitas con-

sultas em XML (System.XML);•Standard Query Operators: Permite que

sejam feitas consultas a objetos.Esse recurso até o momento só está

disponível nas linguagens C# e VB e na versão CTP do Visual Studio (Orcas) lançada em março desse ano e que pode ser baixada em: www.microsoft.com/down-loads/details.aspx?FamilyId=CF76FCBA-07-AF-47AC-8822-4AD346210670&displaylang=en#Instructions.

A Figura 1 mostra a estrutura da LINQ.

Sintaxe da LINQA sintaxe das query expressions (nome

dado às querys LINQ) é muito similar às querys SQL e XSQL, como podemos ver na Listagem 1.

Para iniciar uma query expression usamos a cláusula from e para finalizá-la usamos a cláusula select ou group, ao contrário das querys tradicionais criadas em SQL, onde a hierarquia é o oposto e a cláusula select vem antes da cláusula from, que por sua vez vem antes da cláusula group.

A cláusula from funciona como um laço e recupera em cada iteração um item da coleção e o armazena no identificador especificado na query. A let computa uma expressão a cada iteração e armazena o resultado no seu identificador.

A cláusula where filtra, excluindo os itens que não atendam às condições especificadas na query. No final da query temos a select ou group que especificam como será apresentado o resultado.

As cláusulas select e group ainda podem ser precedidas de uma cláusula orderby para ordenar o resultado. Além disso, podemos inserir o resultado em um identificador para que possa ser criada uma sub-query, o que é possível através da cláusula into.

Mais inovaçõesPara que fique mais fácil o entendimen-

to das query expressions acho interessante

Figura 1. Estrutura da Language Integrated Query (LINQ)

Listagem 1. Estrutura de uma query utilizando LINQ

clausula-from: from [tipo] identificador in coleção

clausula-join: join [tipo] identificador in coleção on item equals item join [tipo] identificador in coleção on item equals item into identificador

clausula-let: let identificador = expressão

clausula-orderby: orderby item direção[ascending, descending]

clausula-select: select item

clausula-group: group item by expressão

comentar brevemente o que torna o conceito da linguagem LINQ possível, então quando falamos de LINQ falamos também de:•Expressões Lambda - esse conceito é si-

milar ao conceito de métodos anônimos, porém com uma sintaxe mais concisa;•Inferência do tipo de variáveis locais

- permite que o tipo de variáveis possa ser definido apenas quando for atribuído um valor a ela, não confundam isso com a antiga Variant existente no Visual Basic e anteriores;•Tipos anônimos - permite que um

novo tipo possa ser criado dinamicamen-te sem que uma classe seja especificada, como é comum;•Métodos de extensão - permite que

seus métodos sejam utilizados em qual-quer objeto que seja do tipo do seu parâ-metro sem que o mesmo seja herdado;

•Inicialização de objetos - permite que os atributos de um objeto sejam iniciali-zados durante sua inicialização, sem o uso do seu construtor.

O código a seguir traz um método de-nominado Converte aparentemente sem utilidade, que não deixa explícito qual o tipo de retorno e quais são os tipos dos seus parâmetros, este método foi criado apenas para ilustrar o quão poderosos são esses novos recursos do Framework 3.0 e quanta flexibilidade eles podem oferecer:public static B Converte<A,B>(A value, Func<A, B> retorno){ return retorno(value); }

Isso só é possível com o uso de um conceito já comentado que é a inferência de tipos. A Listagem 2 ilustra o uso do método criado.

Page 24: dotNET42-Final.pdf

24 .NET Magazine - LINQ - A revolução do .NET 3.0 Edição 42 - .NET Magazine 25

Podemos notar que os tipos estão sendo definidos somente na chamada do mé-todo, onde o primeiro parâmetro, uma string, no caso da primeira chamada, vai ser convertido para o tipo definido no segundo parâmetro que nesse caso é um double.

Por isso, a segunda chamada vai gerar um erro, pois não se pode atribuir um objeto do tipo double a uma variável do tipo string.

Usando Query ExpressionsAgora que já vimos o que é a LINQ, va-

mos ver como criar nossas próprias query expressions. No código a seguir, podemos ver o uso de uma query expression para selecionar alguns itens de uma coleção: List<int> numeros = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };var resultado = from n in numeroswhere (n % 2) == 0select n;

Além do uso da query expression está sendo utilizado o conceito de iniciali-zação de objetos, que permite atribuir valores a um objeto ou coleção no mo-mento de sua inicialização, sem o uso do construtor. Pode-se notar que o uso das query expression deixa o código um tanto quanto mais legível e mais declarativo que um foreach, por exemplo.

Vamos a um exemplo um pouco mais interessante, onde vamos selecionar itens em uma coleção cujo um dos seus atributos esteja abaixo de um limite. A Listagem 3 ilustra o exemplo.

A listagem anterior traz além das query expressions um conceito interessante que é a inferência de tipos de variáveis locais, já comentado anteriormente. Para fazer uso desse recurso basta declarar as variáveis sem definir seu tipo e colocando no lugar do tipo a palavra var.

O conceito de inicialização de objetos, pode ser visualizado na Listagem 3, onde foi criada uma coleção de pessoa e não foi necessário utilizar o Add tradicional-mente utilizado para adicionar itens a uma coleção.

Analisando as query expression fica mais clara a sua sintaxe. Na primeira query expression foi criado um novo objeto, usando o conceito de tipos anônimos, pois ao contrário das querys SQL não é possível simplesmente adicionar os campos que queremos listar separados

Listagem 2. Método Converte sendo consumido

//Corretodouble retorno = Converte(“123”, i => Convert.ToDouble(i));

//Incorretostring retorno = Converte(“123”, i => Convert.ToDouble(i));

//Corretostring retorno = Converte(123, i => i.ToString());

Listagem 3. Query expression para selecionar itens de uma coleção

class pessoa{public int idade;public string nome;}

var funcionarios = new List<pessoa>{ new pessoa{idade = 22, nome=”Diego”}, new pessoa{idade = 28, nome=”Renata”}, new pessoa{idade = 52, nome=”Rogerio”}, new pessoa{idade = 52, nome=”Ricardo”}, new pessoa{idade = 33, nome=”Reginaldo”}, new pessoa{idade = 22, nome=”Fabiano”}, new pessoa{idade = 20, nome=”Edson”}, new pessoa{idade = 19, nome=”Edson”}, new pessoa{idade = 33, nome=”Eduardo”}, new pessoa{idade = 33, nome=”Eduardo”}, new pessoa{idade = 22, nome=”Eduardo”}};

//Lista os nomes e a quantidade de vezes que o mesmo se repetevar resultado = from p in funcionarios group p by p.nome into t select(new { nome = t.Key, Total = t.Count() });

//Lista os nomes com mais de 5 caracteresFunc<string, bool> filter = n => n.Length > 5;var resultado = from p in funcionarios where filter(p.nome) select p;

por uma vírgula. Para que consigamos selecionar dados específicos é preciso criar um objeto.

A listagem traz algumas possibilidades interessantes, por exemplo, na segunda query expression o filtro é criado separa-damente, o que dependendo da situação deixa mais claro o que está sendo feito. Para criar essa expressão capaz de filtrar os dados da query expression foi preciso criar uma expressão Lambda.

Agora que já sabemos como trabalhar os dados contidos em nossas coleções utilizando as query expressions, vamos ver se para trabalhar com banco de da-dos é realmente a mesma coisa, como foi comentado no início do artigo.

LINQ com banco de dados (DLinq)Para começar temos que criar um arqui-

vo do tipo DBML, onde serão definidas as hierarquias e as possíveis relações entre

Figura 2. Criação do arquivo DBML

Page 25: dotNET42-Final.pdf

24 .NET Magazine - LINQ - A revolução do .NET 3.0 Edição 42 - .NET Magazine 25

.NET 3.0

as tabelas que foram selecionadas, esse é um conceito muito similar ao de um DataSet tipado e até de um TableAdapter.

Depois que o arquivo DBML é criado, ele gera uma interface gráfica, para onde devem ser arrastadas as tabelas existentes na conexão criada no Server Explorer e mais dois arquivos, sendo que um deles tem a extensão .CS.

Esse arquivo contém toda a definição das colunas das tabelas, hierarquia e relacionamentos. As Figuras 2 e 3 ilus-tram a criação e a seleção de uma tabela do banco de dados, que nesse caso é a tabela Usuario.

Agora é preciso definir um objeto como mostrado a seguir para que possamos manipular as tabelas existentes no objeto DataClasse.

DataClasses1DataContext db = new DataClasses1DataContext();

Com o objeto de manipulação criado podemos dar início as query expression, por exemplo, em um código anterior, foi criada uma query expression que selecio-nava apenas os números pares existentes em uma coleção de inteiros.

Que tal selecionar apenas os usuários que têm seus IDs pares e para ficar mais legal vamos utilizar a mesma query ex-pression para demonstrar a flexibilidade que tanto foi citada neste artigo. A Lista-gem 4 mostra como ficaria a query expres-sion se aplicada sobre os dados contidos na tabela de usuários do banco de dados. Veja o resultado na Figura 4.

Até agora só foram criadas query expres-sions simples, que tal utilizarmos alguns outros recursos comummente utilizados

Figura 4. Resultado da Query Expression

Figura 3. Diagrama que é criado depois que uma tabela é selecionada

Listagem 4. Query expression que seleciona apenas os IDs pares

var users = from todos in db.usuarios where (todos.id % 2) == 0 select todos;foreach (var u in users){ Console.WriteLine(string.Format(“id: {0} nome: {1}”, u.id, u.nome));}

Listagem 5. Implementação das classes Cliente e Pedido

public class Cliente{ public int ClienteId; public string Nome; public string Endereco; public string Cidade; public string Pais; public string Telefone; public List<Pedido> Pedidos;

public List<Cliente> getClientes() { return new List<Cliente> { new Cliente { ClienteId = 1, Nome = “Diego”, Endereco = “Não definido”, Cidade = “São Paulo”, Pais = “Brasil”, Telefone = “555-5555” },

new Cliente { ClienteId = 2, Nome = “Fabiano”, Endereco = “Não definido”, Cidade = “São Paulo”, Pais = “Brasil”, Telefone = “555-5555” },

new Cliente { ClienteId = 3, Nome = “Harrison”, Endereco = “Não definido”, Cidade = “São Paulo”, Pais = “Brasil”, Telefone = “555-5555” },

new Cliente { ClienteId = 4, Nome = “Leonardo”, Endereco = “Não definido”, Cidade = “São Paulo”, Pais = “Brasil”, Telefone = “555-5555” },

new Cliente { ClienteId = 5, Nome = “Rafael”, Endereco = “Não definido”, Cidade = “São Paulo”, Pais = “Brasil”, Telefone = “555-5555” },

new Cliente { ClienteId = 6, Nome = “Alex”, Endereco = “Não definido”, Cidade = “São Paulo”, Pais = “Brasil”, Telefone = “555-5555” } }; }}public class Pedido{ public int PedidoId; public Cliente Cliente; public DateTime OrderDate; public double Total;

public List<Pedido> getPedidos() { return new List<Pedido> { new Pedido { Cliente = new Cliente { ClienteId = 1 }, PedidoId = 1, Total = 100 }, new Pedido { Cliente = new Cliente { ClienteId = 1 }, PedidoId = 2, Total = 1000.00 }, new Pedido { Cliente = new Cliente { ClienteId = 2 }, PedidoId = 3, Total = 10000.00 }, new Pedido { Cliente = new Cliente { ClienteId = 3 }, PedidoId = 4, Total = 10000.00 }, new Pedido { Cliente = new Cliente { ClienteId = 3 }, PedidoId = 5, Total = 3000.00 }, new Pedido { Cliente = new Cliente { ClienteId = 3 }, PedidoId = 6, Total = 4000.00 }, new Pedido { Cliente = new Cliente { ClienteId = 4 }, PedidoId = 7, Total = 7000.00 }, new Pedido { Cliente = new Cliente { ClienteId = 5 }, PedidoId = 8, Total = 9000.00 }, new Pedido { Cliente = new Cliente { ClienteId = 5 }, PedidoId = 8, Total = 11000.00 }, new Pedido { Cliente = new Cliente { ClienteId = 6 }, PedidoId = 8, Total = 100.00 }, new Pedido { Cliente = new Cliente { ClienteId = 6 }, PedidoId = 8, Total = 12000.00 }, new Pedido { Cliente = new Cliente { ClienteId = 2 }, PedidoId = 8, Total = 2000.00 } }; }}

Page 26: dotNET42-Final.pdf

26 .NET Magazine - LINQ - A revolução do .NET 3.0 Edição 42 - .NET Magazine 27

em querys SQL, como por exemplo, o relacionamento de dados entre tabelas distintas.

Usando classes como tabelasPra abusar dos recursos agora disponí-

veis no Framework foram implementadas duas classes que vamos utilizar como se fossem tabelas de banco de dados. A Listagem 5 mostra a implementação das classes Cliente e Pedido.

Agora que já temos duas supostas “tabelas” com clientes e com pedidos, vamos aprender a extrair a informação utilizando query expression. O código da Listagem 6 mostra como utilizar o join para recuperar os pedidos de cada cliente e seus valores:

O código não tem muitas novidades, a não ser o uso da cláusula join que possibilita que sejam relacionados os dados de duas cole-ções, desde que tenham algo em comum, nesse caso o identificador do cliente.

O código a seguir também não tem mui-tas novidades, além da cláusula join foi utilizada a let, para que fosse computado um dado específico:var pe = from c in clientes join p in pedidos on c.ClienteId equals p.Cliente.ClienteId into cp let x = cp.Count() select new { c.ClienteId, c.Nome, QtdPedidos = x };

A Figura 5 ilustra o resultado obtido após a execução da primeira query ex-pression.

A Figura 6 ilustra o resultado obtido após a execução da segunda query ex-pression.

Linq com XML (XLinq)Para utilizarmos os recursos da lingua-

gem LINQ na manipulação de arquivos XML, basta importar o namespace Sys-tem.XML.Linq. Os objetos disponíveis nesse namespace são muito similares aos objetos comumente utilizados para manipulação de arquivos XML.

A principal diferença pode ser vista na flexibilidade que os objetos fornecem ao seu consumidor, além é claro da sua nomenclatura que diferencia os objetos XLinq dos objetos XML.

Os objetos XLinq iniciam sempre com “X” seguidos pelo nome do objeto, por exemplo, XDocument. Já os objetos XML tradicionais são iniciados com “XML” se-

Listagem 6. Utilizando a cláusula Join

List<Pedido> pedidos = new Pedido().getPedidos();List<Cliente> clientes = new Cliente().getClientes();var pe = from p in pedidos join c in clientes on p.Cliente.ClienteId equals c.ClienteId select new { c.ClienteId, c.Nome, p.Total };

Listagem 7. Utilizando XLinq

XDocument doc = new XDocument(new XDeclaration(“1.0”, “ISO-8859-1”, null));var pe = from p in pedidos join c in clientes on p.Cliente.ClienteId equals c.ClienteId select new { c.ClienteId, c.Nome, p.PedidoId, p.Total };

var xdoc = new XDocument(new XDeclaration(“1.0”, “ISO-8859-1”, null), new XElement(“Clientes”, clientes.Select(f => new XElement(“Cliente”, new XAttribute(“Id”, f.ClienteId), new XAttribute(“Nome”, f.Nome), new XAttribute(“Cidade”, f.Cidade), new XAttribute(“Pais”, f.Pais), new XAttribute(“Telefone”, f.Telefone)))));Console.WriteLine(xdoc);

Figura 5. Resultado da query expression com join

Figura 6. Resultado da query expression com join e let

guidos pelo nome do objeto, por exemplo, XMLDocument.

O código da Listagem 7 ilustra mais claramente as mudanças mencionadas. Serão utilizadas como fonte de dados para nossos testes com a XLinq as mes-mas classes clientes e pedidos implemen-tadas neste artigo:

A Figura 7 ilustra o resultado do código proposto para criação de um arquivo XML com os dados de clientes.

Podemos notar que um recurso que está evidente no código anterior e foi implementado com sucesso nesse novo namespace para manipular arquivos XML foi a inicialização de objetos, isso traz a

Page 27: dotNET42-Final.pdf

26 .NET Magazine - LINQ - A revolução do .NET 3.0 Edição 42 - .NET Magazine 27

.NET 3.0

Listagem 8. Utilizando XLinq

var xdoc = new XDocument(new XDeclaration(“1.0”, “ISO-8859-1”, null), new XElement(“Clientes”, clientes.Select(f => new XElement(“Cliente”, new XAttribute(“Nome”, f.Nome), new XElement(“Pedidos”, pe.Select(p => new XElement(“Pedido”, new XAttribute(“IdCliente”, p.ClienteId), new XAttribute(“Id”, p.PedidoId), new XAttribute(“Valor”, p.Total))).Where(x => x.Attribute(“IdCliente”).Value == f.ClienteId.ToString()))))));Console.WriteLine(xdoc);

flexibilidade necessária para unir a mani-pulação de arquivos XML e a LINQ.

O código anterior cria um arquivo XML com todos os dados dos clientes de nossa fonte de dados. Um ponto importante nesse código é a forma descritiva e até óbvia do seu objetivo, o que facilita muito uma possível manutenção.

Agora eu vou complicar um pouco, vamos supor que será implamantado um sistema de gestão na sua empresa e o sistema precisa dos dados de clientes e seus respectivos pedidos, porém esses dados devem ser passados ao sistema em formato XML. O código da Listagem 8 traz uma possível solução para esse problema utilizando XLinq.

A Figura 8 ilustra o resultado do código proposto para criação de um arquivo XML com dados de clientes e seus res-pectivos pedidos.

ConclusãoEste artigo foi desenvolvido com a

intenção de levar ao leitor, de uma for-ma simples e objetiva, o conhecimento necessário para que o mesmo possa utilizar os recursos disponíveis a partir da versão 3.0 do Framework .NET, mais especificamente a LINQ.

As informaçoes contidas neste artigo são suficientes para que o leitor possa de forma sensata introduzir na sua ro-tina diária de trabalho, os conceitos da linguagem LINQ, buscando com isso aumentar a produtividade e facilitar o entendimento do código escrito, já que uma característica marcante da LINQ é a sua sintaxe declarativa e concisa.

Figura 7. Arquivo XML criado com a utilização de XLinq

Figura 8. Arquivo XML com dados dos clientes criado com a utilização de XLinq

Projeto LINQ

msdn2.microsoft.com/en-us/netframework/aa904594.aspx

Artigo de Anders Hejlsberg sobre a LINQ

msdn2.microsoft.com/en-us/library/aa479865.aspx

Download do Orcas

www.davidhayden.com/blog/dave/archive/2007/02/28/

VisualStudioOrcasMarch2007CTP.aspx

LINQ

w w w. m i c r o s o f t . c o m / d o w n l o a d s / d e t a i l s . a s p x ?

FamilyID=1e902c21-340c-4d13-9f04-70eb5e3dceea&

DisplayLang=en

Referências

Page 28: dotNET42-Final.pdf

28 .NET Magazine - Componentes de terceiros para ASP .NET Edição 42 - .NET Magazine 29

Componentes de terceiros para ASP.NET

Rodrigo Sendin([email protected])

é tecnólogo formado pela FATEC de Americana e MCP .NET. Trabalha com desenvolvimento de software há mais de 10 anos, escreve artigos para .NET Magazine, ClubeDelphi e WebMobi-le. Também desenvolve treinamentos em .net, e atualmente é desenvolvedor C# na TauNet Consulting.

Uma frase muito dita no meio do desenvolvimento de software é Não Reinventar a Roda. É uma

máxima que prega essencialmente a reutilização. Ou seja: Se alguém já fez isso e eu posso reutilizar, por que vou perder meu tempo fazendo de novo?

Neste artigo exploraremos alguns com-ponentes ASP.NET oferecidos por outras empresas (não Microsoft). Existem várias empresas que vendem (e até oferecem gratuitamente) componentes para ASP.NET. São componentes que obviamente realizam funções que não temos nos com-ponentes nativos da plataforma.

Não farei propaganda dessas empresas aqui. O objetivo é conhecer alguns com-ponentes que tratam de funcionalidades muito úteis para o nosso dia a dia. Vere-mos que muitas vezes compensa adquirir um componente de terceiro ao invés de investir tempo na criação de algo que já existe pronto.

E principalmente, demonstraremos o

que você deve avaliar antes de optar pela compra de um componente.

ASPNetVideoRecentemente escrevi um artigo sobre

a criação de uma aplicação Web para pu-blicação de vídeos, ao estilo do YouTube. Na ocasião foi descrito como exibir vídeos em páginas da Web. Não é uma tarefa difícil, mas e se já tivéssemos um compo-nente pronto, que já fizesse isso?

Existe um muito útil para realizar essa tarefa, é o ASPNetVideo. Mas antes de optar por comprar um componente de terceiro, é essencial que você possa testá-lo e a melhor forma de se fazer isso é através de uma versão trial.

O ASPNetVideo possui uma versão trial e você pode realizar o seu download no seguinte link: www.aspnet-video.com. Va-mos avaliar este componente? Faça o do-wnload para a versão 2.0 do ASP.NET, o arquivo se chama ASPNetVideoSetup2_0.zip. Descompacte-o e execute o arquivo

Page 29: dotNET42-Final.pdf

28 .NET Magazine - Componentes de terceiros para ASP .NET Edição 42 - .NET Magazine 29

asp.NET

de setup. É muito importante que o Visual Studio esteja fechado nesse momento.

Uma outra característica que você tem que observar sobre o componente, é se ele é fácil de instalar. Veja que o setup do ASPNetVideo é tranqüilo. Após o término da instalação abra o Visual Studio 2005 e crie um novo projeto ASP.NET.

Na ToolBox temos os controles disponí-veis. É essencial que a instalação dos com-ponentes já disponibilize os controles na ToolBox. Como mostra a Figura 1, temos uma nova seção chamada ASPNetVideo, e nela temos três novos componentes, chamados: QuickTime, WindowsMedia e RealPlayer.

É claro que cada um deles utilizará o software de cada um dos respectivos fabricantes. Vamos fazer um teste com o WindowsMedia. Arraste-o para a pá-gina Default.aspx. Todo componente de terceiro que se preza tem que permitir configurá-lo pela janela de propriedades, ou melhor ainda, tem que disponibilizar as principais configurações na Smart Tag do controle.

Do que adianta investirmos em um componente de terceiro se vamos ter trabalho com codificação? Esse é um dos pontos fundamentais que você precisa avaliar antes de decidir pela compra do componente.

Veja na Figura 2 as opções disponíveis na Smart Tag do controle WindowsMedia.

Podemos definir o tamanho que o vídeo ocupará na janela, podemos definir a propriedade AutoPlay, Loop Count etc. E principalmente, podemos definir aqui, qual é o vídeo que será exibido, claro.

Para o nosso exemplo estou mudando o tamanho do vídeo para Width = 450px e Height = 400px. Em seguida clique no

Figura 1. Componentes ASPNetVideo

Figura 2. Tasks do componente WindowsMedia no design da página

Figura 3. Selecionando um vídeo para teste

botão que temos na frente do campo Video URL, e veja como mostra a Figura 3, que podemos escolher um vídeo que esteja dentro do projeto Web.

Estou selecionando um vídeo de exem-plo e clicando em OK. Em seguida, salve compile e execute sua aplicação. Veja na Figura 4 que o vídeo é exibido no controle.

Veja que junto com o controle temos um link indicando que esta é uma versão trial. Note que foi muito simples a utiliza-ção do componente, e é assim que tem que ser. Um componente de terceiro precisa facilitar o trabalho e não complicar.

Faça o teste com os outros componentes de exibição de vídeos. Você verá que essa é uma ótima solução para a exibição de vídeos em suas aplicações Web.

FreeTextBoxVocê já teve a necessidade de criar um

componente para a edição de textos na Web? Sabe aquelas interfaces de Blogs, onde podemos escrever e formatar o texto que será publicado? O FreeTextBox é um controle que faz exatamente isso.

Acesse o link: www.freetextbox.com. Se você der uma olhada no site, principal-mente na seção que trata das licenças,

Page 30: dotNET42-Final.pdf

30 .NET Magazine - Componentes de terceiros para ASP .NET Edição 42 - .NET Magazine 31

você verá que um grande diferencial desse componente é que você tem uma licença que lhe dá direito a ter acesso aos fontes do componente. Dependendo da sua aplicação, isso pode ser fundamental, uma vez que você mesmo pode alterar o componente.

Vá à seção de downloads e faça o down-load da última versão. Até o fechamento deste artigo a última versão disponível era a 3.1.6, e o arquivo de download se chamava FTBv3-1-6.zip. Descompacte o arquivo e você notará que não existe um setup para o componente. O que temos aqui é a FreeTextBox.dll disponível na pasta ~/FTBv3-1-6\Framework-2.0.

Copie essa DLL para a pasta bin de um projeto ASP.NET 2.0, que pode inclusive ser o mesmo que fizemos anteriormente. Abra o projeto no Visual Studio 2005 e vá na ToolBox. Como não temos um setup, teremos que incluir o controle na ToolBox. Clique com o botão direito em uma área vazia da ToolBox, escolha a opção Add Tab e informe “FreeTextBox” no nome desta nova Tab.

Em seguida clique com o botão direito dentro da nova Tab e escolha a opção Choose Items. Clique em Browse e aponte para a DLL que copiamos para a pasta bin. Veja como mostra a Figura 5, que o componente já é selecionado. Clique em OK e veja agora na Figura 6 que o controle aparece na ToolBox.

Em uma página vazia arraste o FreeTex-tBox. No design não temos muito o que mexer. Talvez algumas formações de layout nas propriedades, mas nada que venha ao caso no momento. Após incluir o controle na página, simplesmente salve, compile e execute o seu projeto.

Veja na Figura 7 que o FreeTextBox dispo-nibiliza uma interface muito parecida com

Figura 4. Testando o controle WindowsMedia

Figura 5. Incluindo o FreeTextBox na ToolBox Figura 6. Componente FreeTextBox na ToolBox

Page 31: dotNET42-Final.pdf

30 .NET Magazine - Componentes de terceiros para ASP .NET Edição 42 - .NET Magazine 31

asp.NET

Figura 7. Testando o componente FreeTextBox

a do Word, para a formatação de textos.Veja que você pode formatar o tipo da

fonte, trocar o tamanho, cor, parágrafo, incluir figuras etc. Enfim, é um ótimo editor de texto para a Web. O resultado dessa formatação é um código HTML, que você pode conferir na aba HTML na parte inferior do controle.

E para utilizar esse código HTML ge-rado pelo controle, basta acessar a pro-priedade Text do mesmo. Assim, em uma aplicação como um Blog, esse controle é muito útil. Imagine criar todas essas funcionalidades do zero?

Nota: ao inserir texto HTML como en-

trada de dados, lembre-se de configurar

o atributo ValidateRequest da página

para False.

DevExpress: ASPxGridAquele que nunca utilizou um Grid

de terceiro que atire o primeiro mouse! Esse sem dúvida é o tipo de componente mais utilizado. Ainda que o GridView do ASP.NET 2.0 seja muito bom, e atenda a maior parte das necessidades de um Grid, sempre haverá uma funcionalidade que não conseguiremos com ele.

São várias as empresas que disponi-bilizam Grids, eu vou demonstrar aqui o Grid da DevExpress (www.devexpress.com). Na seção de downloads desse site, você consegue baixar uma versão trial, do pacote de controles da DevExpress.

E que pacote! Não é só o Grid que você vai encontrar, é conjunto com diversos componentes para ASP.NET e Windows Forms. A dica é dar uma olhada no Demo que é instalado junto com o produto. A partir dela você pode ter uma idéia geral do que faz cada um dos controles.

Você pode utilizar o FreeTextBox com banco de dados através

de DataBind. Por exemplo, em controles como o DetailsView

ou GridView, basta usar colunas templates para servirem de

container ao controle, e então vinculá-lo a uma coluna do

respectivo DataSource.

Banco de Dados com o FreeTextBox

A Microsoft disponibiliza o download do Database

Northwind para SQLServer, neste link:

www.microsoft.com/downloads/details.aspx?FamilyID=

0 6 6 1 6 2 1 2 - 0 3 5 6 - 4 6 A 0 - 8 D A 2 - E E B C 5 3 A 6 8 0 3 4 &

displaylang=en

Se você utiliza o SQLServer 2000, o Northwind já vem instalado.

Onde encontrar o Database Northwind?

Acesse agora o mesmo o Portal .net Plus e assista a uma vídeo aula

de Fabio Galante, que mostra como trabalhar com o FreeTextBox em

aplicações ASP.NET.

www.devmedia.com.br/articles/viewcomp.asp?comp=3327

www.devmedia.com.br/msdn/portal.asp

Outro diferencial que eu achei muito interessante nesse pacote é a documen-tação. Mesmo na versão trial, você tem uma opção chamada Documentation, que traz uma enorme base de conhecimento sobre os componentes.

É óbvio que eu não conseguiria de-monstrar todos os componentes do pa-cote aqui, por isso vamos apenas fazer um exemplo com o Grid, que se chama ASPxGrid. Depois de fazer o download e instalar o produto, crie um novo WebSite no Visual Studio 2005.

Em seguida, com a página Default.aspx aberta vá na ToolBox (Figura 8). Veja que temos duas seções só de componentes da DevExpress. São 43 componentes disponíveis na ToolBox. Além do Grid, temos componentes para Tabs, Menus, PivotTables, Relatórios, Gráficos, e mais uma infinidade de soluções disponíveis para ASP.NET.

Quando você for avaliar um Grid, veja quais são os tipos de DataSources que ele aceita. Eu por exemplo trabalho muito com DataSets Tipados e TableAdapters, se o Grid não for compatível com esse tipo de DataSource, para mim não funciona.

Vamos então ver se o ASPxGrid é com-patível com os DataSets e TableAdapters do ADO.NET. Clique com o botão direito sobre o projeto no Solution Explorer e escolha a opção Add New Item. Escolha o item DataSet, mude o seu nome para “Northwind.xsd” e clique em Add.

Aparecerá uma mensagem perguntan-do sobre a criação da pasta App_Code, confirme clicando em Yes. Em seguida, crie uma conexão com o Northwind no Server Explorer (ou qualquer banco de sua escolha).

Arraste a tabela Customers para o Design Surface do DataSet. Seu DataSet deverá se parecer como o da Figura 9.

Page 32: dotNET42-Final.pdf

32 .NET Magazine - Componentes de terceiros para ASP .NET Edição 42 - .NET Magazine 33

Figura 8. Componentes da DevExpress na ToolBox

Figura 9. DataSet Northwind com DataTable Customers

Salve e faça um Build do seu projeto. Em seguida vá até a página Default.aspx e arraste um ObjectDataSource da Tool-Box para o design da página. Na Smart Tag do ObjectDataSource clique na opção Configure Data Source. Em Business Object, selecione o NorthwindTableAdapters.Cus-tomersTableAdapter, e clique em Next. Em seguida clique em Finish.

Abaixo do ObjectDataSource, arraste o ASPxGrid que você encontra na seção Developer Express: Web.Grid v7.1. E como mostra a Figura 10, em Choose Data Source, aponte para o ObjectDataSource1.

Nesse momento você pode ver que as colunas do Grid já estão apresentando os atributos da tabela Customers. Isso indica que o ASPxGrid é compatível com os Da-taSets do ADO.NET. Mas você também pode ver que esse Grid é compatível com outros DataSources, como acesso direto ao SQL Server, Access, XML e outros.

Se você quiser já pode executar o projeto e verá que o Grid já está funcionando. Porém, antes de fazermos isso, vamos

Figura 10. Escolhendo o DataSource do ASPxGrid

explorar algumas opções que o ASPxGrid oferece. Veja que na Smart Tag do controle temos uma opção chamada Designer, clique nela.

Já deu pra ver no lado esquerdo desta janela a quantidade de opções que temos para configurar o Grid. Obviamente não conseguiremos ver todas, mas vamos às mais interessantes. Clique na opção Columns do menu lateral. Veja que aqui podemos definir e configurar as colunas

que aparecerão no Grid. Por padrão o Grid está com o Auto Gene-

rate Columns ligado, e por isso nenhuma coluna aparece aqui para configuração. Mas temos um botão muito interessante chamado Retrieve Columns, clique nele. Veja, como mostra a Figura 11 que todas as colunas da tabela aparecerão aqui.

Observe que para cada coluna podemos configurar uma enorme quantidade de propriedades. Uma propriedade que eu

Page 33: dotNET42-Final.pdf

32 .NET Magazine - Componentes de terceiros para ASP .NET Edição 42 - .NET Magazine 33

asp.NET

Figura 11. Configurando as colunas do Grid Figura 12. Opções da propriedade EditorType

Page 34: dotNET42-Final.pdf

34 .NET Magazine - Componentes de terceiros para ASP .NET Edição 42 - .NET Magazine 35

Figura 14. Exemplo de utilização do Search, na coluna CompanyName

achei muito interessante está na seção Editors, é a Editor Type. Veja na Figura 12, que através dessa propriedade você pode escolher um controle diferente para a edição do campo, como por exemplo: DropDownList, Image, ListBox e até contro-les especiais do pacote DevExpress como DateEdit, Lookup e SpinEdit.

Clique agora na opção AutoFormat que está na seção View Settings do menu lateral. Veja que você tem uma enorme quantidade de opções de formatação de layout. Vamos escolher Office2003 Blue, que lembra o padrão do Office 2003.

De novo no menu lateral, clique na opção Search que está na seção Functionality. Aqui podemos habilitar a função de pesquisa nas colunas do Grid. Como nos mostra a Figura 13, marque a opção Enable Search, que por padrão vem desabilitada.

Já é o suficiente para podermos testar algumas funcionalidades do Grid. Clique em OK, salve, compile e execute o seu projeto. A primeira coisa que você pode observar é a interatividade que você tem com as colunas e linhas do Grid.

Veja que você consegue ordenar de forma crescente ou decrescente qualquer uma das colunas. Você também pode alterar o tamanho das colunas, apenas clicando nas linhas de divisão e arrastan-do. Também pode mudar as colunas de posição no Grid, clicando e arrastando o seu cabeçalho.

Por padrão, você também pode selecionar as linhas do Grid (sem postback), e mudar essa seleção com a utilização das teclas do teclado. Se desejar, pelo Designer do Grid você também pode configurar múltipla se-leção de linhas ou até seleção de células.

Veja como mostra a Figura 14, que para cada coluna temos uma opção de Search. Basta digitar o começo da palavra que queremos pesquisar e clicar na lupa.

Acesse agora o mesmo o Portal .net Plus e assista a uma vídeo aula de

Luciano Pimenta, que mostra uma série de aulas sobre o componentes

DevExpress.

www.devmedia.com.br/articles/listcomp.asp?txtsearch=DevExpress

www.devmedia.com.br/msdn/portal.asp

Figura 13. Habilitando o Search no Grid

Page 35: dotNET42-Final.pdf

34 .NET Magazine - Componentes de terceiros para ASP .NET Edição 42 - .NET Magazine 35

asp.NET

Figura 15. Exemplo de agrupamento no Grid

As opções de Search também podem ser configuradas no Designer.

E a minha funcionalidade preferida, o agrupamento. Clique no cabeçalho da coluna Country e arraste-a para a área superior do Grid, onde está escrito Drag a column header here to group by that column. Veja que os registros foram agrupados pela coluna escolhida (Figura 15).

Essa, sem dúvida, é uma funcionalidade muito interessante, e que ajuda muito o usuário final. Você pode agrupar o Grid por qualquer uma das colunas e ainda realizar agrupamentos múltiplos. O que eu pude observar quando testei esse Grid e os outros componentes da DevExpress é a quantidade de configurações que temos disponíveis.

Isso é um grande diferencial, pois permite personalizar o componente da forma que precisamos, tornando-o bem portável para as nossas aplicações.

ConclusãoComo você pôde ver o mercado está

cheio de soluções de terceiros quando o assunto é componentes do ASP.NET. Vimos neste artigo, apenas três exemplos do que você encontra por aí. Tudo vai depender da sua necessidade e do quanto você pode investir. Alguns componentes são mais caros, mas em contrapartida vão lhe trazer maior produtividade.

Outro ponto muito importante que você

tem que avaliar é verificar qual é o com-prometimento que a empresa tem com a evolução da tecnologia. Ou seja, quando sair outra versão do .NET, sairá outra versão dos componentes? Tente conhecer outras empresas que usam o componente que você quer comprar, ouça a opinião delas. Procure em fóruns e comunidades

alguma referência do componente. Tome cuidado com componentes gratui-

tos, podem ser um problema, principal-mente se não vierem acompanhados do código-fonte. E tenha sempre em mente que os componentes têm que ajudar no seu dia a dia e não atrapalhar.

Grande abraço e até a próxima!

Page 36: dotNET42-Final.pdf

36 .NET Magazine - Preenchendo formulários Web programaticamente Edição 42 - .NET Magazine 37

Preenchendo formulários Web programaticamente

Guinther Pauli([email protected])

Atua no ramo de tecnologia e programação há mais de 17 anos, é autor de mais de 100 ar-tigos publicados e 200 vídeo-aulas e do livro “Delphi – Programação para Banco de Dados e Web”. Trabalha com .NET desde a versão beta. É Bacharel em Sistemas de Informação, desen-volvedor 5 estrelas Microsoft, Microsoft Certi-fied: MCP, MCAD, MCSD.NET, Borland Certified: Delphi 6, 7, 2005, 2006, Web e Kylix. Editor Ge-ral das Revistas .net Magazine, ClubeDelphi, WebMobile (.NET) e Mr.Bool.

O uso de arquivos texto (TXT) foi, ou provavelmente ainda é, uma das formas mais conhecidas e

utilizadas para comunicar diferentes tipos de aplicação. Imagine um cenário, por exemplo uma empresa A usando um sistema em .NET, que precisa enviar informações sobre parcelas geradas para um sistema B legado, escrito em Clipper ou Cobol. O uso de TXT é inevitável.

Mas um personagem estava para sur-gir e mudar esse cenário. Se o leitor já está pensando no termo XML, acertou. Podemos dizer que o XML estende o formato TXT, já que também é expresso em forma textual, porém tem duas gran-des diferenças: 1) Expõe seus dados em um formato mais lógico e hierárquico; 2) Existem inúmeros parsers prontos para processar arquivos XML.

A tendência é que a comunicação entre sistemas heterogêneos seja feita através de XML, já que esse é um formato ampla-mente aceito e padronizado. E quando se

fala em comunicar aplicativos via XML de forma on-line, então entra outra nova (e nem tão nova assim) e importante tec-nologia: Web Services (chamado a partir daqui simplesmente de WS).

Por exemplo, imagine um cenário onde construímos um sistema para uma agên-cia de turismo. Poderíamos integrar em nosso WebSite uma consulta on-line via WS aos sites das companhias áreas que oferecem as passagens mais baratas para o horário desejado pelo cliente.

Ao invés de entrarmos site por site de cada companhia, nosso sistema faz isso automaticamente via WS (ou usando a técnica que veremos neste artigo). E poderia integrar com outro WS para já disponibilizar ao cliente um hotel próximo ao local de chegada que tenha disponibilidade para um horário X. Tudo automático!

Seria uma maravilha se tudo o que precisássemos integrar em nosso sistema pudesse ser obtido através da comunica-

Page 37: dotNET42-Final.pdf

36 .NET Magazine - Preenchendo formulários Web programaticamente Edição 42 - .NET Magazine 37

Boa idÉia

ção via WS. É bem mais simples receber dados em XML e processá-los com um parser (através das classes do .NET).

Mas a realidade mostra um cenário totalmente diferente. Quase tudo o que vemos é baseado em HTML (browser) e não XML, o que significa que para usar determinado serviço de outra empresa, você precisa abrir um browser, preencher informações e consultar. Isso dá um fim ao processo que precisaria ser feito de forma automática. Ou pelo menos deve-ria, até você ler este artigo.

Quando usamos um browser para utili-zar um serviço de uma empresa, estamos usando o que chamamos de intercâmbio B2C (Businness to Consumer - pt.wikipedia.org/wiki/B2C). O usuário final é responsá-vel por obter a informação de um browser que recebe HTML.

Quando a comunicação é feita de forma automática por um sistema via WS e XML, e o usuário final acessa o serviço via nossa aplicação e não diretamente o serviço, dizemos que a comunicação é feita através de B2B (Businness to Business - pt.wikipedia.org/wiki/B2B).

Por exemplo, se você acessa o site da De-vMedia para comprar edições de revistas anteriores que por ventura não tenha em sua coleção, está usando o B2C. Se está, por exemplo, usando o WS dos Correios (veja edição 36) para exibir dados de endereço do cliente em seu sistema, está usando B2B.

Mas onde quero chegar com toda essa introdução? O fato é que precisamos cada vez mais construir aplicações B2B para agregar funcionalidades as nossas apli-cações, porém, infelizmente, a maioria das coisas que encontramos hoje na Web não são disponibilizadas na forma de WS (B2B), mas somente para usuários finais através de um browser HTML (B2C).

O que nos resta é criar um mecanismo para usar serviços B2C como se fossem B2B.

Criando solicitações HTTPA solução apresentada neste artigo

consiste em fazer via código o que um usuário faria normalmente via Web Bro-wser. Ou seja, podemos usar em nossas aplicações serviços disponibilizados não como WS, mas em forma de Web Sites. Como os dados trafegam sobre o HTTP

em formato HTML, e não XML, é preciso realizar um trabalho extra e “braçal”.

Imagine um usuário preenchendo um cadastro em um Web Site, onde ele infor-ma os campos em um formulário e clica em um botão Gravar. Considere que você precisa transferir todos os registros da sua base de clientes para esse Web Site.

O que fazemos é, para cada registro, preencher os dados do formulário pro-gramaticamente e emitir um comando ao Web Site para clicar no botão Gravar. Ou seja, estamos fazendo tudo via código.

Estamos simulando o papel de um browser, criando uma requisição HTTP no braço (através da classe WebRequest do .NET, do namespace System.Net) e obtendo o valor de retorno. Aplicações desse tipo também são conhecidas como robots.

Como o valor de retorno é HTML, e não XML, normalmente o tráfego de dados será bem mais intenso, visto que em HTML trafegam não somente dados, mas informações de layout, banners, figuras, que normalmente não são necessárias em uma aplicação B2B. Além disso, é preciso fazer o parse manual do arquivo HTML de retorno, procurando linha a linha (ou tag a tag) por um valor desejado.

Os exemplos demonstrados neste artigo são bastante interessantes e vão deixar mais clara a idéia aqui proposta, que se usada com sabedoria, poderá agregar um valor muito grande as suas aplicações Web ou mesmo Desktop.

As aplicações aqui construídas serão do tipo Windows Forms, mas podem fa-cilmente serem feitas utilizando-se ASP.NET Web Forms, caso queira.

Nota: Como aplicações Web são total-

mente dinâmicas, e pelo fato dos exem-

plos fazerem parse manual do código

HTML, é possível que deixem de funcio-

nar caso o fornecedor do serviço modi-

fique por algum motivo o seu layout ou

simplesmente o endereço da página.

No entanto, no endereço para downlo-

ad deste artigo, você sempre encontra-

rá versões atualizadas e funcionais para

os exemplos aqui apresentados.

Obtendo dados da Web via código Neste primeiro exemplo, veremos

como obter (GET) os dados vindos de uma página. Esse é um aplicativo mais simples, pois não será necessário pas-sar nenhum parâmetro em forma de campo para o servidor. Como exemplo, vamos obter a cotação on-line do dólar, disponível na página br.invertia.com do site Terra.

Em uma nova aplicação Windows Forms, desenhe o formulário mostrado na Figura 1. Nele temos um Button, um TextBox chamado “tbResponse” e um Label (“lbResultado”).

O lbResultado vai exibir a cotação atual do dólar obtida a partir do site. O TextBox não tem funcionalidade para o usuário final, ele apenas ajudará a visualizar o conteúdo de retorno (Response) retorna-do do servidor Web. No Click do botão apenas chamamos o método DoRequest (Listagem 1).

Os códigos estão todos comentados para um melhor entendimento. Veja que estamos criando uma requisição HTTP no braço, como se fosse o usuário aces-

Não é o objetivo deste artigo demonstrar exemplos para

uso ilícito da tecnologia, como fazer mau uso de serviços

oferecidos por empresas, sobrecarregar servidores - D.O.S,

preencher cadastros com dados falsos, burlar votações on-

line, fazer spam automático etc.

O objetivo único e principal aqui é mostrar como você

pode integrar suas aplicações com Web Sites que forneçam

serviços úteis.

Advertência

Figura 1. Formulário para exibir o valor do dólar

Page 38: dotNET42-Final.pdf

38 .NET Magazine - Preenchendo formulários Web programaticamente Edição 42 - .NET Magazine 39

Listagem 1. Criando uma requisição HTTP no braço

using System.Net;using System.IO;...private void DoRequest(){ //cria uma requisição para a URL WebRequest rq = WebRequest.Create(“http://br.invertia.com/mercados/divisas”); //obtém a resposta HttpWebResponse rp = (HttpWebResponse)rq.GetResponse(); //obtém um stream contendo a resposta retornada pelo servidor Stream ds = rp.GetResponseStream(); //cria um StreamReader para leitura StreamReader rd = new StreamReader(ds); //lê o conteúdo string ct = rd.ReadToEnd(); //atribui o resultado ao textBox tbResponse.Text = ct; //fecha os objetos rd.Close(); ds.Close(); rp.Close(); //exibe o resultado lbResultado.Text = “R$ “ + ExtractDolar(ct);}

Listagem 2. Extraindo o dólar do Response

private string ExtractDolar(string text){ //procura por indexador fixo int i = text.LastIndexOf(“DOLCM”); //incrementa deslocamento i += 16; //captura o texto return text.Substring(i, 6);}

sando a página. Isso é feito através da classe WebRequest.

Note que, contrariando o padrão do .NET, criamos um objeto WebRequest com o método Create e não com o operador new do C#. A seguir, fazemos um GET para obter o valor de retorno para a página passada como parâmetro no Create do WebRequest.

O valor do Response (variável rp), que é a resposta / retorno, nada mais é que a própria página HTML que seria enviada a um browser. Para fazer a leitura desse Response, precisamos de um StreamReader, que obterá o conteúdo do Response e guar-dará na variável ct (o Content). A seguir fechamos os objetos utilizados.

Após a requisição, exibimos o valor do conteúdo retornado no TextBox, que é o código HTML. O próximo passo é buscar no HTML puro o que estamos procurando, um processo bastante braçal já que estamos trabalhando com HTML e não XML.

O código da função ExtractDolar obtém o valor do dólar a partir do HTML de retorno. A técnica é simples, procuramos por algo fixo no HTML e a posição rela-tiva do que buscamos comparado a esse valor fixo. Esse é um procedimento que você deve fazer examinando o HTML retornado.

Nesse caso, o valor do dólar está 16 posições após o elemento DOLCM e tem tamanho 6. Não fique apavorado com o nível do “hard-coded”, essa é uma das formas mais utilizadas para fazer o parse em um HTML (ou o DOM, dependendo do formato HTML). A função é mostrada na Listagem 2.

Executando a aplicação (não esqueça de colocar a chamada a DoRequest no botão), já podemos ver a cotação on-line do dólar (Figura 2).

Nota: Mesmo que exista na Web um

site que disponibilize os serviços aqui

demonstrados via WS, não é o objetivo

deste artigo usar esse mecanismo.

Preenchendo formulários automaticamente

Uma variação deste primeiro exemplo é obter dados da Web onde há a necessi-dade de primeiramente se preencher um

Figura 2. Cotação do dólar obtida on-line

formulário. O valor de retorno é variável, e depende do que o usuário informou no formulário.

Como exemplo, vamos usar o serviço de tradução disponibilizado pelo site Google, disponível em www.google.com.br/language_tools. Novamente, não importa aqui se existe um WS para obter o mesmo resultado, o que quero mostrar é como preencher forms automaticamente e fazer o parse do valor de retorno.

Em uma nova aplicação Windows Forms, desenhe o formulário mostrado na Figura 3. Nele temos um Button, dois TextBoxes chamados “tbTexto” e “tbRes-ponse”, um Label (“lbResultado”) e um ComboBox (“cmbTraduzir”), além dos Labels apenas para indicarem a função de cada controle.

O usuário vai digitar no primeiro TextBox o valor que deseja traduzir, no ComboBox ele escolhe se deseja traduzir de “Português->Inglês” ou “Inglês->Português” (coloque esses valores na sua propriedade Items) e no Label de re-sultado mostramos o valor da tradução, após o clique no botão.

Não vamos neste exemplo exibir o HTML, caso queira, faça como no primei-ro exemplo. O botão chama o DoRequest (Listagem 3).

Figura 3. Formulário para tradução on-line

O final do código é o mesmo do pri-meiro exemplo, de forma que vou me deter na explicação da primeira parte da listagem. Tudo está comentado, para um fácil entendimento.

Após configurar o Request, testamos o valor escolhido para tradução no ComboBox. A seguir, no objeto WebRequest, configura-mos seu método (Method) para POST, pois vamos postar dados em um formulário.

Page 39: dotNET42-Final.pdf

38 .NET Magazine - Preenchendo formulários Web programaticamente Edição 42 - .NET Magazine 39

Boa idÉia

Listagem 3. Processando a requisição de tradução

using System.Net;using System.IO;...private void DoRequest(){ //cria uma requisição para a URL WebRequest rq = WebRequest.Create(“http://translate.google.com/translate_t”); //verifica a seleção do usuário para a tradução string Conversao; if (cmbTraduzir.SelectedIndex == 0) Conversao = “pt|en”; else Conversao = “en|pt”; //preenche os campos do post string fields = “text=” + tbTexto.Text + “&langpair=” + Conversao; //vamos dar um POST ao invés de GET rq.Method = “POST”; //coloca os campos em um array de bytes byte[] bytes = Encoding.ASCII.GetBytes(fields); //configura o tamanho do content do request rq.ContentLength = bytes.Length; //obtém um stream usado para o request Stream st = rq.GetRequestStream(); //escreve no stream os campos e fecha st.Write(bytes, 0, bytes.Length); st.Close(); //obtém o response a partir do request HttpWebResponse rp = (HttpWebResponse)rq.GetResponse(); //obtém um stream contendo a resposta retornada pelo servidor Stream ds = rp.GetResponseStream(); //cria um StreamReader para leitura StreamReader rd = new StreamReader(ds); //Faz a leitura string responseFromServer = rd.ReadToEnd(); //fecha os objetos rd.Close(); ds.Close(); rp.Close(); //exibe o resultado lbResultado.Text = ExtractTranslation(responseFromServer);}

Listagem 4. Código do ExtractTranslation

private string ExtractTranslation(string text){// procura por indexador fixo int i = text.LastIndexOf(“id=result_box”); // incrementa deslocamento i += 22; // captura o texto int j = text.LastIndexOf(“</div></td>”); return text.Substring(i, j-i);}

Ainda no WebRequest, precisamos en-viar os respectivos Fields, que nada mais são que os campos do formulário. No caso da tradução do Google, é o campo que indica o tipo de tradução a ser feita e o texto a ser traduzido. Note que para isso usamos um array de bytes e passamos como parâmetro para o Write do objeto Stream.

O método ExtractTranslation extrai o conteúdo da tradução a partir da string de retorno, e é mostrado na Listagem 4. O resultado da aplicação em execução é mostrado na Figura 4.

Você pode facilmente adaptar este exemplo para outros tipos de formulários que tenham campos diferentes. Nesse caso, precisará apenas identificar, além da URL de postagem, que campos o form precisa receber como parâmetro.

Isso pode ser obtido verificando-se o código-fonte da página HTML, veja, por exemplo, na Figura 5 como obtivemos acesso aos campos do formulário de tradução.

Observe pela Figura 5 que podemos ob-ter os detalhes do form, como a URL onde precisamos dar o POST. Note também que os campos ficam dentro do elemente form, uma boa dica para você procurar no extenso HTML quais os campos precisa fornecer, que nesse caso são dois, chama-dos de text e langpair.

TemperaturaQue tal exibir ao usuário as informações

atualizadas sobre o tempo, na cidade onde ele mora. É o que vamos fazer neste último exemplo, um pouco semelhante ao anterior. Dos diversos sites que dis-ponibilizam informações sobre o tempo em cidades brasileiras, o que escolhi para esta aplicação foi o br.weather.com (Figura 6).

O primeiro passo para obtermos os serviços do site é preenchermos seu form e examinarmos os códigos HTML de envio e de retorno. O que nos interes-sa obter está circulado na Figura 6. As informações que precisamos passar ao servidor estão no outro círculo, nesse caso, um único campo que é o nome da cidade que você deseja obter informações sobre o tempo.

Examinando o código HTML da página, o primeiro passo é procurar pela tag form,

Figura 4. Google dando uma mão na tradução

Figura 5. Detalhes do formulário

Page 40: dotNET42-Final.pdf

40 .NET Magazine - Preenchendo formulários Web programaticamente Edição 42 - .NET Magazine 41

Figura 6. Site br.weather.com

é ela que indica os campos que devem ser postados. Nesse caso, encontramos os campos da Figura 7, um chamado Text e outro oculto (hidden).

É importante também detectar em que local devemos postar os dados, nesse caso consultamos o atributo Action do elemento form.

Nota: Se a página possuir múltiplos ele-

mentos forms, tenha o cuidado de es-

colher aquele que posta os dados que

realmente deseja enviar, claro.

Estudado o comportamento da página, passamos para aplicação. Ela é semelhan-te as demais que criamos, de forma que não vou entrar em todos os detalhes do design do form. Você pode facilmente construí-lo baseando-se na Figura 8.

Os componentes que vão ser referen-ciados no código tiveram seus nomes padrão modificados, como mostra a figura. Além disso, bem abaixo do form, temos um PictureBox. O botão chama o método DoRequest, que pode ser visto na Listagem 5.

O código é praticamente igual ao do exemplo anterior, mudando somente o nome dos campos que precisamos enviar ao servidor. No final, exibimos as infor-mações nos Labels, sendo elas: a tempera-tura e uma descrição do tempo.

Os métodos usados no final do código, que fazem o parse do HTML de retorno e obtêm as informações desejadas, podem ser vistos na Listagem 6.

Um método aqui merece especial aten-ção, o ExtractImage. O site em questão devolve um pequeno ícone indicando as condições do tempo na cidade pesquisa-da (tempo bom, nublado, chuva etc.).

O que obtemos como retorno é a URL para a imagem. Se estivéssemos usando ASP.NET para criar nossa aplicação, e quiséssemos exibir essa imagem, bastaria passar essa URL para um Image.

Porém estamos usando Windows Forms, e precisamos fazer uma nova requisição somente para pegar a imagem (o HTML não permite embutir imagens no código), então precisamos de um novo método.

É o que faz o ConfigPictureBox (Listagem 7). Basicamente criamos um Request e guardamos o retorno em um Response,

Figura 7. Estudando o comportamento da página

Listagem 5. Consultando o tempo

using System.Net;using System.IO;...private void DoRequest(){ //cria uma requisição para a URL WebRequest rq = WebRequest.Create(“http://br.weather.com/search/search/”); //preenche os campos do post string fields = “where=” + tbTexto.Text + “&what=”; //configura o ContentType rq.ContentType = “application/x-www-form-urlencoded”; //vamos dar um POST ao invés de GET rq.Method = “POST”; //coloca os campos em um array de bytes byte[] bytes = Encoding.ASCII.GetBytes(fields); //configura o tamanho do content do request rq.ContentLength = bytes.Length; //obtém um stream usado para o request Stream st = rq.GetRequestStream(); //escreve no stream os campos e fecha st.Write(bytes, 0, bytes.Length); st.Close(); //obtém o response a partir do request HttpWebResponse rp = (HttpWebResponse)rq.GetResponse(); //obtém um stream contendo a resposta //retornada pelo servidor Stream ds = rp.GetResponseStream(); //cria um StreamReader para leitura StreamReader rd = new StreamReader(ds); //lê os dados string responseFromServer = rd.ReadToEnd(); //fecha os objetos rd.Close(); ds.Close(); rp.Close(); //exibe os resultados lblTemperatura.Text = ExtractTemperatura(responseFromServer); lblStatus.Text = ExtractStatus(responseFromServer); string URLImagem = ExtractImage(responseFromServer); ConfigPictureBox(URLImagem);}

Page 41: dotNET42-Final.pdf

40 .NET Magazine - Preenchendo formulários Web programaticamente Edição 42 - .NET Magazine 41

Boa idÉia

Figura 8. Form para obter informações sobre o tempo

que é a imagem. Usando um FileStream, salvamos a imagem no disco.

A aplicação final em execução é mostra-da na Figura 9.

ConclusãoAgora você já pode integrar sua aplica-

ção com os mais variados tipos de Web Si-tes, basta usar a imaginação. Por exemplo, por aqui já criamos um aplicativo que se comunica com o Orkut, enviando scraps e obtendo informações sobre contatos.

Também uma aplicação que a partir dos dados do cliente, exibe um mapa com a lo-calização exata da quadra, rua e número. Colocamos esse último disponível para download. Tudo usando preenchimento programático de formulários.

É bem provável que alguns dos serviços aqui demonstrados estejam disponíveis via WebServices, mas conforme comen-tei, o objetivo e propósito deste artigo foi considerar esses sites como modelos, como objetivo de estudo, para que agora você possa criar seus próprios aplicativos que consomem serviços baseados em Web Sites. Quem sabe até mesmo a idéia exposta na introdução deste artigo.

Bom, eu não tenho dúvida que preci-saria de um outro artigo – ou talvez a revista inteira, sem exagerar – só para listar a imensidão de possibilidades do que pode ser feito com o que foi demons-trado nestes exemplos. Toda a Web está nas mãos do seu código.

Agora use a imaginação, expresse-a no código e veja os resultados. Bom proveito e até a próxima!

Listagem 6. Métodos para o parse das informações

private string ExtractTemperatura(string text){ //procura por indexador fixo int i = text.IndexOf(“obsTempText”); //incrementa deslocamento i += 32; //captura o texto return text.Substring(i,2) + “ºC”;}

private string ExtractStatus(string text){ //procura por indexador fixo int i = text.IndexOf(“obsText”); //incrementa deslocamento i += 9; //captura o texto string Status = string.Empty; while (!(text[i].ToString() == “<”)) { Status += text[i]; i += 1; } return Status;}

private string ExtractImage(string text){ //procura por indexador fixo string URL = “http://image.weather.com/web/common/intlwxicons/52/”; int i = text.IndexOf(URL) + URL.Length; //captura a URL while (!(text[i].ToString() == “.”)) { URL += text[i]; i += 1; } return URL + “.gif”; }

Listagem 7. Método ConfigPictureBox

private void ConfigPictureBox(string URL){ //cria uma requisição para a imagem WebRequest rq = WebRequest.Create(URL); //cria um response HttpWebResponse rp = (HttpWebResponse)rq.GetResponse(); //cria um stream a partir do response (imagem) Stream ds = rp.GetResponseStream(); //cria um filestream para gravar a imagem no disco FileStream fs = new FileStream(“Img.gif”, FileMode.Create); //aloca um buffer byte[] buffer = new byte[512]; int byteCount; do { //escreve no buffer e salva byteCount = ds.Read(buffer, 0, 512); fs.Write(buffer, 0, byteCount); } while (byteCount > 0); //fecha objetos fs.Close(); ds.Close(); rp.Close(); //carrega a figura pictureBox1.Load(“Img.gif”);}

Figura 9. Frio e tempo bom em Porto Alegre

Page 42: dotNET42-Final.pdf

42 .NET Magazine - Criando Templates e StarterKit de projetos Edição 42 - .NET Magazine 43

Criando Templates e StarterKit de projetos

Thiago Miranda([email protected])

é Bacharel em Sistemas de Informação pelo Centro Universitário do Leste de Minas Ge-rais - UnilesteMG. Atualmente trabalha como Analista de Sistemas na Cientec - Consultoria e Desenvolvimento de Sistemas. Possui 4 anos de experência na área.

Os desenvolvedores de software deparam-se frequentemente com o termo “produtividade”.

A maioria das empresas, objetivando sa-tisfazer bem seus clientes, busca agilizar o desenvolvimento reduzindo sempre que possível o tempo de produção, sem perder é claro a qualidade.

Diante desse cenário, venho demonstrar como podemos criar nossos próprios templates e StarterKits de projetos, usando o Visual Studio 2005, favorecendo a rapi-dez, no que tange o desenvolvimento de novas soluções. Antes de começar nosso exemplo, vou descrever os conceitos sobre os objetos de trabalho que apren-deremos neste artigo.

O que são Templates e Starterkits?Bom, quando selecionamos um novo

projeto no Visual Studio, seja ele Win-dows ou Web, estamos na verdade esco-lhendo um template de projeto. Ele contém informações básicas de um projeto em

seu estado inicial. Por exemplo, um novo projeto Web contém por padrão um dire-tório chamado App_Data e também uma página chamada Default.aspx. Esses dois objetos estão definidos em um template que representa um projeto Web.

Agora, os StarterKits são instaladores de projetos que permitem distribuir para outras pessoas, uma implementação ou uma tecnologia específica desenvolvida. Por exemplo, podemos ter um template que contém vários projetos pré-definidos e a partir daí, criar então um instalador para ele, facilitando sua distribuição ao time de desenvolvimento.

Com essas definições, podemos dar início ao nosso exemplo que será divido em duas etapas, sendo a primeira, voltada para a cria-ção de um template contendo três projetos, e a segunda, voltada para a criação de um StarterKit para a instalação desse projeto.

Criando uma SolutionVamos criar um projeto Web Site, por-

Page 43: dotNET42-Final.pdf

42 .NET Magazine - Criando Templates e StarterKit de projetos Edição 42 - .NET Magazine 43

VisuaL sTudio

tanto abra o Visual Studio 2005 e acesse o menu File>New>Web Site. Dê nome ao projeto de “ProjetoStarterKit” e salve-o num diretório chamado “MultiplosProje-tosTemp” (Figura 1). A Figura 2 represen-ta a estrutura básica que usaremos como template para a criação do Starterkit.

Adicione nessa solução dois projetos do tipo ClassLibrary. Clique com o botão direito na Solution, depois selecione Add>New Project>Class Library e salve-os no diretório criado anteriormente, chamando-os de ClassLibrary1 e ClassLi-brary2 (Figura 3).

Deixe no projeto ClassLibrary1 uma única definição de classe chamada Class1 e exclua a classe existente no projeto Clas-sLibrary2. Com o objetivo de demonstrar que qualquer recurso existente na plata-forma .NET pode ser adicionado a um

Figura 1. Criando um projeto Web Site

Figura 2. Estrutura da solução para criação do templateFigura 3. Criando o projeto ClassLibrary

template, vamos a partir de agora inserir um Web User Control.

Clique com o botão direito no projeto Web, selecione Add New Item e escolha o item Web User Control. Mantenha o mesmo nome (Figura 4) e clique em OK para adicioná-lo.

Logo depois, adicione um arquivo de configuração (web.config). Clique com o botão direito no projeto Web, selecione Add New Item e escolha o item Web Con-figuration File (Figura 5).

Em um projeto de template, todas as referências/dependências dos projetos ClassLibrary definidas no projeto Web serão criadas automaticamente assim que criarmos uma nova solução a partir desse template.

Portanto, vamos definir as referências do projeto Web. Clique com o botão di-

reito no projeto Web, selecione Property Pages. Selecione a opção References e cli-que em Add Reference. Na nova janela que se abre, clique na guia Projects e selecione os dois projetos ClassLibrary. Finalize esse processo clicando nos botões OK das respectivas telas (Figura 6).

Finalizamos então a criação de uma so-lução contendo três projetos, que serão a base do nosso template de projeto. Vamos comprovar se a solução está 100% correta, executando um Build Solution. Após a compilação, veremos que um novo dire-tório chamado Bin foi criado, contendo as DLLs dos projetos ClassLibrary que acaba-mos de referenciar (veja Figura 2).

Criando um template de projetoA partir de agora, entraremos no pro-

cesso de criação do template. O primeiro

Page 44: dotNET42-Final.pdf

44 .NET Magazine - Criando Templates e StarterKit de projetos Edição 42 - .NET Magazine 45

Figura 4. Adicionando um Web User Control ao projeto Web

Figura 5. Adicionando um arquivo web.config ao projeto Web

Figura 6. Adicionando referências

passo é exportar cada projeto existente em nossa solução para um template espe-cífico de cada projeto. Comecemos pelo projeto Web e logo depois, façamos os mesmos passos para os demais projetos. Para exportar o projeto Web para tem-plate, acesse o menu File>Export Template (Figura 7).

Uma nova janela será aberta. Ela possui duas opções, sendo uma para exportação de apenas um Item (Item Template) e outra para exportação de um projeto por com-pleto (Project Template). Selecionaremos a opção Project Template (Figura 8).

Na mesma janela, escolhemos que proje-to será exportado e também a categoria de linguagem que o projeto terá quando um novo for criado baseado nesse template. O projeto Web se chama ProjetoStarterKit e a categoria de linguagem é Visual C#. Após configuradas essas opções, prossiga a exportação clicando em Next.

Na janela seguinte, podemos definir um ícone, um nome e também uma breve descrição para o template expor-tado. Vamos dar nome ao template de “ProjetoWebTemplate” e como descrição, digite: “Exemplo de Projeto de Template”. O ícone será o default do Visual Studio (Figura 9).

As duas opções Automatically import the template into Visual Studio e Display an explorer window on the output files folder, correspondem respectivamente, à impor-tação automática do template exportado para dentro do Visual Studio e a exibição do arquivo exportado em uma janela do Windows Explorer.

Como o template que estamos gerando será composto por três projetos, vamos deixar a primeira opção desmarcada. Por fim, clique em Finish para finalizar a ex-portação do projeto Web para template.

Veremos na janela do Windows Explo-rer que se abre, o arquivo que acabamos de exportar. Repita os mesmos passos de exportação para os demais projetos, tendo como resultado final, três arquivos de template (com extensão ZIP), gerados dentro do diretório padrão do Visual Studio 2005.

Os nomes dos templates serão: ClassLi-brary1Template e ClassLibrary2Template. Já a descrição, será a mesma do primeiro projeto exportado (Figura 10).

Após exportados os templates, crie um

Page 45: dotNET42-Final.pdf

44 .NET Magazine - Criando Templates e StarterKit de projetos Edição 42 - .NET Magazine 45

VisuaL sTudio

Figura 9. Definindo ícone, nome e descrição do template

Figura 8. Configurando as opções de exportação

Figura 7. Exportando um template no Visual Studio

diretório temporário, por exemplo (C:\Temp). Nesse diretório, descompacta-remos todos os arquivos de template que acabamos de exportar, sendo que cada arquivo descompactado deverá ser armazenado dentro de seu diretório específico.

Portanto, remova os três arquivos de template zipados para dentro do diretó-rio C:\Temp. Descompacte-os em seus diretórios específicos e logo em seguida, exclua os três arquivos zipados, pois não vamos mais precisar deles. Portanto, o diretório C:\Temp deverá conter apenas os três diretórios (Figura 11).

Estrutura do templateO passo seguinte é criar um arquivo

de configuração do template que estamos criando, que possui extensão vstemplate. Esse arquivo, que tem o formato em XML, é dividido em duas seções. A pri-meira, chamada <TemplateData>, contém propriedades que permitem definir o nome, descrição, tipo do projeto, ícone, entre outras.

Figura 10. Arquivos de templates exportados

Page 46: dotNET42-Final.pdf

46 .NET Magazine - Criando Templates e StarterKit de projetos Edição 42 - .NET Magazine 47

Figura 11. Arquivos de templates descompactados em seus respectivos diretórios

Na segunda, chamada <TemplateCon-tent>, devemos definir links no arquivo de template que referenciarão os projetos que serão criados automaticamente, quando uma nova solução for criada a partir desse template.

Veja na Tabela 1 a descrição das proprie-dades desse arquivo de configuração.

Crie um arquivo de texto comum com o Notepad e altere sua extensão para vstemplate. Dê o nome de “MultiplePro-jectTemplate.vstemplate”. O conteúdo final desse arquivo deverá ficar conforme a Listagem 1.

Como podemos ver, a tag <ProjectTem-plateLink> contém o nome do projeto e faz referência também a um arquivo de configuração desse projeto, onde contém informações relativas a todos os objetos e componentes existentes nele.

Por exemplo, o arquivo vstemplate específico do projeto Web contém in-formações que indicam que ele possui um web.config, um WebUserControl, uma página Default.aspx etc., assim como, o arquivo vstemplate do projeto ClassLi-brary1, contém informações sobre as classes que ele contém, bem como suas referências.

Com isso, podemos concluir que esse ar-quivo é o que especifica todo o conteúdo de seu respectivo projeto. Para ajudá-lo a compreender melhor o conteúdo desse arquivo, basta abrí-lo no Visual Studio e posicionar o mouse sobre as tags, pois assim um hint será exibido com uma des-crição sobre a funcionalidade específica de cada uma.

Vamos entrar agora na etapa final de criação do template. É muito simples, basta compactar dentro de um mesmo arquivo em formato ZIP, todos os três diretórios descompactados anteriormente mais o arquivo vstemplate que acabamos de criar. Dê a esse arquivo o nome de “Multiple-ProjectTemplate.zip” (Figura 12).

Pronto, está criado nosso template, con-tendo múltiplos projetos dentro. Vamos testá-lo, pois esse arquivo será usado poste-riormente na criação do StarterKit. Copie o arquivo (MultipleProjectTemplate.zip) e cole-o no diretório padrão do Visual Studio 2005 (C:\Documents and Settings\<usuario>\My Documents\Visual Studio 2005\Templates\ProjectTemplates\Visual C#).

Abra seu Visual Studio 2005 e acesse

Propriedade Descrição

Name Nome de apresentação do template no box New Project do Visual Studio.

DefaultName Nome default para um novo projeto criado a partir de um template (pode ser alterado pelo usuário antes da criação).

Description Uma pequena descrição.

ProjectType Tipo de projeto.

SortOrder Ordem de apresentação do template no box New Project do Visual Studio.

CreateNewFolder Define se será criada uma nova pasta para o projeto quando o mesmo for criado.

LocationField Habilita/desabilita campo de localização na janela New Project do Visual Studio.

EnableLocationBrowseButton Habilita/desabilita botão Browse na janela New Project do Visual Studio.

Icon Especifica um ícone personalizado.

ProjectTemplateLink Especifica o arquivo de configuração (vstemplate) dos projetos que farão parte do template.

Tabela 1. Propriedades do arquivo vstemplate

Figura 12. Arquivo de template final compactado

Page 47: dotNET42-Final.pdf

46 .NET Magazine - Criando Templates e StarterKit de projetos Edição 42 - .NET Magazine 47

VisuaL sTudio

Listagem 1. Criando o arquivo vstemplate

<VSTemplate Version=”2.0.0” xmlns=”http://schemas.microsoft.com/developer/vstemplate/2005” Type=”ProjectGroup”> <TemplateData> <Name>MultipleProjectTemplate</Name> <DefaultName>MultipleProject</DefaultName> <Description>Exemplo de Projeto de Template</Description> <ProjectType>CSharp</ProjectType> <!--<ProjectSubType>CSharp</ProjectSubType>--> <SortOrder>1</SortOrder> <CreateNewFolder>true</CreateNewFolder> <LocationField>Enabled</LocationField> <EnableLocationBrowseButton>true</EnableLocationBrowseButton> <Icon>__TemplateIcon.ico</Icon> </TemplateData> <TemplateContent> <ProjectCollection>

<ProjectTemplateLink ProjectName=”ProjetoWebTemplate”> ProjetoWebTemplate\MyTemplate.vstemplate </ProjectTemplateLink>

<ProjectTemplateLink ProjectName=”ClassLibrary1Template”> ClassLibrary1Template\MyTemplate.vstemplate </ProjectTemplateLink>

<ProjectTemplateLink ProjectName=”ClassLibrary2Template”> ClassLibrary1Template\MyTemplate.vstemplate </ProjectTemplateLink> </ProjectCollection> </TemplateContent></VSTemplate>

Figura 13. Criando um novo projeto a partir do template

Figura 14. Exclusão do arquivo de template

o menu File>New>Project. Na janela que se abre, selecione a opção Visual C# no Project types, selecione o template que acabamos de criar, que está localizado na seção My Templates (Figura 13).

Escolha um nome e um diretório que quiser e pressione OK pra criar uma nova solução. Veremos então que a solução será criada contendo três projetos, sendo eles Web, ClassLibrary1 e ClassLibrary2, conforme havíamos definido no início deste artigo.

Criando o StarterKitAcesse o diretório padrão do Visual Stu-

dio (C:\Documents and Settings\<usuario>\My Documents\Visual Studio 2005\Templa-tes\ProjectTemplates\Visual C#) e exclua o arquivo de template que havíamos adicio-nado manualmente (Figura 14).

Mas você pode estar se perguntando, por que excluí-lo? Porque criaremos um StarterKit que fará a instalação automática desse template no diretó-rio. Vamos agora acessar o diretório temporário (C:\Temp) e criar mais um arquivo de configuração, também em formato XML.

Basta criar um arquivo texto comum com o Bloco de Notas e depois alterar sua extensão (TXT) para “vscontent”. Nesse arquivo, como podemos ver na Listagem 2, é definido o nome do arquivo de template (MultipleProjectTemplate.zip) na tag </FileName>, que será executado pela instalação.

Podemos conhecer as outras proprieda-des, observando a Tabela 2. Especifique as propriedades do arquivo vscontent conforme a Listagem 2 e salve-o com o nome de “MultipleProjectTemplate.vscontent”.

Venho chamar a atenção para a tag <Attributes>, nela é definido o tipo do projeto de template e também o tipo do projeto como um todo, que estamos de-senvolvendo. Assim que finalizarmos a instalação do StarterKit, veremos que ele será instalado no diretório específico de templates do Visual Studio.

O que define essa característica de instalação é justamente a segunda tag Attribute. Se desejar testar outros tipos de projetos, basta abri-lo no Visual Studio e utilizar o Intellisense como helper.

Depois de configurado o arquivo, va-

mos compactá-lo junto com o arquivo de template chamado MultipleProjectTemplate.zip, que criamos na primeira parte deste artigo. Dê nome de “StarterkitMultiple-Project.zip” (Figura 15).

O último passo para a criação do Star-terKit é muito simples. Para que tenha-mos um arquivo que seja “executável”, basta apenas alterar a extensão do Star-terkitMultipleProject.zip para VSI, ficando, portanto assim, StarterkitMultipleProject.vsi (Figura 16).

Page 48: dotNET42-Final.pdf

48 .NET Magazine - Criando Templates e StarterKit de projetos Edição 42 - .NET Magazine 49

Figura 15. Arquivo StarterKit criado

Figura 16. Alteração de extensão do arquivo StarterKit de ZIP para VSI

Figura 17. Interface do assistente de instalação

Figura 18. Mensagem de erro referente à ausência de assinatura digital Figura 19. Interface final do assistente

Testando a instalação do StarterKitPronto, está criado nosso StarterKit. Podemos agora então

executá-lo e testá-lo. A Figura 17 ilustra a primeira tela do assistente de instalação.

O nome MultipleProject exibido nessa tela foi definido na tag <DisplayName> do MultipleProjectTemplate.vscontent. Deixe selecionada essa opção e clique em Next para continuar. Uma mensagem de erro é exibida conforme a Figura 18.

Porém, podemos ignorá-la clicando em Yes, pois ela é exibida devido ao instalador não possuir uma assinatura digital. Ge-ralmente, StarterKits desenvolvidos pela Microsoft possuem assinatura digital incluída.

A Figura 19 representa o último passo de instalação. Portanto, clique em Finish para terminar.

Veremos uma mensagem exibida na própria tela confirmando o sucesso da instalação. Agora, podemos observar no diretório padrão do Visual Studio (C:\Documents and Settings\<usuario>\My Documents\Visual Studio 2005\Templates\ProjectTemplates) que o template foi criado com sucesso. Clique em Close para fechar o assistente.

Listagem 2. Estrutura do arquivo (vscontent)

<?xml version=”1.0” encoding=”utf-8”?><VSContent xmlns=”http://schemas.microsoft.com/developer/vscontent/2005”>

<Content> <FileName>MultipleProjectTemplate.zip</FileName> <DisplayName>MultipleProject</DisplayName> <Description>Instalador de MultipleProject</Description> <FileContentType>VSTemplate</FileContentType> <ContentVersion>1.0</ContentVersion>

<Attributes> <Attribute name=”TemplateType” value=”Project”/> <Attribute name=”Project Type” value=”Visual C#”/> </Attributes>

</Content></VSContent>

Page 49: dotNET42-Final.pdf

48 .NET Magazine - Criando Templates e StarterKit de projetos Edição 42 - .NET Magazine 49

VisuaL sTudio

Propriedade Descrição

FileName Nome do arquivo de template (ZIP) que contém os diretórios dos projetos mais o arquivo (vstemplate).

DisplayName Nome do projeto de template que será apresentado na tela de instalação.

Description Uma pequena descrição sobre o starterkit.

FileContentType Tipo de projeto starterkit.

ContentVersion Versão do starterkit.

Attributes Especifica o tipo de template e também o tipo do projeto starterkit.

Tabela 2. Propriedades do arquivo (vscontent)

Figura 20. Template adicionado ao Visual Studio

Figura 21. Nova solução criada a partir do template e compilada com sucesso

Terminada a instalação, vamos testar o template criando uma nova solu-ção. No Visual Studio, acesse o menu File>New>Project e veja que o template é exibido na seção My Templates. Sele-cione-o, defina um nome e também um diretório para salvá-lo.

As Figuras 20 e 21 ilustram os processos de criação e compilação realizados com sucesso, referentes à nova solução.

ConclusãoPodemos concluir que a criação de um

StarterKit automatiza consideravelmente o desenvolvimento de novas soluções que possuam características básicas e comuns entre elas. Uma vez criado o StarterKit, o mesmo poderá ser distribuído ao time de desenvolvimento, rapidamente.

Concluímos também que o processo de criação de templates de projetos é bastante simples e eficaz, permitindo economizar um tempo considerável na fase inicial de programação.

Um grande abraço e até o próximo artigo!

MSDN – “How to: Create Starter Kits” – (inglês)

msdn2.microsoft.com/en-us/library/ms364046(vs.80).aspx

MSDN Wiki – “Introdução aos Starter Kits” – (português)

msdnwiki.microsoft.com/pt-br/mtpswiki/ms247071

(VS.80).aspx

Referências

Page 50: dotNET42-Final.pdf

50 .NET Magazine - Utilizando o Code Analysis do Visual Studio Edição 42 - .NET Magazine 51

Utilizando o Code Analysis do Visual Studio

Penihel Roosewelt([email protected])

tem 20 anos e é certificado Microsoft MCP, MCTS e MCAD. Trabalha com .NET há três anos na ci-dade de Brasília-DF. Atualmente trabalha para a AgênciaClick em projetos voltados para a Web. Além de ser completamente apaixonado por tecnologia e .NET.

O Visual Studio Code Analysis é uma ferramenta que verifica o código validando a conformi-

dade com o Microsoft .NET Framework Design GuideLines (msdn2.microsoft.com/en-us/library/ms229042.aspx).

É uma ferramenta que permite fazer um ìcheck-upî no seu código-fonte, veri-ficando regras de design, uso correto de padrões, deteca ainda problemas como performance, segurança e outros.

Ele usa Reflection, MSIL Parsing e Call-graph Analysis para analisar o código. São executadas verificações para cerca de 200 regras de código, nas seguintes áreas:

• Design (60 regras): Regras para in-terfaces e estrutura das classes. Envolve melhores práticas para uso de namespa-ces, eventos, coleções e parâmetros de métodos;

• Globalização (7 regras): Práticas para o sistema aceitar vários idiomas facilmente;

• Interoperalidade (16 regras): Regras

para o uso correto de objetos COM e COM +;

• Manutenibilidade (3 regras): Regras para ajudar na manutenção do código, geralmente com heranças confusas e códigos muito extensos;

• Mobilidade (2): Poucas, mas eficientes regras para compatibilidade em disposi-tivos móveis;

• Nomes das variáveis (20 regras): Pro-vavelmente as regras mais conhecidas, que envolvem desde nome das variáveis até nomes das Assemblies;

• Performance (19 regras): Considero as mais importantes, mas nem sempre são levadas a sério. Detecta melhorias de performance que podem ser corrigidas, apenas com melhorias no código;

• Portabilidade (2 regras): Regras para o código interagir com uma possível mudança de plataforma (Windows para Web, Mobile ou Mono);

• Confiabilidade (5 regras): Regras para garantir que o código não atrasará os

Page 51: dotNET42-Final.pdf

50 .NET Magazine - Utilizando o Code Analysis do Visual Studio Edição 42 - .NET Magazine 51

VisuaL sTudio

recursos da CLR e do Garbage Collector e também boas práticas para uso de multi-threading;

• Security (24 regras): Regras também muito importantes que tratam de brechas de segurança causadas por código sem boas práticas;

• Usuais (40): Regras gerais para boas práticas Microsoft.

Depois de ver tantas regras, você deve estar pensando, mas agora, vou levar dois meses para deixar meu código aprovado por essa ferramenta! Porém você pode configurar apenas que regras específicas você deseja aplicar.

Hoje em dia essa ferramenta é conheci-da com Code Analysis, vem junto com o Vi-sual Studio Team Edition for Developers, porém não existe nas versões Standard e Professional.

Um dia, na era .NET 1.1, era conhecida como FxCop, mas ainda existe uma versão que pode ser usada em uma GUI separa-da. O FxCop pode ser acessado em: www.gotdotnet.com/Team/FxCop.

Nota: Para saber mais sobre o FxCop,

veja o artigo de Rodrigo Sendin publi-

cado na edição 35.

O FxCop também pode ser baixado para o .NET 2.0 para quem não tem o Visual

Studio Team Edition. Neste artigo vamos ver em detalhes o Code Analysis para o Visual Studio Team Edition.

O IDE do Visual Studio não mostra as funcionalidades com todas as flexibili-dades do Code Analysis (CA). O CA tem uma ferramenta de linha de comando e veremos como utilizá-la.

Existe a possibilidade também de você desenvolver novas regras, acesse

Figura 1. Habilitando o Code Analysis no Visual Studio Team Edition

media.techtarget.com/digitalguide/images/Misc/professionalvsts_ch08.pdf para mais informações.

Mão na MassaCrie um projeto Class Library em C#,

renomeie o arquivo Class1.cs para ìPay-Calculator.csî e adicione o código da Listagem 1.

O código calcula o salário do desenvol-

Listagem 1. Criando uma classe de exemplo

using System;using System.Collections.Generic;using System.Text;

namespace CodeAnalysisClassLibrary{ public class PayCalculator { public enum Pay_Level { EntryLevel = 20, Normal = 35, Senior = 50 }

public static int MaximumHours; public const double BONUS = 0.10; static PayCalculator() { MaximumHours = 100; } public static double ComputePayment(int hours, Pay_Level level) { if (hours > MaximumHours) { throw new ArgumentOutOfRangeException(“Horas Ultrapassadas”); } return ((int)level * hours); } }}

Page 52: dotNET42-Final.pdf

52 .NET Magazine - Utilizando o Code Analysis do Visual Studio Edição 42 - .NET Magazine 53

vedor de acordo com um fator do enum Pay_Level e multiplicando ao número de horas. Ao primeiro olhar, o código não tem nenhum erro e também é totalmente compilável, mas vamos ver o que o CA tem a dizer sobre ele.

Habilitando o CAA primeira coisa a fazer é habilitar o

CA, pois por padrão no Visual Studio ele vem desabilitado. Para habilitar, acesse o menu Project>CodeAnalysisClas

sLibrary Properties. Será aberta a tela de propriedades.

Selecione a aba Code Analysis e marque o item Enable Code Analysis (Figura 1) e para finalizar salve o projeto.

Nessa mesma tela podemos ver que cada regra pode ser configurada como Warning ou Error, sendo que Warning é a configuração padrão. Quando uma regra está definida para Warning, ela não impe-de o sistema de ser compilado.

Já quando definida como Error, se a re-gra não for satisfeita, o sistema não será compilado. Para mudar essa configuração apenas dê um duplo clique em cima da coluna de Status.

Podemos ainda alterar o Status de um grupo inteiro ou apenas de uma regra específica, para isso clique no sinal de (+) de cada grupo e altere o status de cada regra individualmente.

Também existem duas caixas de seleção onde você pode indicar que tipo de Build deve ser executado. O mais comum é configurá-lo apenas para Builds Releases e não habilitar para Builds Debugs. No nosso exemplo, vou deixar selecionadas todas as regras e com Status em Warning.Figura 2. Executando o Code Analysis no projeto

Figura 3. Janela de erros

Executando o CAAgora vamos aprender a executar o

CA. Confirme que você salvou as confi-gurações dos passos anteriores, acesse o menu Build e clique em Run Code Analysis on CodeAnalysisClassLibrary (Figura 2). O Build será executado, e no final aparecerá uma janela semelhante à Figura 3.

É possível que a janela não apareça automaticamente. Para mostrá-la, acesse o menu View>Error List. Note que nesse caso, temos 10 regras que não foram sa-tisfeitas no código.

Cada linha contém uma descrição e uma indicação de onde está o erro. Al-gumas regras não são necessariamente associadas a uma linha de código, assim não indicam nenhum arquivo.

Se você der um duplo clique em uma regra que contenha uma associação de código, o Visual Studio posicionará o cursor no local exato do erro. Até aí tudo bem, mas qual o erro?

Geralmente apenas com a descrição da regra você já pode matar a charada e saber o que fazer para se enquadrar na regra, mas alguns erros não são muito claros. Vamos ver alguns exemplos mais adiante.

Page 53: dotNET42-Final.pdf

52 .NET Magazine - Utilizando o Code Analysis do Visual Studio Edição 42 - .NET Magazine 53

VisuaL sTudio

XML de documentaçãoCada vez que você roda o CA, ele altera

um arquivo XML dentro da pasta onde o assembly será compilado (/bin/debug ou /bin/release) e geralmente terá o nome de CodeAnalysisClassLibrary.dll.CodeAnaly-sisLog.xml.

Esse arquivo contém um relatório com as mesmas informações da janela Error List, porém em um modelo bem mais apresentável. Isso é bem útil para você apresentar esses resultados para chefes/colegas ou acrescentar em documentos. A Figura 4 mostra o arquivo.

Vamos corrigir alguns problemas indi-cados pelo CA. No Error List localize o erro com o a descrição: CA1810 : Microsoft.Performance : Initialize all static fields in CodeAnalysisClassLibrary.PayCalculator when those fields are declared and remove the explicit static constructor. Clique com o botão direito e escolha Show Error Help.

Isso mostrará uma janela explicativa com todos os detalhes da regra, dizendo o motivo de existir a regra e como você pode corrigir o erro (Figura 5).

Na janela de ajuda, é explicado que o código ficará mais eficiente se tirarmos a inicialização da variável do construtor estático e deixarmos diretamente na de-claração da variável.

Corrigindo errosCom essa informação vamos alterar o

código. No Error List clique duas vezes na regra para sermos redirecionados para o construtor estático. Remova todo o construtor e altere a declaração da variável para:

public static int MaximumHours=100;

Pronto, corrigimos o primeiro erro. Para conferir, execute novamente o CA e verifique que no Error List existem ape-nas 9 Warnings. Corrigir todos os 9 erros

Figura 4. Arquivo XML útil para documentação

Figura 5. Descrição e explicação sobre a regra

Page 54: dotNET42-Final.pdf

54 .NET Magazine - Utilizando o Code Analysis do Visual Studio Edição 42 - .NET Magazine 55

passo a passo levaria muito esforço, por isso, vou direto para o próximo assunto do artigo, mas o importante é que você entenda que é muito fácil corrigir os erros apontados pelas regras.

Ignorando regrasUm ponto muito importante é que você

não precisa analisar todas as regras do CA, existem formas de evitar que certas regras sejam executadas, pois podem não se apli-car a seu cenário. A forma mais fácil é des-marcar a regra na tela de propriedades do projeto, como mostrado anteriormente.

Se você não souber exatamente o que uma regra faz, marque todas, e depois vá desmarcando de acordo com o seu julgamento de necessidade da regra. No nosso caso, estamos com 9 Warnings no Error List. Clique com o botão direito na primeira, que deve ser a de código CA 2209 e clique em Suppress Message. Note que agora a regra fica com o texto com uma tarja (Figura 6).

Depois de executar o Suppress Message, o CA criou um arquivo no projeto chamado GlobalSuppressions.cs que contém atributos para serem aplicados em todo o assembly.

Figura 6. Ignorando a regra no Error List

Abra esse arquivo e veja como ele utiliza o atributo System.Diagnostics.CodeAnaly-sis.SuppressMessage, indicando que a regra não deve ser analisada, conforme vemos no código a seguir: [assembly: System.Diagnostics.CodeAnalysis. SuppressMessage("Microsoft.Usage", "CA2209:AssembliesShouldDeclareMinimum Security")]

Você pode também colocar esse atributo no método ou na classe. Para saber mais sobre ele, acesse msdn2.microsoft.com/en-us/library/ms244717(vs.80).aspx.

Linha de comandoVamos à próxima funcionalidade. Como

disse anteriormente, o Visual Studio não explora todas as flexibilidades do CA, mas quando você quiser fazer tarefas avançadas, pode usar a ferramenta de linha de comando.

As versões anteriores eram conhecidas apenas como FxCop, e essa ferramenta era bem mais usada do que hoje. Ela pode ser encontrada na pasta de instalação do Visual Studio no caminho: C:\Arquivos de programas\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\FxCopCmd.exe.

O FxCopCmd pode executar qualquer ta-refa que existe no IDE, pois o IDE chama essa ferramenta passando vários parâme-tros. O CA (ou FxCop) faz análises não no código-fonte, mas sim no Assembly.

Porém o Visual Studio deixa isso trans-parente para o desenvolvedor, que pode ter a impressão que a ferramenta analisa o código-fonte. Vamos supor que o pro-jeto já está compilado através do CodeA-nalysisClassLibrary.dll, olhe um exemplo de como fazer essa análise através da linha de comando:

FxCopCmd.exe /f: CodeAnalysisClassLibrary.dll /o: “C:\reportresult.xml” /s

Lembrando que você deve estar dentro da pasta onde se encontra o arquivo Fx-CopCmd.exe (Figura 7).

Neste exemplo, pedi ao CA para gerar o relatório no drive C. Abra o report.xml e veja que o mesmo contém os 9 Warnings e que o arquivo é igual ao gerado pelo Visual Studio.

Agora vamos analisar o comando, o primeiro parâmetro exe /f: CodeAnaly-sisClassLibrary.dll indica o assembly que será analisado, o segundo parâmetro /o: indica onde serão salvas as mensagens e

Page 55: dotNET42-Final.pdf

54 .NET Magazine - Utilizando o Code Analysis do Visual Studio Edição 42 - .NET Magazine 55

VisuaL sTudio

Figura 7. Utilizando o FxCopCmd

o resultado da análise. O último parâmetro /s indica que o

resultado deve ser mais simplificado e que as informações sejam mostradas em uma forma mais resumida.

ConclusãoO Code Analysis do Visual Studio Team

Edition é uma das melhores ferramentas do Visual Studio e ajuda na qualidade e no controle do código que é gerado pela sua equipe. A sua maior qualidade é a flexibilidade para configuração.

Às vezes não queremos usar todas as regras para análise, por isso, um fator importante na hora de usar, é você avaliar quais grupos de regras ou quais regras específicas devem ser dispensadas pela sua equipe e quais não devem.

Também é importante lembrar que você não precisa do Visual Studio para usá-la, pode baixá-la gratuitamente em www.gotdotnet.com/Team/FxCop e usá-la através da linha de comando como mostramos aqui ou também usar a GUI específica que existe especialmente para o FxCop.

Um ponto fraco da ferramenta é quando queremos criar nossas próprias regras, onde o processo é trabalhoso e exige conhecimentos avançados de .NET, prin-cipalmente em Reflection.

Se você estiver usando a versão do Fx-Cop separada do Visual Studio, pode ter mais facilidades para criar novas regras. Enfim, espero que com este artigo você possa ter condições de melhorar o código produzido por você e sua equipe.

Abraços!

FxCop

www.gotdotnet.com/Team/FxCop

In Source Suppression Overview

msdn2.microsoft.com/en-us/library/ms244717(vs.80).aspx

Criar regras para o Code Analysis

m e d i a . te c h t a rg e t. co m / d i g i t a l g u i d e / i m a g e s / M i s c /

professionalvsts_ch08.pdf

Microsoft .NET Framework Design GuideLines

msdn2.microsoft.com/en-us/library/ms229042.aspx

Reflection

msdn2.microsoft.com/en-us/library/system.reflection.aspx

Links

Page 56: dotNET42-Final.pdf

56 .NET Magazine - Microsoft Solutions Framework Edição 42 - .NET Magazine 57

Microsoft Solutions Framework

Fábio Camara(www.fcamara.com.br)

tem 18 anos de experiência no desenvolvimento de softwares e produtos, e na gestão de projetos em grandes empresas no Brasil, com destaque para projetos na área de telefonia e financeira/bancária (SPB), além de extensa experiência em treinamento e consultoria no desenvolvimento de software e gestão de projetos. É autor de 15 livros, possui as certificações MCT, MCP, MCSA, MCSE, MCAD (C# e VB .NET) Charter, MCDBA, MCSD .NET (Early Achiever), MCTS, MCPD, MSF Certified Practitioner, ITIL Foundations, Delphi Programmer Master, Certified SCRUM Master e é INETA Speaker (International .NET Association). Microsoft MVP (Most Valuable Professional) para a ferramenta Visual Studio Team System. Foi o fundador da ArchITettura, a primeira fábrica de software do Brasil voltada exclusivamente à tec-nologia Microsoft .NET. Foi Consulting Manager da FórumAccess Consultoria. É consultor especial da Poliedro, conselheiro técnico da Coca-Cola do Nordeste e responsável pelos treinamentos da F|Camara Formação e Consultoria.

MSF vem passando por desenvol-vimento contínuo e melhorias durante uma década. A visão

original para MSF era colecionar e orga-nizar um corpo de orientação e melhores práticas para utilização como um guia durante o ciclo de vida de desenvolvi-mento de software.

No início, os principais influenciadores do MSF foram:•A experiência de desenvolvimento da

própria Microsoft;•Contribuições de experiências da Mi-

crosoft Consulting, a empresa de serviços da Microsoft;•Melhores práticas da indústria;•Contribuições do programa de empre-

sas parceiras Microsoft.O MSF versão 4 (atualmente está em

revisão final a versão 4.1) é uma evo-lução da metodologia MSF, criada pela Microsoft em 1993. Desde a década de 90 o MSF adicionou uma forte influência da comunidade Ágil, tornando-a uma

metodologia de vanguarda. Historicamente, a Microsoft sempre

teve muito cuidado para evitar que o MSF virasse uma metodologia. Por isso, eu quero dizer que a adoção de MSF nunca designou a compra de ferramentas caras, modelos etc., ou a adoção de processos altamente prescritivos e detalhados.

Ao invés, MSF conscientemente mos-trava direções para prover orientação e princípios dos quais podem ser agrega-dos a uma variedade metodologias de forma discreta. Isso inclui, por exemplo, os famosos processos de metodologias como DSDM e RUP.

Se analisarmos habilmente, concluire-mos que para a década de 90 essa abor-dagem fazia todo sentido. A Microsoft destinava seus esforços para atender suas próprias necessidades de processos e não compreendia como útil destinar investimentos para formalizar o MSF como uma metodologia one size fits all approaching.

MicrosoftFramework

Page 57: dotNET42-Final.pdf

56 .NET Magazine - Microsoft Solutions Framework Edição 42 - .NET Magazine 57

proJETo/aNáLisE

Na minha leitura, está é a razão que mais me agrada em usar MSF em meus desafios, pois foi uma metodologia criada em cima de necessidades específicas e reais, mesmo considerando que a Microsoft não é uma empresa de desenvolvimento comum.

Hoje a proposta da Microsoft ao promo-ver MSF para metodologia é fundamen-tada pela compreensão da necessidade real de utilizarmos um mecanismo que maximize a comunicação e os princípios de melhores práticas de desenvolvimen-to, testes e controle de forma integrada.

Antes de chegar nessa dimensão de maturidade, MSF passou por três grandes revisões que representam significativa-mente a evolução como um framework para o desenvolvimento de projetos. Nessa última revisão foram criadas duas instâncias da versão 4.0: MSF for Agile Software Development e MSF for CMMI Process Improvement.

Eu acredito que MSF agora representa uma significativa mudança na atitude Microsoft, principalmente pela transpa-rência na definição dos métodos, papéis e processos.

Destaco positivamente também a inte-gração com as ferramentas Visual Studio, que marca a história do MSF como um divisor de águas. Em outras palavras, será ensinado nos livros o que é MSF pré VSTS (Visual Studio Team System) e o que é MSF pós VSTS.

Comparação de MSF v3 e MSF v4Primeiramente, quando conheci a MSF

versão 3.1 em meados de 1999, achei-a simplesmente fantástica. Dividida em dois modelos e três disciplinas, aprofun-dei-me em colocar os modelos em prática imediatamente. Os modelos eram:•Team Model: Definição dos papéis de

Program Manager, Product Manager, User Experience, Release Manager, Tester e De-veloper;•Process Model: Explicação dos proces-

sos, técnicas e artefatos de cada fase do ciclo. As fases eram: Envisioning, Planning, Developing, Stabilizing e Deploying.

As disciplinas eram:•Project Management: Na minha leitu-

ra esta disciplina foi uma agressão ao “espírito” MSF e deve ter sido alguma imposição de pensadores de acordo com as práticas definidas no PMBok;

•Risk Management: Disciplina que defi-ne um ciclo para identificação e controle de riscos factíveis ao projeto;•Readiness Management: Disciplina que

define um ciclo para tratamento das li-ções aprendidas de um projeto. Útil como boas práticas para elaboração de sistemas de base de conhecimento.

No MSF v4, tivemos significativas mudan-ças na estruturação dos modelos. Em Team Model os papéis de Product Manager e User Experience foram trocados pelo papel de Bu-siness Analyst, que convenhamos está muito mais aderente a realidade dos projetos.

Na verdade, os papéis do MSF v3 Pro-duct Manager e User Experience continuam existindo, porém são considerados como parte do cliente. No time de desenvolvi-mento é considerado o papel de Business Analyst como o responsável pelo relacio-namento com o Product Manager e o User Experience.

Ainda no Team Model, tivemos a in-clusão na MSF v4 do papel de arquiteto de sistemas. Esse papel há anos é uma requisição dos pensadores que definem metodologias. Pode-se entender que ele vem como uma transição do papel de Program Manager do MSF v3, que na ver-são 4 recebeu o nome chicle de mercado Project Manager.

Veja na Tabela 1 as diferenças dos pa-peis nas versões 3 e 4 do MSF.

Em Process Model, as mudanças foram na forma do ciclo, que antes era espiral e agora definido como iterativo incremental e a inclusão de uma nova fase chamada contínuos. A mudança na forma do ciclo vem como um importante passo em si-nergia com os movimentos ágeis.

Iterativo, porque possui um ciclo peque-no e rápido que é repetitivo. Incremental porque sempre soma funcionalidades aos resultados dos ciclos anteriores.

MSF e os princípios de desenvolvimento Ágil

Os princípios de desenvolvimento ágil estavam no ar na década de 90 como uma reação às metodologias tradicionais de desenvolvimento em cascata (waterfall), consideradas muito pesadas para equipes pequenas.

MSF surgiu entre outras coisas da necessidade de criar novos aplicativos para a plataforma cliente-servidor, que respondia diretamente às necessidades de negócio dos clientes de uma maneira muito mais ágil do que a plataforma mainframe. No ambiente da época, como hoje, as regras de negócio e a tecnologia mudavam rapidamente.

No conceito de entrega em versões, MSF 1.0 explica que um sistema que demora muito para ser desenvolvido perde seu va-lor para o cliente quando finalmente é com-pletado, e está sempre no círculo vicioso de tentar alcançar requisitos em constante fluxo. Por isso justifica-se a necessidade de colaborar com o cliente para priorizar e tomar decisões para balancear os três parâmetros mais comuns de gerências de projetos: cronograma, escopo, recursos.

Para “desenvolver sistemas rapidamen-te e atender a necessidades estratégicas de negócio” a solução recomendada pela MSF é “manter o cronograma e fixar a data final de entrega da versão”.

Isso implica uma intensa atividade de priorização em conjunto e significa que “grandes idéias ou requisitos desejáveis tomam uma prioridade menor do que o cronograma de entrega da versão. O projeto inteiro é gerenciado do início ao fim para acomodar essa realidade”.

Eis aqui um mapeamento inicial dos doze princípios da MSF (Tabela 2). Note que alguns princípios da MSF correspon-dem a mais de um do Manifesto, já que o

MSF v3 MSF v4

User Experience Business Analyst

Product Manager Business Analyst

Program Manager Dividido entre Project Manager e Architect

Release Manager Release Manager

Tester Tester

Developer Developer

??? DataBase Professional

Tabela 1. Diferença das versões 3 e 4 do MSF

Page 58: dotNET42-Final.pdf

58 .NET Magazine - Microsoft Solutions Framework Edição 42 - .NET Magazine 59

particionamento conceitual é semelhante, mas não idêntico.

A seguir, vamos ver como MSF se en-caixa no Manifesto Ágil.

As raízes Ágeis da MSFMSF v4 é uma evolução de versões ante-

riores da MSF que acrescenta influências da comunidade Ágil e outras inovações. MSF for Agile Software Development faz parte da nova geração de metodologias Ágeis (Agile 2.0).

Mas quais são os critérios para uma metodologia Ágil? Não há um “padrão de certificação” para Ágil, mas podemos com segurança usar os mesmos crité-rios eleitos pelos participantes do First

Princípios por trás do Manifesto Ágil Princípios de MSF 1.x correspondentes MSF for Agile Software Development

Nossa prioridade mais alta é satisfazer ao cliente através de entregas

contínuas e antecipadas de software útil. Entrega em Versões, Atitude Mental de Produto, Construção Diária.

Entregue Valor em Incrementos, Enfoque no Valor

para o Negócio.

Mudanças nos requisitos são bem-vindas, mesmo que cheguem

tarde durante o desenvolvimento. Processos ágeis usam mudanças

para a vantagem competitiva do cliente.

Entrega em Versões, Priorização e Cronogramação Orientadas a Risco, Enfoque

Iterativo, Desenvolvimento em Paralelo com Sincronizações Freqüentes.

Entregue Valor em Incrementos; Mantenha-se Ágil,

Adapte-se a Mudanças; Enfoque no Valor para o

Negócio.

Entregar software operante freqüentemente, de algumas semanas a

alguns meses, de preferência nos intervalos mais curtos.

Entrega em Versões, Enfoque Iterativo, Atitude Mental de Produto, Atitude

Mental de Data de Entrega Fixa.Entregue Valor em Incrementos.

Cliente e desenvolvedores devem trabalham juntos diariamente

durante o projeto.

Cliente como Gerente de Produto, Gerente de Produto e Experiência do Usuário

como parte do Modelo de Equipe desde o início do projeto.

Faça Parceria com os Clientes, Trabalhe por Uma Visão

Compartilhada, Modelo de Equipe.

Criar projetos com indivíduos motivados. Dar a eles o ambiente e

suporte que necessitam, e confiar neles para a execução do projeto.

Modelo de Equipe, Equipe de Iguais, Equipes Pequenas e com Poder de

Decisão.

Tenha Satisfação de um Trabalho Bem Feito, Dê

Poder de Decisão aos Membros da Equipe, Estabeleça

Responsabilidade Claramente.

O método mais eficiente e efetivo para transmitir informações dentro

e para a equipe de desenvolvimento é conversação face a face.Princípio de Colocação, Comunicações Abertas.

Promova Comunicações Abertas, Trabalhe por Uma

Visão Compartilhada.

Software operante é a medida primária de progresso. Construção Diária (incluindo documentação do usuário e testes de Aceitação). Entregue Valor em Incrementos.

Processos ágeis promovem desenvolvimento sustentável. Os

patrocinadores, desenvolvedores e usuários devem ser capazes de

manter um ritmo constante de maneira indefinida.

Entrega em Versões, Manutenção com uma nova Entrega (nenhuma fase de

manutenção em separado), Atitude Mental de Produto.Entregue Valor em Incrementos.

Atenção contínua a excelência técnica e ao bom desenho ampliam

a agilidade.

Modelo de Aplicativo, Processo de Análise Concorrente, Planejamento

através da Construção, Análise Orientada a Arquitetura e Design, Modelo

Baseado em Serviços.

Invista em Qualidade.

Simplicidade, a arte de maximizar a quantidade de trabalho não

feito, é essencial. Entrega em Versões.

Entregue Valor em Incrementos, Enfoque no Valor

para o Negócio.

As melhores arquiteturas, requisitos e desenhos emergem de equipes

auto-organizadas.

Modelo de Equipe, Equipe de Iguais, Equipes Pequenas e Com Poder de Decisão,

Planejamento de Baixo para Cima.

Modelo de Equipe, Promova uma Equipe de Iguais,

Internalize Qualidades de Serviço, Enfoque na Visão

Genérica (Look at the Big Picture).

Em intervalos regulares, a equipe reflete sobre como se tornar mais

efetiva e então harmoniza e ajusta seu comportamento de acordo

Revisões Pós Entregas, Aprendendo ao Fazer, Planejamento através da

Construção.Aprenda com Todas as Experiências.

Tabela 2. Princípios da MSF

eWorkshop on Agile Methods [Boehm et al., 2002].

Para essa reunião, escolheram basear a definição de uma metodologia Ágil nos doze “Princípios por trás do Manifesto Ágil”, e quatro pontos sugeridos por Ken Schwaber, um dos participantes e autor do processo Scrum. Depois dessa reunião, os critérios ainda estão sendo debatidos, mas isso está além do escopo deste artigo.

Definindo agilidadeO Manifesto Ágil para Desenvolvimen-

to de Software diz o seguinte:“Estamos descobrindo melhores manei-

ras de desenvolver software fazendo-o, e

ajudando outros a fazê-lo. Através desse trabalho viemos a valorizar:•Indivíduos e iterações ao invés de

processos e ferramentas; •Software operante ao invés de docu-

mentação abrangente; •Colaboração com o cliente ao invés de

negociação de contrato; •Responder à mudança ao invés de

seguir um planejamento.Ou seja, se por um lado há valor nos

itens da direita, valorizamos mais os itens da esquerda”.

Fonte: www.agilemanifesto.org

Ken Schwaber propôs o seguinte:“Um método ágil é: Iterativo, Incremen-

Page 59: dotNET42-Final.pdf

58 .NET Magazine - Microsoft Solutions Framework Edição 42 - .NET Magazine 59

proJETo/aNáLisE

tal, Auto-Organizante e Emergente”Fonte: [Boehm et al., 2002]

MSF e o Manifesto ÁgilMSF valoriza indivíduos e iterações

ao invés de processos e ferramentas. Os desafios de lidar com software como pro-duto mental coletivo para um mercado de massa, fizeram com que a Microsoft ficas-se bem consciente das complexidades do desenvolvimento de software.

Ao capacitar os times colocando-os em pequenas e auto-suficientes Equipes de Iguais, e ao conectar-se aos seus usuários através de estudos amplos de Usabilidade em laboratórios, garantiu que o elemento humano é o mais importante ao trazer os produtos para o mercado.

MSF valoriza software operante ao invés de documentação abrangente. Al-gumas citações clássicas da MSF bastarão para mostrar esse ponto de que software operante como fator fundamental para trazer a idéia do produto do abstrato para o concreto:

“Você tem de fazer o produto visível. Pú-blico. Você pode imaginar se vendarmos os olhares de dezenas ou mesmo centenas de pessoas e deixá-las à solta para cons-truir uma ponte sem poder ver o que estão fazendo? É essencial criar os executáveis do produto de software em construção tão frequentemente quanto possível.”

E também, “Se equipe = software, então o software operante corrente é o estado corrente da equipe”.

Jim McCarthy, Dynamics of Software Development, páginas 109-112

Especificamente sobre a documentação em si, eis aqui o pragmatismo da MSF:

“Na Microsoft, documentos de desenho são desenvolvidos quando eles são neces-sários, e quando memorandos, notas de reunião e especificações de interface são suficientes, o tempo não é perdido escre-vendo documentos de desenho formais.” “Quando são necessários” pode ser:•Ao iniciar um novo produto;•Quando membros da equipe são no-

vos na companhia de uma maneira ou de outra;•Quando o desenho é complexo;•Quando há muitos desenvolvedores

no projeto para que seja possível asse-gurar comunicação apropriada de outra

maneira [...].Para os propósitos de manutenção de

expansão depois da entrega do software, a melhor resposta é ter código auto-do-cumentante e gerar quaisquer documen-tações suplementares automaticamente a partir do próprio código.”

MSF 1.0 [1993]Isso é semelhante à recomendação do

Robert Martin no tocante à documentação para projetos Ágeis: “Não produza nenhu-ma documentação a não ser que a necessi-dade seja imediata e significante.”

(Martin [2002])MSF valoriza colaboração com o clien-

te ao invés de negociação de contrato. Negociação de contratos é essencialmente algo que se faz ao desenvolver software customizado. Para um mercado de massa, isso não é possível, portanto Microsoft teve de desenvolver as habilidades ne-cessárias para ser bem sucedida. Isso significa obter muito feedback dos clientes para fazer um produto atraente para milhões de pessoas.

O sucesso da Microsoft em usar princípios de HCI (Human Computer Interaction) para preencher as necessidades de usabilidade, associados a uma estrutura de equipe de-terminada em função de atender a critérios de qualidade de satisfação do cliente, mos-tram que seu processo de desenvolvimento é voltado ao cliente, e que a colaboração com estes é utilizada intensivamente.

Por exemplo, a MSF determina que tanto os papéis Educação do Usuário e Gerência de Produto sejam representados em uma equipe (esse último preferencialmente por um usuário). Também determina que todos os outros papéis sejam mapeados para ob-jetivos de qualidade do ponto de vista do cliente. Isso transparece na MSF como um enfoque forte na satisfação do cliente.

Jim McCarthy foi até poético sobre isso:“Seu relacionamento com o cliente é

como uma dança ou romance. Você dá alguns passos (suas entregas e mensa-gens), e eles dão passos em resposta, e então você dá mais passos. Você deve estar focado no fluxo de transações, no padrão e direção totais, não somente na última transação.

Tudo isso é parte de se ter uma estraté-gia de tecnologia de múltiplas entregas [...]. Se seus clientes sabem (ou sentem) que você vai ser pontual nas entregas,

que eles estão em uma viagem tecno-cro-nológica com você, que você e eles estão indo a algum lugar juntos, as expectativas deles vão ficar mais ajustadas.”

Idem, página 76.MSF valoriza responder à mudança

ao invés de seguir um planejamento. Além do conceito de Entrega em Versões e desenho iterativo como maneiras de lidar com mudanças de escopo, a filoso-fia de planejamento da MSF mostra sua adaptabilidade:

“Planejamento através da construção: Um dos objetivos implícitos da MSF é ajudar organizações a criar uma conexão entre o processo de planejamento e o de construção. Ao construir, uma empresa ganha experiência tecnológica assim como um melhor entendimento de como a em-presa está posicionada para absorver e dar suporte à tecnologia. O processo é iterativo: os processos de planejamento e construção são ambos candidatos para aperfeiçoamen-to contínuo. Quer dizer, cada um contribui ao refinamento do outro.”

MSF 1.0 [1993]

Conclusão A MSF original poderia ter sido incluída

como parte do Manifesto Ágil em 2001. Na época eu era gerente em uma dotcom, e usei MSF (combinado com FDD) em de-zenas de projetos em que era obrigatório ser ágil. De fato, na época fiquei surpreso que alguém da Microsoft não estivesse entre os participantes da reunião.

Somente mais tarde entendi que a MSF não tinha ninguém que fizesse na época parte do “colégio invisível” da comunidade Ágil (Invisible College: grupo informal de pesqui-sadores de um assunto - Price [1963]).

Do mesmo modo, também não foram convidados Mikio Aoyama, que já em 1997 havia criado seu Agile Software Pro-cess (Aoyama [1997]), e outros como Ian Graham com seu SOMA.

Page 60: dotNET42-Final.pdf

60 .NET Magazine - Dicas de GridView Edição 42 - .NET Magazine 61

Dicas de GridView

Luciano Pimenta([email protected])

é Técnico em Processamento de Dados, Editor Técnico da Revista ClubeDelphi, .net Maga-zine e WebMobile. Editor de vídeo aulas do Portal DevMedia (www.devmedia.com.br). Palestrante da 4ª edição da Borland Conference (BorCon).

Desde a minha primeira experi-ência com o ASP.NET, um dos controles que mais utilizei foi

o Grid, pela sua facilidade em mostrar os dados no formato de tabela. Primei-ramente, usei o DataGrid da versão 1.x do .NET Framework e agora o GridView para o .NET 2.0.

A primeira idéia de quem começa com ASP.NET é fazer aplicações Web iguais a aplicações Desktop, mas claro nem tudo é possível. Especificamente, em relação ao Grid, adicionar imagens, controles e formatações de acordo com determinado campo, são as primeiras funcionalidades que desejamos.

O DataGrid é muito customizável, mas o GridView trouxe muito mais facilidades ao desenvolvedor, como inserção, atua-lização, exclusão e seleção de dados, de forma muito simples.

Neste artigo, veremos algumas dicas úteis para a utilização desse controle para customizá-lo em suas aplicações Web.

Adicionando controlesA funcionalidade de templates do ASP.

NET ajuda em muito a customização do GridView para a adição de controles. Basta criar um coluna do controle do tipo TemplateField e adicionar os controles necessários.

Neste exemplo, vamos trabalhar com o CheckBox, onde simularemos um Web-Mail. Para quem está acostumado a usar WebMail, sabe que os e-mails aparecem em um Grid, onde podemos selecioná-los, exclui-los entre outras funcionalidades.

Crie uma nova aplicação Web no Vi-sual Studio 2005, com suporte ao AJAX (Figura 1).

Usaremos AJAX para que algumas dicas fiquem de fácil entendimento, já que não teremos refresh total da página. Na página Default.aspx adicione um UpdatePanel e dentro dele um GridView.

Não vamos no concentrar em conexões com o banco ou formatações do Grid-View. Temos ótimos artigos publicados,

Page 61: dotNET42-Final.pdf

60 .NET Magazine - Dicas de GridView Edição 42 - .NET Magazine 61

MÃo Na Massa

mostrando essas características, bem como temos vídeos aulas no Portal do Assinante.

Formate o GridView na opção que dese-jar e conecte ao banco de dados Northwind que acompanha o SQL Server. Você pode usar outro banco de sua preferência. Para este exemplo, use os dados da tabela Cus-tomer (selecione apenas alguns campos).

Deixe o controle com a opção de pagi-nação ativada (propriedade AllowPaging). Acesse a propriedade Columns do Grid-View, adicione um campo do tipo Templa-teField e clique em OK (Figura 2).

Acesse a Smart Tag do GridView e clique na opção Edit Templates. Na seção Ite-mTemplate, adicione um CheckBox. Feche o editor, rode a aplicação e veja os Check-Boxes adicionados ao GridView.

A primeira funcionalidade que usare-mos é saber que linhas foram “seleciona-das” com o CheckBox. Adicione um botão e um TextBox na página. No Click do botão adicione o código da Listagem 1.

O código está comentado para um fácil entendimento. O que fizemos foi criar uma variável do tipo StringBuilder (já adicionando um texto inicial), percorrer todas as linhas do GridView e procurar o controle CheckBox que adicionamos via template, com o FindControl.

Esse método retorna um Control, então fi-zemos um type cast para um CheckBox. Vale salientar que o parâmetro do FindControl é o nome do controle e o mesmo deve ser digitado corretamente, claro.

Se o controle não for nulo (foi encontrado) e estiver marcado (Checked), então adiciona-mos na sb os valores das colunas 1 e 2.

Nota: As colunas do GridView começam

com 0, sendo que a do TemplateField é

contada também.

Rode a aplicação, marque alguns Che-ckBoxes e clique no botão. Como mostra a Figura 3, o TextBox exibe as linhas “selecionadas”.

Como estamos usando AJAX, não temos refresh total da página. Ótima dica, mas para ficar melhor, que tal colocar um CheckBox no cabeçalho da coluna e ao marca-lo, todos os controles das linhas fossem marcados?

Abra o Template do GridView e na Smart Tag, altere para HeaderTemplate na opção

Figura 1. Criando o projeto Web com suporte ao AJAX

Figura 2. Adicionando um TemplateField no GridView

Listagem 1. Obtendo a linha com o CheckBox marcado

using System.Text;...protected void Button1_Click(object sender, EventArgs e){ //cria um StringBuilder StringBuilder sb = new StringBuilder(“* Itens Selecionados *”); //percorre todas as linhas (rows) do GridView foreach (GridViewRow row in GridView1.Rows) { //”procura” pelo CheckBox CheckBox ch = (CheckBox)row.FindControl(“CheckBox1”);

//se achou e está marcado if ((ch != null) && (ch.Checked)) { //adiciona na var sb os campos do GridView sb.AppendLine(); sb.Append(row.Cells[1].Text + “ - “ + row.Cells[2].Text); } }

//repassa para o TextBox a sb TextBox1.Text = “”; TextBox1.Text = sb.ToString();}

Page 62: dotNET42-Final.pdf

62 .NET Magazine - Dicas de GridView Edição 42 - .NET Magazine 63

Figura 3. Obtendo os CheckBoxes marcados

Listagem 2. Marcando/desmarcando os CheckBoxes

//percorre todas as linhas (rows) do GridViewforeach (GridViewRow row in GridView1.Rows){ //procura pelo CheckBox CheckBox ch = (CheckBox)row.FindControl(“CheckBox1”); //se achou if (ch != null) { //repassa para o CheckBox das linhas, o mesmo valor do CheckBox2 ch.Checked = (sender as CheckBox).Checked; }}

Listagem 3. Alterando a fonte da linha marcada

using System.Drawing;...

//percorre todas as linhas (rows) do GridViewforeach (GridViewRow row in GridView1.Rows){

//procura pelo CheckBox CheckBox ch = (CheckBox)row.FindControl(“CheckBox1”);

//se achou if (ch != null) { if (ch.Checked) { //formata o tamanho, negrito e cor row.Font.Size = 14; row.Font.Bold = true; row.ForeColor = Color.Red; } else { //volta ao padrão row.Font.Size = 12; row.Font.Bold = false; row.ForeColor = Color.Black; } }}

Display. Adicione outro CheckBox, altere a propriedade AutoPostBack do controle para True, pois sem ela, o código adicio-nado no evento CheckedChanged não seria executado.

Dê um duplo clique no controle e no evento adicione o código da Listagem 2.

O código é praticamente igual ao anterior, apenas verificamos se a variável ch não está nula e repassamos para a mesma o valor da propriedade Checked do controle que adicionamos no cabeçalho da coluna.

Rode e faça o teste. E se ao clicar no CheckBox de uma linha eu quisesse alte-rar a fonte da linha? Também fica muito simples. Acesse o template do GridView para o CheckBox das linhas, alterando a propriedade AutoPostBack do mesmo para True. Dê um duplo clique no controle e adicione o código da Listagem 3.

O código continua semelhante aos exemplos anteriores. Verificamos se a variável ch não é nula e depois se foi mar-cada. Se positivo, alteramos as configura-ções da fonte da linha. Senão, voltamos às configurações normais.

O código do else vai variar de acordo com as formatações do seu GridView. Rode a aplicação e teste (Figura 4).

A funcionalidade de adicionar controles no GridView é semelhante para outros tipos de controles. Você pode tomar por base essas dicas para adicionar um Dro-pDownList, por exemplo.

Master/DetailCrie uma nova página e adicione dois

GridViews. Para o primeiro, crie uma co-nexão com a tabela Orders do Northwind. Para o segundo GridView acesse os dados da tabela Order Details.

Na tela do wizard onde você escolhe os campos, após escolher os mesmos, clique no botão Where. Na tela que abrir, em Column escolha OrderID, em Source selecione Control e em ControlID escolha GridView1 (Figura 5).

Clique em Add para adicionar o parâme-tro. Note que o valor do parâmetro será a propriedade SelectedValue do GridView1.

Acesse agora o mesmo o Portal .net Plus e assista a uma vídeo aula de Luciano

Pimenta, que mostra como adicionar um DropDownList no GridView.

www.devmedia.com.br/articles/listcomp.asp?comp=2035

www.devmedia.com.br/msdn/portal.asp

Page 63: dotNET42-Final.pdf

62 .NET Magazine - Dicas de GridView Edição 42 - .NET Magazine 63

MÃo Na Massa

Figura 4. Alterando a fonte da linha marcada

Figura 5. Configurando os parâmetros da consulta

Figura 6. Master/Detail com dois GridViews

Finalize o wizard e no GridView1 acesse a Smart Tag, marcando a opção Enable Selection.

Rode a aplicação, selecione uma linha do GridView1 e veja que o GridView2 será preenchido com os dados referente aos itens da tabela pai (Order) (Figura 6). Neste exemplo, eu configurei a consulta do GridView2 para que trouxesse o nome do produto.

Master/detail com TemplatesMas se eu quiser que os itens (no caso

os details) sejam mostrados sem que o usuário clique na linha do GridView1? Para isso usaremos templates no GridView master.

Crie uma nova página e adicione um GridView, adicionando os dados da ta-bela Orders. Acesse o editor de colunas do controle e remova todos os campos, adicionando apenas um do tipo Template-Field. Acesse as configurações do template e adicione uma tabela com duas linhas e três colunas.

Na linha superior, adicione o rótulo dos campos (digite ou coloque Labels), e na linha inferior, adicione três Labels. Para as Labels vamos usar a técnica de DataBind para mostrar os valores dos campos.

Acesse a Smart Tag do primeiro Label e acesse a opção Edit Databindings. Na janela que abrir, configure o campo no item Bound to (Figura 7).

Faça o mesmo para os outros campos. Abaixo da tabela, adicione um GridView e configure para acessar os dados da tabela Orders Details e configure um parâmetro igual ao exemplo anterior, só que ao invés de escolher o GridView1, você escolherá o Label1 (referente ao campo OrderID).

Finalize o wizard e rode a aplicação. Veja na Figura 8 que estamos visualizando os dados da master (Orders) e em seguida a detail (Order Details).

Trabalhando com imagensMostrar imagens no GridView é simples.

Por exemplo, para mostrar imagens nos comandos de seleção, exclusão, atualiza-ção e edição, basta configurar proprieda-des no editor de colunas.

Indique a imagem que deseja na pro-priedade XXImageURL, onde o XX indica o tipo de comando (Cancel, Delete, Insert, Update). Por último altere ButtonType

Page 64: dotNET42-Final.pdf

64 .NET Magazine - Dicas de GridView Edição 42 - .NET Magazine 65

para Image. Veja na Figura 9 um exemplo dessas imagens.

Mas e se eu tenho imagens salvas na pas-ta da aplicação e na tabela do banco tenho apenas o nome dela, como mostrar?

Vamos imaginar que tenhamos uma pasta no diretório da aplicação, chamada imagens e dentro dela os arquivos cadas-trados no banco. Ao conectar a tabela, trazemos todos os campos da mesma.

No campo que guarda o nome da ima-gem, você deve abrir o editor de colunas e configurar a propriedade DataFormatS-tring para “<img src=imagens/{0}>”.

Rode a aplicação e veja as imagens sen-do mostradas no GridView (Figura 10).

Imagens de acordo com determinada condição

Em uma tabela de clientes, certamente possuimos um campo indicador do sexo. Que tal mostrar no GridView a listagem dos clientes e de acordo com o sexo mos-trar uma imagem diferente?

Bem, criei uma tabela de clientes, onde existe um campo chamado SEXO, sal-vando, obviamente as opções “M” ou “F”. Para este exemplo, vou me basear no ótimo artigo de Eduardo Henrique Rizo publicado na edição 33. Adicione o código da Listagem 4 na página.

O código anterior retorna o nome do arquivo, salvo na pasta imagens de acordo com o valor passado como parâmetro. No editor de colunas do GridView, para o campo SEXO, transforme-o em um TemplateField.

Acesse o editor de templates e adicione um Image. Acesse a Smart Tag e escolha a opção Edit DataBindings. Na tela, escolha Custom binding e digite: “GetImagem(Convert.ToString(Eval("SEXO")))”.

Com esse código, fizemos o Bind na propriedade ImageURL do controle, que passará o valor do campo SEXO através do Eval(“SEXO”). Feche o editor, rode a aplica-ção e veja as imagens sendo mostradas de acordo com o sexo do cliente (Figura 11).

ValidaçõesPodemos usar os controles de validação

normalmente na edição/inserção de va-lores no GridView. Novamente, faremos uso de Templates. Conecte a uma tabela do banco e escolha uma formatação para o GridView.

Figura 8. Master/detail usando templatesFigura 8. Master/detail usando templates

Figura 7. DataBinding de controles no TemplateFieldFigura 7. DataBinding de controles no TemplateField

Figura 9. Colocado imagens nos comandos do GridView

Page 65: dotNET42-Final.pdf

64 .NET Magazine - Dicas de GridView Edição 42 - .NET Magazine 65

MÃo Na Massa

Listagem 4. Criando um método que retorne o nome do arquivo

protected string GetImagem (string aSexo){ string ret = “”; if (aSexo == “M”) ret = “~/imagens/M.bmp”; else if (aSexo == “F”) ret = “~/imagens/F.bmp”; return ret;}

Listagem 5. Colocando um somatório no rodapé

if (e.Row.RowType == DataControlRowType.Footer){ PRODUTOSTableAdapter prod = new PRODUTOSTableAdapter(); e.Row.Cells[0].Text = “Quant: “ + Convert.ToString(prod.GetTotal());}

Figura 10. Mostrando imagens da aplicação no GridView Figura 11. Mostrando imagens de acordo com o valor do campo SEXO

Transforme os campos que deseja colo-car as validações, como templates. Acesse o editor de templates e escolha o item EditIte-mTemplate na opção Display (Figura 12).

Será mostrado o TextBox quando o usuá-rio escolher a opção de inserção ou edição da linha. Adicione um RequiredFieldVa-lidator e aponte o ControlToValidate para o TextBox, e digite a mensagem de erro em ErrorMessage. Feche o editor e rode a aplicação (Figura 13).

Somatório no rodapéSe o GridView possui um campo com

valores numéricos ou monetários, certa-mente você gostaria de mostrar um total no rodapé da página. Primeiramente, altere para True a propriedade ShowFooter do GridView.

Neste exemplo, criei um DataSet tipado e um método que retorna a quantidade de itens da tabela, mas você pode adaptar facilmente a sua necessidade (sem o uso de TableAdapter).

Após, acesse o evento RowDataBound e adicione o código da Listagem 5.

GetTotal é uma query criada no Table-Adapter que retorna a quantidade de registros da tabela. Primeiramente, verifi-camos se estamos no rodapé do GridView através da propriedade RowType. Assim, colocamos na primeira coluna, um texto e a quantidade (Figura 14).

AgrupamentoPara fazer um agrupamento, usaremos a

mesma técnica já bastante mostrada neste artigo, templates. Será muito semelhante ao exemplo de master/detail usando templates. Para este exemplo, conectare-mos o GridView à tabela Categories do Northwind.

Deixe apenas um campo e transforme-o

Page 66: dotNET42-Final.pdf

66 .NET Magazine - Dicas de GridView

em TemplateField no editor de colunas. Adicione um outro GridView no editor de templates e configure para a tabela Pro-ducts, mas que mostre apenas os produtos de uma categoria específica. Nesse caso será um Label que você pode adicionar no editor de templates.

Depois basta rodar a aplicação e visu-alizar o agrupamento (Figura 15). Qual-quer dúvida, consulte o projeto que está para download (neste exemplo, removi o cabeçalho das colunas do GridView dos produtos).

ConclusãoVimos neste artigo algumas dicas para a

utilização do GridView, um dos controles mais utilizados em aplicações ASP.NET no Visual Studio 2005. Também sugiro a leitura do artigo de Rodrigo Sendin publicado na edição 41, que mostra con-figurações avançadas do controle.

Para quem quiser avançar, que tal colo-car todas essas dicas em prática, exten-dendo o controle padrão para um Grid-View turbinado. Fica aí a dica! Um grande abraço a todos e até a próxima!

Figura 13. Validando os campos no GridView

Figura 14. Mostrando o somatório no GridView

Figura 15. Agrupamento com dois GridViews

Figura 12. Opções do Template

A edição que você precisa

está esgotada?

Seus problemas acabaram!!!

Com a assinatura Gold você já pode consultar onlinetodos os artigos publicados na sua revista desde a edição nº 1.

Seja um assinante Gold!

Assinatura

Goldwww.devmedia.com.br/assgold

Saiba Mais! Acesse:

Para mais informações: www.devmedia.com.br/central

Atenção: Já encontram-se disponíveis as assinaturas GOLD das revistas WebMobile e .net Magazine.

Page 67: dotNET42-Final.pdf

O Evento do desenvolvedor

Web e Wireless

31 de Agosto e 01 de Setembro em São Paulo / SP

Palestras 100% técnicas!Garanta sua participação e conheça o que as tecnologias Java e .net trazem de melhor para este mercado!

Confira abaixo a Grade de Palestras:Realização:

9:00-10:20

10:30-11:50

12:00-13:20

13:30-14-50

15:00-16:20

16:20-17:00

17:00-18:20

18:30-19:50

20:00-21:20

Mini Curso 1 - Java ME Primeiros Passos – Parte 1

Mini Curso 1 - Java ME Primeiros Passos – Parte 2

Almoço

Mercado de Jogos para Celulares

Mini Curso 2 – Conectividade em Java ME - Do básico ao avançado– Parte 1

Otimização de Aplicações Java ME

Utilizando SVG (Scalable VectorGraphics) com Java ME

BREAK

Mini Curso 2 – Conectividade em Java ME - Do básico ao avançado– Parte 2

1º dia - 31 de Agosto

Interfaces ricas na Web com Ajax – Parte 1

Interfaces ricas na Web comAjax – Parte 2

Almoço

Interfaces ricas para a Web com Flex 2.0 e Java

Struts2 - A Evolução do framework

Struts2 - Desenvolvendo uma aplicação com ajax e validaçãoParte 2

Relatorios Web

BREAK

Struts2 - Desenvolvendo uma aplicação com ajax e validaçãoParte 1

WEB 2.0: Conceitos e Tecnologias

Padrões de Projeto Java EE – Parte 1

Almoço

Padrões de Projeto Java EE – Parte 2

JavaFX: interfaces em Java de forma fácil e portável – Parte 1

Além do básico: explorando APIs sofisticadas com Java ME nas plataformas Nokia – Parte 1

Além do básico: explorando APIs sofisticadas com Java ME nas plataformas Nokia – Parte 2

BREAK

JavaFX: interfaces em Java de forma fácil e portável – Parte 2

Linq - veja na prática os fundamentos deste projeto.

Introdução ao ASP.NET AJAX

Almoço

Desenvolvendo Gadgets Corporativos para Windows Vista

Introdução ao Silverlight

Construa uma aplicação 100% OO com ASP.NET - Parte 1

Construa uma aplicação 100% OO com ASP.NET - Parte 2

BREAK

.net 3.0 - Xaml Browser Apllications

Desenvolvimento para dispositivos móveis na plataforma .NET 2.0 - Parte 1

Desenvolvimento para dispositivos móveis na plataforma .NET 2.0 - Parte 2

Almoço

Novidades no Windows Mobile 6

Acionamento de dispositivos eletro-mecanicos com Pocket PC

Desenvolvendo programa para PocketPC com rede sem fio e WebServices - Parte 2

Criando aplicações WAP com ASP.NET

BREAK

Desenvolvendo programa para PocketPC com rede sem fio e WebServices - Parte 1

Ciclo de vida de desenvolvimento com VSTS

Mini-curso de C# - Parte 1

Almoço

Mini-curso de C# - Parte 2

ASP.NET Caching

BREAK

Criação de um portal com ASP.NET 2.0 e WebParts

Aprenda na prática a criar um sistema de enquetes em ASP.NET - Parte 1

Aprenda na prática a criar um sistema de enquetes em ASP.NET - Parte 2

Sala 1 Sala 2 Sala 3

Salas de Java

Sala 1 Sala 2 Sala 3

Salas de .NET

9:00-10:20

10:30-11:50

12:00-13:20

13:30-14-50

15:00-16:20

16:20-17:00

17:00-18:20

18:30-19:50

2º dia - 01 de Setembro

Sala 1 Sala 2 Sala 3 Sala 1 Sala 2 Sala 3

Implementando uma loja virtual em Java EE 5 com JPA e EJB3 – Parte 1

Implementando uma loja virtual em Java EE 5 com JPA e EJB3 – Parte 2

Almoço

Implementando uma loja virtual em Java EE 5 utilizando JSF para a interface com o usuário.- Parte 1

Implementando uma loja virtual em Java EE 5 utilizando JSF para a interface com o usuário.- Parte 2

BREAK

Desenvolvendo aplicações Web com o Spring Framework – Parte 1

Desenvolvendo aplicações Web com o Spring Framework – Parte 2

Google Web Toolkit passo-a-passo – Parte 1

Google Web Toolkit passo-a-passo – Parte 2

Almoço

Planejamento e Execução de Testes em Aplicações Web – Parte 1

Planejamento e Execução de Testes em Aplicações Web – Parte 2

Desenvolvendo e implantando uma força de vendas em Palm – Parte 2

BREAK

Desenvolvendo e implantando uma força de vendas em Palm – Parte 1

1º dia - 31 de Agosto

2º dia - 01 de Setembro

Net Framework 3.0 - Conheça o WPF e surpreenda-se

Aplicações com ASP.NET 2.0 e AJAX - Parte 1

Almoço

AJAX Control Toolkit

Aplicações com ASP.NET 2.0 e AJAX - Parte 2

XAML

BREAK

Silverlight na prática

Otimizando aplicações em Windows Mobile 5.0

Construindo uma aplicação Mobile passo a passo com Visual Studio 2005

Almoço

Envio e recebimento de dados no Pocket usando FTP

Windows Mobile no Windows CE

SQL Server 2005 Compact Edition - Parte 2

BREAK

SQL Server 2005 Compact Edition - Parte 1

Aplicações Web para dispositivos móveis

Linq para Compact Framework

Almoço

ASP.NET 2.0 na prática: Profiles e Membership

WorkFlow Foundation no ASP.NET

Testes automatizados em aplicações ASP.NET

BREAK

Desenvolvimento WEB: Uma Abordagem Utilizando OO e Técnicas de Teste de Software

Desenvolvendo um Game em Java ME - Parte 1

Desenvolvendo um Game em Java ME - Parte 2

Almoço

Desenvolvendo um Game em Java ME - Parte 3

Introdução ao uso do bluetooth em J2ME

Java Wireless: O que nós precisamos saber sobre MIDP3?

BREAK

Multimídia em J2ME

Apoio:Patrocínio: Apoio Cultural:

Para mais informações acesse:www.devmedia.com.br/eventos/webmobiletechweek

Page 68: dotNET42-Final.pdf