Anda di halaman 1dari 45

Sumrio

Novidades, 06 Desenvolvendo um blog com ASP.NET


Minicurso [ Vladimir Rech ]

29 - Iniciando com Threads no C#


.Net

Boa Ideia
[ Everton Coimbra de Arajo e Giuvane Conti ]

Ol, eu sou o DevMan! Desta p-


gina em diante, eu estarei lhe aju-

.Net 37 Primeiros passos com o namespace System.IO dando a compreender com ainda
[ Fbio Rosa ] mais facilidade o contedo desta
edio. Ser um prazer contar com
sua companhia! Confira abaixo o
que teremos nesta revista:
Expediente Editorial

EDITORIAL

J
faz bastante tempo que a Web 2.0 foi lanada, mas, porque no pensarmos
que antes no existia uma forma de interagir com os visitantes? Atualmente,
sempre que visitamos uma pgina, pensamos logo em ir visualizar os coment-
rios da mesma. Um exemplo notrio de Web Site que utiliza recursos da Web 2.0 so
os Blogs. Desta forma, que tal aprender a criar um blog no ASP.NET? Vladimir Rech
mostra na prtica cada passo.
Alm desse tema, tambm temos outro assunto que sempre ser importante, exe-
Ano 3 - 25 Edio 2012 - ISSN 2179624-6 cutar tarefas na sua aplicao sem depender de outras. Um exemplo muito comum
quando sua aplicao trava quando voc gera um relatrio no sistema (vendas do
ms, por exemplo). Neste caso, por que no colocar este relatrio em uma Thread?
esse o objetivo do artigo Iniciando com Threads no C#.
Para finalizar, temos o artigo do Fbio Rosa, que demonstra na prtica como trabalhar
Corpo Editorial
com diretrios e arquivos utilizando a biblioteca System.IO do .NET Framework. Seja
ASP.NET ou Windows Forms, a manipulao dos mesmos sempre ser necessrio.

Um grande abrao e uma excelente leitura!


Editor Geral
Rafael Silva (rafael@rlsystem.com.br)

Jornalista Responsvel
Kaline Dolabella - JP24185

Na Web
www.devmedia.com.br/revista-easy-dotnet-magazine
Rafael Silva
rafael@rlsystem.com.br
Editor Chefe da .net Magazine e Easy .net Magazine
http://www.rlsystem.com.br
Atendimento ao Leitor
A DevMedia conta com um departamento exclusivo para o atendimento ao leitor. Se voc tiver algum
twitter.com/rafaellealsilva
problema no recebimento do seu exemplar ou precisar de algum esclarecimento sobre assinaturas,
exemplares anteriores, endereo de bancas de jornal, entre outros, entre em contato com:

www.devmedia.com.br/central
(21) 3382-5038
Fale com o Editor!
muito importante para a equipe saber o que voc est achando da revista: que tipo de artigo voc
Publicidade 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 sugesto!
Para informaes sobre veiculao de anncio na revista ou no site e para fechar parcerias ou aes
especficas de marketing com a DevMedia, entre em contato com: Se voc estiver interessado em publicar um artigo na revista ou no site .NET Magazine, entre em
contato com os editores, informando o ttulo e mini-resumo do tema que voc gostaria de publicar:
Cristiany Queiroz
publicidade@devmedia.com.br Rafael Silva - Editor da Revista
rafael@rlsystem.com.br

Assine agora e tenha acesso a


todo o contedo da DevMedia:
www.devmedia.com.br/mvp
Seo .Net Nesta seo voc encontra artigos bsicos sobre as tecnologias .net

Desenvolvendo um
blog com ASP.NET
Parte 1
Este artigo faz parte de um curso Resumo DevMan
De que se trata o artigo:

A
t a chegada do Framework .NET, o desen- Este artigo trata dos recursos nativos no ASP.NET (como gridview, Da-
volvimento de aplicaes Web baseava-se em taGrid, etc) para a criao de aplicaes Web utilizando os recursos de
projetos desenvolvidos em plataformas como Web Forms. A ideia bsica criar um sistema de blog.
PHP ou ASP clssico, onde a interface era criada usando
editores HTML e o cdigo da regra de negcios escrito Em que situao o tema til:
juntamente com a interface. O tema til para os desenvolvedores conhecerem os principais
O problema principal no desenvolvimento Web no a recursos nativos que existem na plataforma .NET, como os controles
separao entre interface de usurio e regras de negcio, de WebForms: TextBox, GridView etc. Desta forma, ser possvel criar
mas entender os detalhes que envolvem o gerenciamento qualquer tipo de aplicao Web.
de uma aplicao baseada numa arquitetura cliente-
servidor. Um destes detalhes baseia-se no fato de que Desenvolvendo um blog com ASP.NET Parte 1:
do lado do cliente (usurio da aplicao) existe pouco Desenvolver aplicaes ASP.NET usando Web Forms a maneira mais
ou nenhum controle do que est acontecendo e assim, prtica de criar projetos que sero executados em browsers, visto que
torna-se necessrio gerenciar o estado da pgina para atravs do mesmo voc possui um conjunto de controles prontos para
poder enviar os dados corretos. Considere tambm a serem utilizados, gerando uma grande produtividade. Para poder explorar
grande diversidade de browsers existentes e que cada os recursos do ASP.NET, este artigo vai considerar a utilizao dos mesmos
um possui particularidades na renderizao do HTML, em um projeto para gerenciar blogs de vrios usurios.
comportamento do JavaScript etc. Nestes blogs, o usurio poder enviar suas publicaes "baseadas
Parte destes problemas (no .NET) so resolvidos de em texto puro para simplificar algumas tarefas" alm de gerenciar os
maneira bem simples, atravs de server controls, que dados do blog.
so componentes que podem ser destinados a montar
uma interface com o usurio, tais como TextBox, Labels,
Combo Box entre outros, alm de controles no visuais e, rapidamente comearam a aparecer pginas muito pesadas que
destinados a realizar tarefas de validaes, por exemplo. tentavam recriar nos browsers o mesmo ambiente de aplicaes
Todos estes componentes podem ser facilmente mani- desktop. Isso um erro, porque o browser um ambiente distinto
pulados atravs das caixas de ferramentas do Visual do desktop, os recursos so limitados e, ainda que seja possvel
Studio e do editor de propriedades. construir interfaces com um layout rico, certos cuidados precisam
Um dos aspectos mais importantes e tambm mais cri- ser tomados, como evitar a utilizao excessiva de controles, com-
ticados do ASP.NET o recurso de criao de Web Forms. ponentes desnecessrios e validaes interminveis.
Este consiste de server controls aninhados em uma tag Considerando ainda o ASP.NET, a sua principal vantagem que
<form>, ou seja, voc pode fazer o design de um Web possvel definir a interface com o usurio utilizando um arquivo
Form como faria em uma aplicao Windows Forms, dada ASPX que possui marcaes HTML para os server controls, tags
a sua facilidade de manipulao. Mas, muitos excessos so HTML, alm de suporte a JavaScript e CSS. Alm disso, utiliza
cometidos por alguns desenvolvedores menos preparados um arquivo separado para escrever o cdigo C# (ou VB.NET)

6 Easy .Net Magazine Edio 25


vinculado com a pgina. Esta forma de organizar o cdigo cha- Por outro lado, embora a utilizao do editor visual permita um
mada de code behind e d amplo suporte para escrever eventos rpido desenvolvimento da pgina com a verificao imediata do
em resposta a iteraes do usurio com os controles. resultado, o cdigo HTML gerado tem a tendncia de ser mais car-
regado, com elementos desnecessrios e de difcil manuteno.
Componentes ASP.NET O que se pode fazer usar uma combinao do melhor dos
Quando se est desenvolvendo projetos com ASP.NET, alm dois mundos. Assim, para criar pginas em branco, com layout
das facilidades do designer e do code behind, o desenvolvedor mais simplificado, onde somente elementos mais bsicos sero
tambm tem sua mo uma variedade grande de controles de inseridos, tem-se relativa facilidade com esta linguagem, usando
servidor que simplificam algumas tarefas. o editor HTML.
Estes controles podem ser arrastados para o designer e ter suas Utilizar diretamente a edio do cdigo possui muitas vanta-
propriedades configuradas pelo editor de propriedades do Visual gens entre as quais, podemos citar o recurso de Code Completion
Studio. Mas, uma das principais caractersticas que executam (IntelliSense) que na verso 2010 do Visual Studio est muito bem
tarefas importantes, simplificando nosso trabalho. Veja alguns resolvida. A Figura 1 mostra este recurso em ao.
grupos de controles:
1. Componentes para editar e exibir dados: envolve controles
onde os dados so editados ou visualizados. Entre os controles
mais comuns esto TextBox, Label, GridView, FormView, Radio
Button, CheckBox, alm de outros das mesmas categorias.
2. Componentes navegacionais: compem elementos para cons-
truir itens de navegao pela aplicao dando suporte a contedo
esttico e dinmico. Seu contedo pode estar baseado no banco
de dados ou em arquivos de configurao XML do projeto. Estes
controles envolvem menus, TreeViews e Site Map Path.
3. Componentes para validao dos dados: estes permitem ve-
rificar os dados que foram editados nos controles e testar a sua
validade tanto no lado do cliente (executando cdigo JavaScript
gerado automaticamente) como do lado do servidor. Estes valida-
dores so executados assim que uma ao HttpPost disparada.
Esta ao tipicamente executada quando um usurio clica em
um boto para enviar os dados para o servidor, por exemplo.
4. Componentes para aperfeioamento da interface: permite
melhorar a experincia do usurio com a interface, evitando
Figura 1. IntelliSense do editor HTML em ao
round trips desnecessrios (envio de dados para o servidor com
o redesenho total da pgina) e tambm agilizando o comporta- J o editor visual permite editar algumas propriedades de
mento da interface. Os principais componentes desta categoria maneira mais simples em componentes mais complexos, como
so aqueles controles do grupo AJAX Extensions e Web Parts da o GridView, onde necessrio configurar vrias colunas que
caixa de ferramentas do Visual Studio. devero ser exibidas no mesmo. Neste caso, a utilizao do editor
visual facilita bastante, visto que voc possui um assistente para
Foram citados nestes grupos somente os controles nativos que criar as mesmas.
so fornecidos com uma instalao padro do Visual Studio e Mas, um dos recursos mais interessantes a possibilidade de ter
ferramentas de programao para o Framework .NET. Existem no uma janela exibindo tanto o cdigo HTML, como o design. Isto
mercado inmeros controles para esta plataforma, tanto gratuitos feito com o boto Split e a Figura 2 mostra esta janela em ao.
como pagos. Verifique no site oficial para a plataforma ASP.NET importante observar que a gerao do HTML para o browser
(seo Links) para conhecer alguns destes. em tempo de execuo feita pelo servidor, considerando o brow-
ser do cliente mais do que o cdigo que est na pgina, mas, est
Usando o Editor HTML ou o Designer claro que quanto mais enxuto o cdigo HTML for, melhor e mais
Uma dvida comum para quem est comeando ou aperfeio- gil vai ser a carregamento da pgina.
ando-se no desenvolvimento com ASP.NET se o correto usar o
editor visual ou manipular o cdigo HTML. Como sempre, exis- Usando JavaScript
tem aspectos positivos e negativos para as duas abordagens. Como foi dito anteriormente, o ASP.NET usa pginas e controles
O editor HTML deve ser utilizado para realizar ajustes mais do lado do servidor para gerar o contedo para o browser.
rpidos, como alterar o estilo CSS do fundo de algum controle Em alguns casos, possvel interagir com JavaScript e assim
ou at mesmo alterar seu ID. executar cdigos do lado do cliente da aplicao.

Edio 25 Easy .Net Magazine 7


Desenvolvendo um blog com ASP.NET Parte 1

avanada e vital para a execuo do programa depender de um Java


Script, pode ser que sua aplicao no funcione corretamente.

Validadores
Uma das boas prticas no desenvolvimento de qualquer tipo de
software que antes que os dados sejam persistidos no banco, estes
possam ser validados para evitar problemas, tais como:
1. Estouro de capacidade de armazenamento de campos em ta-
belas. Por exemplo, campos string (varchar no SQL Server) que
tenham tamanho menor do que o comprimento do texto que esteja
sendo enviado ir causar um erro na aplicao.
2. Os tipos de dados podem ser incompatveis. O usurio pode
ter digitado um valor errado em um campo numrico, uma data
no formato errado.
3. Dados mais complexos podem estar incorretos, tais como endere-
os de e-mail que precisam sempre respeitar um formato. O usurio
desavisado pode acabar enviando um endereo incorreto.
4. Validaes para manter regras da aplicao. Pode ser que no
Figura 2. Usando a visualizao Split do Visual Studio
seu projeto no possam haver nomes repetidos ou endereos de
e-mail repetidos, por exemplo.
Ao utilizar esses cdigos JavaScript, estes so executados sem
que seja necessrio o envio de dados para o servidor. Assim, em Estes tipos de verificao podem ser feitos de diversas maneiras,
casos com validaes ou interaes com o usurio, interessante tanto usando cdigo escrito com C# no code behind da aplicao
usar JavaScript. como em JavaScript.
Uma aplicao tpica pedir a confirmao de alguma ao, por O uso do cdigo escrito com C# apresenta a desvantagem de
exemplo, ao clicar em um boto para enviar dados para o servidor. exigir uma validao no servidor e, consequentemente, espera
Veja um exemplo de implementao a seguir, onde o cdigo do usurio nesta tarefa. J a utilizao do JavaScript pode tornar
de confirmao em JavaScript adicionado ao corpo de uma a validao insegura, visto que o usurio pode desativ-lo em
pgina ASPX. qualquer navegador. Na prtica, o ideal utilizar os dois, sim-
plesmente pelo fato que a utilizao do JavaScript permite que as
<html xmlns=http://www.w3.org/1999/xhtml> informaes sejam validadas sem a necessidade da pgina ir at
<head runat=server>
<title>BlogEngine - Gerenciador de Blogs</title> o servidor e, caso o usurio desative o Javascript, o mesmo seria
<script language=javascript> automaticamente validado pelo servidor, atravs do C#.
function confirmacao(msg) { return confirm(msg); }
Para contornar este problema, o ASP.NET disponibiliza um
</script>
</head> conjunto de controles chamado Validators, que podem ser encon-
trados no Visual Studio, na aba Validation (Figura 3). Alm disso,
Ou usando arquivos com a extenso .js contendo o cdigo os mesmos j implementam as validaes em JavaScript (Client)
JavaScript que deve ser usado em diversos pontos do projeto e C# (Server) automaticamente.
e ligando este arquivo s pginas ASPX na TAG <head>, como A Tabela 1 mostra uma descrio de cada validador.
neste outro exemplo: Este evento tipicamente executado quando um boto clica-
do. possvel tambm definir para cada boto um conjunto de
<html xmlns=http://www.w3.org/1999/xhtml> controles a serem validados e assim, validar somente os dados
<head runat=server>
<title>BlogEngine - Criao do Blog</title> necessrios para cada Send.
<script type=text/javascript src=scripts.js></script>
</head>
Entity Framework para acesso aos dados
Outro aspecto importante para o desenvolvimento com ASP.NET
A escolha da melhor opo vai depender de cada caso e de a sua grande conectividade com os bancos de dados. A partir da
cada aplicao, porm, como os arquivos scripts precisam ser verso 3.0 do Framework .NET foi introduzido o Entity Framework
enviados para o cliente junto com o contedo, a tendncia ter (EF) e a linguagem LINQ para manipulao de dados.
a carga cada vez mais lenta, conforme o tamanho deste arquivo Enquanto LINQ permite executar consultas no banco de dados
for crescendo. usando uma sintaxe bem prxima quela do C#, com o EF poss-
Por outro lado, bom observar que alguns browsers desabilitam vel mapear os dados armazenados em bancos de dados relacionais,
por padro a execuo de scripts. Assim, se alguma funo mais como o SQL Server, para classes e objetos.

8 Easy .Net Magazine Edio 25


Controle Descrio
Permite comparar o contedo de um controle com outro.
CompareValidator
Este validador deve ser usado quando for necessrio confirmar dados digitados pelo usurio em dois controles, tais como senhas.
Usa um cdigo no lado do servidor em C# para executar validaes mais complexas.
CustomValidator Uma aplicao tradicional deste componente quando for necessrio executar qualquer operao mais complexa para validao ou,
por exemplo, obter informaes do banco de dados para realizar a validao.
Usando tipos de dados definidos, onde possvel especificar uma faixa para a qual os dados do controle devero pertencer para
RangeValidator serem vlidos.
til quando uma data deve estar dentro de um determinado perodo, por exemplo.
Este validador usa expresses regulares para comparar o contedo de um controle.
RegularExpressionValidador As expresses regulares so cdigos escritos para representar padres para formatos de dados como datas, endereos da Internet e
de e-mail, por exemplo.
RequiredFieldValidator Faz com que o preenchimento do controle seja obrigatrio. A pgina vai ser considerada invlida at que o controle seja preenchido.

Tabela 1. Descrio dos componentes de validao

3. Refinar o comportamento do mapeamento dos dados para que


estes sejam carregados apenas no momento necessrio;
4. Dar suporte a vrios tipos de bancos de dados.

Figura 4. Exemplo de tabelas mapeadas com Entity Framework

Figura 3. Controles para validao

A ideia bsica do EF definir classes para cada tabela do banco Tutorial


de dados. Usando estas classes, as tradicionais operaes para con-
sultar, inserir, atualizar e excluir os dados no banco so executadas
atravs de mtodos sem que seja necessrio inserir instrues A aplicao de exemplo
em SQL no seu cdigo, embora, seja possvel personalizar estas Vamos por em prtica os conceitos que foram apresentados em
instrues em alguns casos. uma aplicao de exemplo e que ter as seguintes caractersticas:
A Figura 4 mostra um exemplo de mapeamento baseado em 1. Permitir a criao de um blog usando um nome e uma descrio
um banco de dados SQL Server. Observe sua semelhana com os de contedo.
diagramas de classe. 2. Cada blog vai ser gerenciado por um usurio que vai ter de
importante observar que com o EF possvel ainda realizar cadastrar seu nome, um e-mail e uma senha para gerenciar o
as seguintes operaes: blog.
1. Definir o banco de dados atravs do cdigo; 3. Somente ser permitida uma conta de e-mail por blog para
2. Realizar atualizaes no schema do banco de dados; simplificar o gerenciamento.

Edio 25 Easy .Net Magazine 9


Desenvolvendo um blog com ASP.NET Parte 1

4. O usurio informa o seu e-mail e senha para fazer o login. Se indicando que trata-se de uma foreign key (chave estrangeira)
o mesmo for bem sucedido, ele redirecionado para a pgina de atravs das letras fk e os nomes da tabela de origem e da
gerenciamento do blog. Caso no tenha xito, uma mensagem de chave estrangeira.
erro ser exibida.
5. Na pgina de abertura deve ser permitido alterar alguns dados Listagem 2. Criao da tabela posts
do blog como nome, descrio, conta de e-mail vinculado e incluir
novos posts. Tambm ser possvel criar um novo blog usando create table posts
(
um link que redireciona o usurio para uma pgina de cadastro id int identity(1,1) not null,
de seus dados. id_blog int not null,
6. Um novo post deve conter o ttulo, o subttulo, as palavras chave post_title varchar(100) not null,
post_subtitle varchar(100) null,
separadas por espao, e o contedo do blog, inicialmente apenas date_created datetime not null default(getdate()),
texto. content varchar(5000),
keywords varchar(1000) null,
primary key (id)
Nesta fase do projeto sero usadas as seguintes tecnologias do )
Framework .NET: go
1. ASP.NET;
alter table posts
2. Acesso aos objetos do banco de dados usando Entity add constraint fk_posts_blogs
Framework; foreign key (id_blog)
references blogs (id)
3. Integrao ASP + JavaScript. go
4. O banco de dados a ser usado ser o SQL Server.
alter table posts
check constraint fk_posts_blogs
Definio do banco de dados go
O banco de dados ter inicialmente duas tabelas, uma para
armazenar os dados dos blogs e os seus gerenciadores e outra
para os posts. Criao do projeto
O banco foi denominado de BlogEngine. A Listagem 1 demons- O projeto foi criado usando o Visual Studio 2010, o Framework 4.0
tra o script para a gerao da tabela blogs que armazena os blogs e o template ASP.NET Empty Web Application. Este template
e os dados dos seus administradores. cria um projeto vazio, sem nenhuma pgina ou cdigo sendo
gerado automaticamente pelo Visual Studio. A Figura 5 mostra
a janela de criao do projeto que acessada pelo menu File >
Listagem 1. Script para a criao da tabela Blogs
New Project.
create table blogs
(
id int identity(1,1) not null,
name varchar(50) not null unique,
password varchar(50) not null,
description varchar(1000) not null,
date_created datetime not null default(getdate()),
admin_name varchar(100) not null,
admin_mail varchar(100) not null,
primary key (id)
)
go

Este script cria a tabela com os seus campos e define tambm a


chave primria para o campo id.
A utilizao da clusula default na linha que cria o campo
date_created permite definir um valor padro para cada registro Figura 5. Criando o projeto Web
novo da tabela.
O script da tabela posts est na Listagem 2. Definindo o acesso ao banco de dados
Neste script, alm da criao da tabela, ser criado tambm o A primeira tarefa a ser realizada dentro do projeto criar a
relacionamento com a tabela blogs, atravs do campo id_blog, estrutura para acessar o banco de dados. Neste exemplo optei
utilizando a instruo alter table posts add constraint.... pelo Entity Framework porque pode ser usada a linguagem LINQ
O nome da constraint pode ser qualquer um, mas no script para integrar consultas ao banco com a linguagem C# e tambm
foi usado fk_ posts_blogs, para facilitar sua identificao porque os dados so mapeados para classes.

10 Easy .Net Magazine Edio 25


Existem muitas maneiras de fazer o ma-
peamento. Neste exemplo, vou partir do
pressuposto que o banco j esteja criado
e que o acesso j esteja liberado. Outras
alternativas so criar o cdigo inicialmente
no projeto para que o banco de dados seja
gerado a partir deste.
O primeiro passo criar o DataModel
que o repositrio dentro do projeto
responsvel pela criao das classes vin-
culadas com as tabelas do banco de dados.
O meio de fazer isso no Visual Studio
usar o menu de contexto da janela Solution
Explorer e acessar as opes Add > New
Item, como ilustrado na Figura 6.
Esta ao inicia um assistente para a cria-
o do DataModel. O primeiro passo deste Figura 6. Inserindo DataSource
assistente escolher o tipo do acesso que
ser feito. Neste processo deve ser usado
o modelo ADO.NET Entity Data Model.
A Figura 7 ilustra a janela do primeiro
passo do assistente.
Se no estiver visualizando esta janela
corretamente, selecione o item Data no
painel Installed Templates.
O segundo passo escolher se voc vai
criar um modelo vazio ou, como o caso
deste exemplo, vai ser usado um modelo
baseado em um banco de dados existente.
Neste caso, a janela que apresentada
tem a aparncia da Figura 8. Nesta, para
escolher a gerao do Data Model, a partir
de um banco de dados, escolha a opo
Generate from database.
Ao fazer isto, o assistente solicita a confi-
gurao da conexo com o banco. O boto Figura 7. Criando o DataModel
New Connection deve ser usado para
criar uma nova conexo com o banco. Este
boto mostra a janela da Figura 9 que tem
os campos necessrios para especificar o
servidor, o tipo de autenticao e o nome
do banco de dados.
Neste exemplo selecionei a autenticao
Windows, ou seja, aquela em que o usu-
rio autenticado j est cadastrado no SQL
Server como usurio. Esta autenticao
tem como vantagem no requerer a en-
trada das credenciais de usurio. Caso
voc opte por hospedar esta aplicao
em um servidor externo, importante
que voc selecione o tipo de autenticao
que exija usurio e senha. Assim, torna
o processo de autenticao mais seguro,
Figura 8. Primeiro passo do assistente para criar o DataModel

Edio 25 Easy .Net Magazine 11


Desenvolvendo um blog com ASP.NET Parte 1

visto que a mesma no integrada diretamente com o servidor. Seguindo na criao do Data Model, o prximo passo escolher as
Como estamos trabalhando em modo local, a autenticao com tabelas. A Figura 11 mostra a janela onde selecionam-se as tabelas
Windows facilita nosso trabalho, j que no necessrio informar do banco de dados. Neste exemplo, vamos mapear todas as tabelas,
usurio e senha. que na prtica iro fazer parte do nosso projeto. Desta forma, o Entity
Ao fazer as configuraes e fechar esta janela o assistente mostra os Framework j cria todas as classes com base nas tabelas mapeadas.
dados da mesma numa janela como a da Figura 10. Neste ponto voc Tambm dado o nome para o Data Model no campo Model
pode tambm dar o nome que achar mais significativo para a conexo namespace.
que foi configurada. Este nome ser usado durante a elaborao do
cdigo em C# para criar o Data Model e acessar os dados. ]

Figura 11. Escolhendo as tabelas

As opes desta etapa so:


Pluralize or singularize generated object name: aqui possvel
converter o nome dos objetos do banco de dados tabelas no nosso
Figura 9. Configurando a conexo
caso para o plural ou singular. Neste exemplo, deixe como ficou
definido no banco.
Include foreign key columns in the model: com esta opo sele-
cionada, o modelo gera uma coluna para chaves estrangeiras, mas,
como se trata de um modelo orientado a objeto, a coluna mapeia o
objeto inteiro. Ou seja, ao mapear um objeto do tipo blogs, criada
uma coluna com o nome posts j que esta tabela relaciona-se com
a outra tabela de mesmo nome. Neste caso, mapeada uma lista
de todos os posts que tem o id do blog. Isto vai ser til quando
estiver sendo definida a pgina de gerenciamento dos blogs. Os
registros dos posts podero ser trazidos na mesma consulta que
carrega os dados do blog.

Finalizada esta etapa, o Visual Studio gera um Entity Data Model,


que tem o comportamento semelhante ao diagrama de classes,
com os nomes destas tabelas que foram mapeadas, geradas como
nomes de classes. Nesta janela possvel editar as propriedades
selecionando cada objeto e usando o editor de propriedades do
Visual Studio, mas para o nosso no ser feito, porque as proprie-
dades da classe j esto adequadas s necessidades. O diagrama
Figura 10. Conexo criada de classes deve ter a aparncia da Figura 12.

12 Easy .Net Magazine Edio 25


existe uma regra que defina qual pgina voc deve criar primeiro,
isto depende somente de como voc preferir.
A criao de uma pgina nova no projeto pode ser feita de
diversas formas, sendo a mais comum usando o menu de con-
texto da janela Solution Explorer atravs dos comandos Add >
New Item.
Este comando vai abrir uma janela como a da Figura 13 onde so
definidos os dados para a criao do novo elemento.

Figura 12. DataModel Finalizado

O mapeamento do Data Model cria uma configurao padro


no arquivo Web.Config. Este arquivo deve ser alterado para que o
contedo e a conexo com o banco estejam adequados ao seu am-
biente de produo. A Listagem 3 mostra a string de conexo que
foi gerada automaticamente ao fazer este mapeamento. Observe Figura 13. Adicionando uma nova pgina
que o contedo vai ser diferente para cada servidor. Tambm
note que nesta string de conexo a autenticao feita usando No contexto da aplicao estou criando um novo Web Form e
integrao com o usurio do Windows (propriedade Integrated vou chamar de Default.aspx. Este nome convencionado como
security=True). Assim, a autenticao da conexo com o banco sendo o mais adequado para uma pgina inicial em um projeto
de dados SQL Server realizada utilizando a autenticao com ASP.NET. Embora voc possa usar outro nome e definir a pgina
Windows, conforme comentado anteriormente. como padro, recomendo seguir este padro para evitar proble-
mas de compatibilidade, j que o servidor IIS (que roda aplicaes
ASP.NET) sempre procura por um arquivo Default.aspx para ser
Listagem 3. Web.Config com a configurao da conexo ao banco a pgina inicial de um Web Site.
O desenvolvimento de aplicaes Web depende demais de fa-
<connectionStrings>
<add name=BlogEngineEntities tores como o navegador que est sendo usado para visualizar as
connectionString=metadata=res://*/BlogEngineDataModel.csdl| pginas, ento, conveniente manter os padres do projeto que
res://*/BlogEngineDataModel.ssdl|res://*/BlogEngineDataModel.msl;
provider=System.Data.SqlClient;provider connection string=&quot;
j esto testados.
data source=vladimir-note;initial catalog=BlogEngine;integrated O design da pgina default segue o que est exibido na Figura 14.
security=True;multipleactiveresultsets=True;App=EntityFramework
&quot; providerName=System.Data.EntityClient />
</connectionStrings>

O principal aspecto a ser observado quando se trabalha com o


acesso a banco de dados (neste exemplo com o Entity Framework)
verificar os dados da string de conexo para que no hajam pro-
blemas. Se voc observou este exemplo e o comparar com outra
string de conexo, geralmente usada em projetos que no esto
trabalhando com o Entity Framework, vai perceber que esta ltima
bem mais complexa. Mas, note que o contedo basicamente o
mesmo a partir do atributo Connection string.

Criando a pgina inicial


Embora no seja necessrio ser esta a primeira pgina a ser
criada, neste projeto optei por fazer desta forma. Na prtica, no Figura 14. Design da pgina principal

Edio 25 Easy .Net Magazine 13


Desenvolvendo um blog com ASP.NET Parte 1

Os controles mais importantes so controles do tipo TextBox para Nota


o usurio informar o endereo de e-mail e a senha para poder Nesta e nas demais listagens deste artigo o cdigo foi formatado de forma a facilitar a sua leitura,
fazer a autenticao. assim, sero usadas muitas quebras de linha e formataes que normalmente no so comuns.
Alm destes, tambm foi colocado um boto para fazer o envio Preste ateno a este detalhe principalmente nas marcaes HTML.
dos dados. O boto faz com que os dados dos controles TextBox
sejam validados usando um componente chamado Required
FieldValidator. Observe que o link que redireciona para a pgina de criao do
Estes controles so vinculados com controles como TextBox e tem blog e rtulos dos campos foram usados texto HTML puro, sem a
o seu comportamento configurado para responder a validao da utilizao de labels do ASP.NET. Para facilitar a sua implementa-
pgina ASP.NET que ocorre quando um boto que executa uma o, na Tabela 2 esto descritos os controles ASP.NET que foram
ao de post (envio de dados para o servidor) clicado. usados e como as propriedades devem ficar configuradas.
Os detalhes de implementao desta pgina podem ser verifica-
dos na Listagem 4 que mostra a marcao HTML usada. Controle Propriedade Valor
ID txtEmail
Listagem 4. Marcao html da pgina principal TextBox Columns 100
MaxLength 100
<%@ Page
ID LoginRequiredFieldValidator
Language=C#
AutoEventWireup=true ErrorMessage necessrio informar um e-mail.
RequiredFieldValidator
CodeBehind=Default.aspx.cs Display Dynamic
Inherits=BlogEngine.Default %> ControlToValidate txtEmail
<!DOCTYPE html PUBLIC -//W3C//DTDXHTML1.0Transitional//EN ID txtPass
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd>
Columns 10
<html xmlns=http://www.w3.org/1999/xhtml> TextBox
<head runat=server> MaxLength 10
<title>BlogEngine- GerenciadordeBlogs</title> TextMode Password
</head> ID PassRequiredFieldValidator
<body>
ErrorMessage necessrio informar a senha.
<form id=form1 runat=server> RequiredFieldValidator
<h1 BlogEngine- GerenciadordeBlogs</h1> Display Dynamic
Bemvindoaogerenciadordeblogs.<br /> ControlToValidate TxtPass
Faaoseuloginnoscamposabaixoou, crieoseublog ID BtnSend
<a href=NewBlog.aspx> aqui</a>.<br /> Button
Text Enviar
E-Mail<br />
<asp:TextBox Tabela 2. Configurao das propriedades dos controles da pgina Default.aspx
runat=server
ID=txtEmail
O login necessrio para identificar o usurio e manter na vari-
Columns=100
MaxLength=100 /><br /> vel de sesso o ID do blog que est sendo gerenciado. O processo
<asp:RequiredFieldValidator de login consiste basicamente em obter o endereo de e-mail e
runat=server
a senha. Este processo feito no blog usando dois mtodos, o
ID=LoginRequiredFieldValidator
ErrorMessage=necessrioinformarume-mail. primeiro, que valida os campos e responde ao evento Click do
Display=Dynamic boto. Se os controles estiverem vlidos (ou seja, foi fornecido
ControlToValidate=txtEmail /><br /> um valor correto), chamado um mtodo para fazer o login e
Senha<br />
<asp:TextBox carregar na sesso os dados do blog. Estes dois mtodos esto
runat=server descritos na Listagem 5.
ID=txtPass A Listagem 5 comea pelo mtodo que responde ao evento Click
Columns=10
MaxLength=10 na linha 19. Quando um click feito em uma pgina, se houver
TextMode=Password /><br /> componentes de validao como foram inseridos nesta pgina
<asp:RequiredFieldValidator o ASP.NET aplica a regra de validao vinculada aos controles.
runat=server
ID=PassRequiredFieldValidator Desta forma, antes de chamar o mtodo que vai fazer o login,
ErrorMessage=necessrioinformarasenha. a propriedade IsValid do objeto Page (que representa a pgina
Display=Dynamic atualmente carregada) verificado. Esta verificao a primeira
ControlToValidate=txtPass /><br />
<asp:Button feita no mtodo e est na linha 21. Se a pgina estiver vlida feita
runat=server uma chamada para o mtodo que faz o login na linha 24.
ID=btnSend Este mtodo est descrito a partir da linha 27. A primeira tarefa
Text=Enviar />
</form>
criar uma instncia do Data Model que foi criado no incio do
</body> projeto (linha 29 e 30) para poder usar a linguagem LINQ para
</html> obter os dados do banco.

14 Easy .Net Magazine Edio 25


Listagem 5. Cdigo para fazer o login ClientScript. O mtodo RegisterStartupScript usado para fazer
a chamada do script. Este mtodo requer trs argumentos:
19 protected void btnSend_Click(object sender, EventArgs e)
20 {
1. O primeiro o tipo do objeto que est chamando o script. Nes-
21 if (!Page.IsValid) te caso, uma Page que tem o seu tipo passado como argumento
22 return; atravs do mtodo GetType().
23
24 doLogin();
2. O segundo argumento um identificador para o script para o
25 } seu gerenciamento e a correta gerao do cdigo para o browser
26 por parte do servidor. Informe sempre um id que no seja repetido
27 private void doLogin()
28 { no projeto.
29 var dataModel = new BlogEngineEntities(ConfigurationManager 3. Por fim, o terceiro argumento contm o cdigo para o JavaScript
30 .ConnectionStrings[BlogEngineEntities].ToString()); propriamente dito.
31 var result = (from blog in dataModel.blogs
32 where blog.admin_mail == txtEmail.Text.ToLower() &&
33 blog.password == txtPass.Text Este bloco mostra a mensagem para o usurio e encerra o mto-
34 select new { blog.id }).ToList();
do, ou ento, se os dados passados pelo usurio forem vlidos, o
35
36 if (result == null || result.Count == 0) mtodo armazena o valor do id do blog na varivel de sesso na
37 { linha 44 e redireciona o usurio para a pgina de gerenciamento
38 ClientScript.RegisterStartupScript(
do blog.
39 Page.GetType(), Login,
40 <script>alert(Login ou senha incorretos.)</script>); Com estes procedimentos o login validado e o id do blog
41 return; passado apropriadamente para a memria de onde poder ser lido
42 }
43
posteriormente. Um ponto importante neste tipo de aplicao
44 Session[UserId] = result[0].id; validar se h um login ativo. Uma forma de fazer isto na carga da
45 Response.Redirect(BlogStartPage.aspx); pgina inspecionando uma varivel definida como identificador de
46 }
sesso. A pgina Default tem um objetivo duplo: tanto usada para

Nota

Para comear a escrever o cdigo correspondente ao evento Click do boto, basta alternar o design
do Visual Studio para mostrar o design da pgina em vez da marcao HTML. Depois disso, basta dar
um clique duplo sobre o boto e o editor do cdigo C# exibido.

Este cdigo usa a string de conexo com o banco que est ar-
mazenada no arquivo Web.config, para poder ler esta usada a
classe ConfigurationManager. Voc vai precisar adicionar nas
clusulas using da pgina a biblioteca System.Configuration para
poder usar esta classe.
O bloco que vai da linha 31 35 contm a instruo LINQ que
compara o e-mail e a senha informados com o banco de dados
retornando uma lista contendo o id do blog. Este id ser arma-
zenado na varivel de sesso para ser usado posteriormente nas
demais pginas para permitir as outras operaes.
muito importante observar que nesta etapa ainda no est sen-
do feita a proteo da senha com criptografia. Assim, este cdigo
ainda no pode ser usado em uma aplicao real. Na prxima
edio vou demonstrar como fazer a proteo da senha usando
criptografia de senha gerando um hash.
Se o usurio informou um endereo de e-mail ou uma senha
incorretos o programa precisa alertar isto. Na verso desta pgina,
optei por emitir um alerta usando a funo alert do JavaScript.
Isto evita que seja necessrio ter um componente oculto para esta
mensagem na pgina e tambm serve para demonstrar como
executar scripts deste tipo a partir do C#. Na linha 36 o bloco
if verifica a validade do login, se estiver incorreto na linha 38
gerado o script para mostrar um alerta para o usurio com a classe

Edio 25 Easy .Net Magazine 15


Desenvolvendo um blog com ASP.NET Parte 1

estabelecer a sesso como quebrar esta num processo de logoff.


Nas demais pginas, sempre ser verificado se h uma sesso
vlida, caso no houver, o usurio vai sempre ser redirecionado
para a pgina de login. O cdigo para quebrar a sesso exibido
na Listagem 6 que mostra o mtodo Page_Load normalmente
executado todas as vezes que a pgina carregada. claro que,
caso voc prefira, ao invs de fazer os procedimentos de login e
logoff na mesma pgina, poderia criar elas separadamente, como
Login.aspx e Logoff.aspx.

Listagem 6. Mtodo para carga da pgina e quebra de sesso

13 protected void Page_Load(object sender, EventArgs e)


14 {
15 if (!Page.IsPostBack && Session[UserId] != null)
16 Session[UserId] = null;
17 }

O mtodo bastante simples, verifica se no se trata de uma


reconstruo da pgina aps um envio de dados para o servidor
(como, por exemplo, durante a validao do login) e se a sesso
j no est nula.
Neste caso, armazena o valor null na varivel de sesso. Este
processo vai fazer com que as prximas pginas, ao serem car-
regadas redirecionem para a pgina inicial por no haver um
identificador vlido.

Pgina de criao do blog Figura 15. Design da pgina de criao do blog


Se o usurio no tiver um login poder usar um link na pgina
inicial para criar o seu blog e os dados necessrios. A pgina de Nesta aplicao para fazer a validao para que haja um ende-
criao do blog foi chamada neste projeto de NewBlog.aspx e o reo nico de e-mail e tambm nome nico para o blog utilizei
seu design pode ser conferido na Figura 15. um validador chamado CustomValidator, alm do validador
Esta pgina possui entre os principais controles, TextBoxes, RequiredFieldValidator que j foi empregado na pgina inicial.
validadores diversos e um boto para envio dos dados. Estes com- Este usa um conjunto de propriedades que so configurados com
ponentes podem ser mais facilmente identificados na Listagem 7 o editor do Visual Studio e cdigo C# executado no servidor da
que detalha o cdigo HTML usado nesta pgina. pgina para fazer a validao dos controles.
A localizao dos controles no designer do Visual Studio tam- Para o endereo de e-mail ser verificado quanto ao formato
bm facilitada estando o TextBox e o controle Button no grupo correto foi usado um RegularExpressionValidator que usa expres-
Standard e os validadores adivinhe no grupo Validation. ses regulares para validar o contedo dos controles. Falarei um
pouco mais sobre este controle mais adiante. Como a validao de
Nota e-mail um valor dinmico, somente com expresses regulares
poderamos realizar esta validao e, no ASP.NET, o controle
Voc sabia que mesmo se estiver visualizando o cdigo HTML possvel arrastar os controle para o
RegularExpressionValidator serve justamente para isto.
cdigo, que o Visual Studio trata de gerar a tag correspondente ao controle? Experimente fazer isto
A Tabela 3 mostra como ficaram as configuraes dos controles
da prxima vez que precisar trabalhar com HTML e ASP.NET.
visuais da pgina NewBlog.aspx. Estou mostrando os controles
de cima para baixo.
Para criar um blog corretamente nesta aplicao alguns aspectos Sobre o componente RegularExpressionValidator este controle l
importantes devem ser verificados. No pode haver dois blogs a expresso regular que foi confirmada e a aplica para o contedo
com o mesmo nome para que possa ser respeitada a integridade digitado no controle TextBox que est vinculado com o validador.
referencial que foi definida na criao da tabela blogs no banco A expresso regular para validar e-mail certamente difcil
de dados. de ler:
O endereo de e-mail do administrador do blog tambm deve
ser nico, alm de ser corretamente formatado. Estas validaes ^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))
podem ser feitas de diversas formas inclusive com cdigo C#. ([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$

16 Easy .Net Magazine Edio 25


Controle Propriedade Valor Observaes
ID txtName
Columns 50
Esta propriedade limita o nmero de caracteres
TextBox
que podero ser inseridos no controle.
MaxLength 50
Use-a para no ter problemas com o tamanho dos
dados ao inserir no banco de dados.
ID NameRequiredFieldValidator
ErrorMessage necessrio informar o nome.<br />
Marcando esta propriedade como Dynamic, o
RequiredFieldValidator
Display Dynamic texto que est configurado em ErrorMessage s
ser exibido aps a validao.
ControlToValidate txtName
Este controle usa um cdigo do lado do servidor.
Sua funo verificar se no existe nenhum outro
ID CustomValidatorName
registro no banco de dados que tenha o mesmo
ttulo.
ErrorMessage Use outro nome. Este j est sendo usado.<br />
CustomValidator Display Dynamic
ControlToValidate txtName
Marcando esta propriedade como True, caso o
contedo do controle vinculado com o validador
SetFocusOnError True no seja validado, se no houver nenhum contro-
le antes deste com este mesmo tipo de validador,
este controle receber o foco do cursor.
ID txtDescription
Columns 50
TextBox Rows 5
TextMode MultiLine
MaxLength 1000
ID DescriptionRequiredFieldValidator
ErrorMessage necessrio informar uma descrio.<br />
RequiredFieldValidator
Display Dynamic
ControlToValidate txtDescription
ID txtAuthor
TextBox Columns 100
MaxLength 100
ID AutorRequiredFieldValidator

ErrorMessage necessrio informar um nome para o autor.<br />


RequiredFieldValidator
Display Dynamic
ControlToValidate txtAuthor
ID txtMail
TextBox Columns 100
MaxLength 100
ID EmailRequiredFieldValidator

ErrorMessage necessrio informar um endereo de e-mail.<br />


RequiredFieldValidator
Display Dynamic
ControlToValidate txtMail
este validador que verifica se o endereo de
e-mail informado est correto.
ID EmailRegularExpressionValidator O validador usa expresses regulares que so
RegularExpressionValidator
uma forma de evitar ter de escrever cdigos para
executar validaes complexas.
ErrorMessage Endereo de e-mail invlido.<br />

Tabela 3. Configurao dos controles da pgina de criao do blog

Edio 25 Easy .Net Magazine 17


Desenvolvendo um blog com ASP.NET Parte 1

Controle Propriedade Valor Observaes


este validador que verifica se o endereo de
e-mail informado est correto.
ID EmailRegularExpressionValidator O validador usa expresses regulares que so
uma forma de evitar ter de escrever cdigos para
executar validaes complexas.
ErrorMessage Endereo de e-mail invlido.<br />
^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]
ValidationExpression Veja mais explicaes adiante.
{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$
RegularExpressionValidator ControlToValidate txtMail
Este validador executa uma consulta ao banco de
CustomValidator ID dados para assegurar que o endereo de e-mail
informado ainda no exista no banco.
ErrorMessage Use outro e-mail. Este j est sendo usado.<br />
Display Dynamic
ControlToValidate txtMail
SetFocusOnError True
ID txtPass
Columns 10
TextBox TextMode Password

MaxLength 10

ID PassRequiredFieldValidator
ErrorMessage necessrio informar uma senha.<br />
RequiredFieldValidator Display Dynamic

ControlToValidate txtPass

ID txtConfirm
Columns 10
TextBox TextMode Password

MaxLength 10

O objetivo deste controle comparar as duas


ID PassCompareValidator
senhas digitadas e validar se esto iguais.

CompareValidator
ControlToCompare txtPass
ControlToValidate txtConfirm
Display Dynamic

ErrorMessage As senhas no conferem.<br />

ID btnSend

Executa uma funo pr-definida com JavaScript


do lado do cliente pedindo uma confirmao
antes de validar os dados da pgina e enviar para
OnClientClick confirmacao(Confirma o envio?);
Button o servidor.
Esta funo vai ser explicada adiante no tpico
Definindo o arquivo de script.

Text Enviar

Continuao: Tabela 3. Configurao dos controles da pgina de criao do blog

18 Easy .Net Magazine Edio 25


Sua composio requer o conhecimento do funcionamento <sequncia de letras/nmeros/ponto>@<sequncia de letras/
de expresses regulares que so um recurso muito usado nmeros>.<sequncia de trs letras[.<sequncia de duas letras>]
pelos programadores desde que as primeiras linguagens co-
mearam a ser criadas. Em resumo, a expresso valida o texto Considere a quantidade de cdigo necessria para validar esta
aplicando o formato usado para endereo de e-mail que deve regra com a linguagem C# e voc vai ter uma ideia sobre a utili-
ser o seguinte: dade de expresses regulares, conforme a Listagem 7.

Listagem 7. Marcao HTML da pgina de criao do blog

<%@Page ErrorMessage=necessrioinformarumnomeparaoautor.<br/>
Language=C# Display=Dynamic
AutoEventWireup=true ControlToValidate=txtAuthor/>
CodeBehind=NewBlog.aspx.cs Endereodee-mail<br/>
Inherits=BlogEngine.NewBlog%> <asp:TextBox
runat=server
<!DOCTYPEhtmlPUBLIC-//W3C//DTDXHTML1.0Transitional//EN ID=txtMail
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd> Columns=100
MaxLength=100/><br/>
<htmlxmlns=http://www.w3.org/1999/xhtml> <asp:RequiredFieldValidator
<headrunat=server> runat=server
<title>BlogEngine-CriaodoBlog</title> ID=EmailRequiredFieldValidator
<scripttype=text/javascriptsrc=scripts.js></script> ErrorMessage=necessrioinformarumendereodee-mail.<br/>
</head> Display=Dynamic
<body> ControlToValidate=txtMail/>
<h1>BlogEngine-Criarnovoblog</h1> <asp:RegularExpressionValidator
<ahref=Default.aspx>Logoff</a>-Criarconta runat=server
<hr/> ID=EmailRegularExpressionValidator
Useestapginaparacriaroseublog.<br/> ErrorMessage=Endereodee-mailinvlido.<br/>
Oendereodee-mailserusadoparaoseulogin.<hr/> ValidationExpression=^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))
Spodehaverume-mailparacadablog.<br/> ([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$
<formid=form1runat=server> ControlToValidate=txtMail/>
NomedoBlog<br/> <asp:CustomValidator
<asp:TextBox ID=CustomValidatorEmail
runat=server runat=server
ID=txtName ErrorMessage=Useoutroe-mail.Estejestsendousado.<br/>
Columns=50 Display=Dynamic
MaxLength=50/><br/> ControlToValidate=txtMail
<asp:RequiredFieldValidator SetFocusOnError=True
runat=server onservervalidate=CustomValidatorEmail_ServerValidate/>
ID=NameRequiredFieldValidator Senha<br/>
ErrorMessage=necessrioinformaronome.<br/> <asp:TextBox
Display=Dynamic runat=server
ControlToValidate=txtName/> ID=txtPass
<asp:CustomValidator Columns=10
ID=CustomValidatorName TextMode=Password
runat=server MaxLength=10/><br/>
ErrorMessage=Useoutronome.Estejestsendousado.<br/> <asp:RequiredFieldValidator
Display=Dynamic runat=server
ControlToValidate=txtName ID=PassRequiredFieldValidator
SetFocusOnError=True ErrorMessage=necessrioinformarumasenha.<br/>
onservervalidate=CustomValidatorName_ServerValidate/> Display=Dynamic
Descriodocontedodoblog<br/> ControlToValidate=txtPass/>
<asp:TextBox Confirmaodasenha<br/>
runat=server <asp:TextBox
ID=txtDescription runat=server
Columns=50 ID=txtConfirm
Rows=5 Columns=10
TextMode=MultiLine TextMode=Password
MaxLength=1000/><br/> MaxLength=10/><br/>
<asp:RequiredFieldValidator <asp:CompareValidator
runat=server runat=server
ID=DescriptionRequiredFieldValidator ID=PassCompareValidator
ErrorMessage=necessrioinformarumadescrio.<br/> ControlToCompare=txtPass
Display=Dynamic ControlToValidate=txtConfirm
ControlToValidate=txtDescription/> Display=Dynamic
Nomedoautor<br/> ErrorMessage=Assenhasnoconferem.<br/>/>
<asp:TextBox <asp:Button
runat=server runat=server
ID=txtAuthor ID=btnSend
Columns=100 OnClientClick=confirmacao(Confirmaoenvio?);
MaxLength=100/><br/> Text=Enviaronclick=btnSend_Click/>
<asp:RequiredFieldValidator </form>
runat=server </body>
ID=AutorRequiredFieldValidator </html>

Edio 25 Easy .Net Magazine 19


Desenvolvendo um blog com ASP.NET Parte 1

Na interface foram definidos dois controles do tipo CustomValida- Listagem 8. Enviando e validando o nome
tors. Estes controles executam um cdigo no lado do servidor que 42 protected void CustomValidatorName_ServerValidate(object source,
deve retornar se o contedo foi validado ou no. Para escrever um 43 ServerValidateEventArgs args)
event handler em seu cdigo para um controle deste, voc precisa 44 {
45 var dataModel = new BlogEngineEntities(ConfigurationManager
selecionar o controle (em modo design no Visual Studio) e na janela 46 .ConnectionStrings[BlogEngineEntities].ToString());
onde se visualiza os eventos associados com o controle, dar um duplo 47 var list = from blog in dataModel.blogs
clique sobre o item ServerValidate. Esta ao vai exibir o editor de 48 where blog.name.ToUpper() == args.Value.ToUpper()
49 select blog.name;
cdigos onde voc pode entrar com o cdigo C# que deve ser parecido 50 args.IsValid = list == null || list.Count() == 0;
com o da Listagem 8. Estes controles foram utilizados pelo fato de ser 51 }
necessrio criar validaes customizadas, mas, utilizando os recursos
Listagem 9. Validando o e-mail
de validaes do prprio ASP.NET, vistos anteriormente.
O mtodo consulta no banco de dados por outros ttulos de 53 protected void CustomValidatorEmail_ServerValidate(object source,
54 ServerValidateEventArgs args)
blog iguais ao que o usurio digitou. Se nenhum for encontrado a
55 {
pgina vai ser validada. Este cdigo inicia-se na linha 45 criando 56 var dataModel = new BlogEngineEntities(ConfigurationManager
uma instncia do Data Model definido no projeto para poder 57 .ConnectionStrings[BlogEngineEntities].ToString());
58 var list = from blog in dataModel.blogs
conectar-se ao banco. 59 where blog.admin_mail.ToLower() == args.Value.ToLower()
Na linha 47 foi definida a instruo LINQ que faz a comparao 60 select blog.admin_mail;
do ttulo do blog. Para poder tornar a consulta case insensitive o 61 args.IsValid = list == null || list.Count() == 0;
62 }
cdigo converte tanto o contedo do banco como o que foi digitado
pelo usurio para maisculas para fazer a comparao. Listagem 10. Inserindo o registro do blog
Por fim, na linha 50, se nenhum registro foi encontrado, a pgina
16 protected void btnSend_Click(object sender, EventArgs e)
(que est embutida no parmetro args) validada. 17 {
Da mesma forma que necessrio validar o blog para que o ttulo 18 if (Page.IsValid)
19 if (InsertBlog())
seja nico, o endereo de e-mail tambm precisa passar por esta
20 Response.Redirect(Default.aspx);
validao. Na Listagem 9 voc verifica como ficou definido o c- 21 }
digo que consulta o banco de dados para comparar o endereo de 22
23 private bool InsertBlog()
e-mail. Observe que este evento s vai ser disparado se o endereo 24 {
j foi validado pelo RegularExpressionValidator. 25 var model = new BlogEngineEntities(ConfigurationManager
Este mtodo bem parecido com o que valida o ttulo do blog. 26 .ConnectionStrings[BlogEngineEntities].ToString());
27 var blog = new BlogEngine.blogs()
Na linha 56 criada a instncia para o Data Model usando as con- 28 {
figuraes de string de conexo que foram armazenadas. Criando 29 id = 0,
esta instncia se torna possvel o uso do Entity Framework, para 30 admin_mail = txtMail.Text,
31 admin_name = txtAuthor.Text,
a persistncia/consulta dos dados. 32 name = txtName.Text,
Da linha 58 at a 60 definida a instruo LINQ que faz a consul- 33 password = txtPass.Text,
ta no banco de dados. Note que desta vez, para fazer a comparao 34 description = txtDescription.Text,
35 date_created = DateTime.Now
case insensitive, foi usado o mtodo ToLower() para o contedo 36 };
do banco e do controle. Assim, caso o usurio coloque algum 37 model.AddObject(blogs, blog);
38 return model.SaveChanges(System.Data
valor minsculo ou maisculo no teremos problemas, visto que
39 .Objects.SaveOptions.AcceptAllChangesAfterSave) > 0;
sempre convertermos os mesmos para minsculos. 40 }
O mtodo finaliza verificando se algum endereo foi retornado
e faz a validao da pgina.
Uma vez definidos os mtodos deve ser escrito o cdigo que en- O mtodo InsertBlog inicia-se na linha 23. Em resumo ele cria
via os dados para o banco e cria o blog. Esta ao vai ser executada um Data Model, configura um novo objeto para insero no banco
quando o usurio der um clique no boto que foi definido. Assim, e envia os dados para este.
para escrever o cdigo, d um duplo clique neste elemento. Na linha 25 novamente est sendo criado o Data Model partindo
O cdigo para inserir os dados est na Listagem 10. da configurao armazenada no arquivo Web.Config.
Este cdigo est dividido em dois mtodos, o primeiro, corresponde A partir da linha 27 definido um novo objeto usando a classe
ao mtodo criado automaticamente pelo Visual Studio como Event blogs atravs da inicializao direta, ou seja, estou passando os
Handler para o evento click do boto. Este mtodo bem simples. Ele valores das propriedades diretamente no momento da inicializao
verifica se a pgina est vlida, caso positivo, se o mtodo que insere aps chamar o construtor. Este tipo de sintaxe torna o cdigo mais
os dados no banco (chamado aqui de InsertBlog) retornar sucesso fcil de entender, embora, se quiser definir um construtor persona-
a aplicao redireciona para a pgina inicial novamente para que o lizado ou, criar uma instncia para em seguida informar os valores
usurio possa fazer login e iniciar a administrao do blog. para as propriedades dos objetos, no h nenhum problema.

20 Easy .Net Magazine Edio 25


Depois de definir os dados do objeto este enviado para o Data
Model na linha 37. atravs do mtodo SaveChanges (na linha 38)
que o objeto gravado no banco. Como as tabelas foram mapeadas
e geradas suas devidas classes, os campos das tabelas se tornaram
propriedades, ao qual esto sendo setados diretamente no cdigo,
com base nos valores vindo dos TextBoxes. Isso tudo facilita muito,
principalmente pelo fato de no ser necessrio escrever comandos
SQL e tudo que foi setado nas propriedades automaticamente
persistido atravs do mtodo SaveChanges.
Este cdigo bastante simples e este modelo pode ser usado para
outras operaes semelhantes, como voc vai poder conferir na
pgina de incluso de post do blog.

Pgina de gerenciamento do blog


Aps o usurio cadastrar o blog, o aplicativo permite que ao
fazer o login, este possa administrar o seu blog. As tarefas de
administrao que esto disponveis so as alteraes dos se- Figura 16. Pgina para gerenciamento do blog
guintes dados:
1. Nome do blog; Para distribuir os controles nesta pgina foi usada uma tabela
2. Descrio do contedo; (tag <table>) onde na primeira coluna so colocados os campos
3. Nome do autor; referentes edio do blog e na segunda coluna, um controle
4. Endereo de e-mail. GridView para listar os ttulos dos posts j inseridos e sobre este
um boto que abre a pgina de insero dos posts.
Alm disso, na janela de administrao possvel tambm A Listagem 11 detalha o cdigo HTML para esta pgina. Lem-
visualizar uma lista com o ttulo1 dos2/9/11
FairCom101206BRhalffinal.pdf
posts j enviados e chamar
3:19 PM
brando que a formatao usada apenas para tornar o cdigo
a janela para incluso de novos posts. O design da pgina de mais legvel para o artigo.
administrao que foi chamada no projeto de BlogStartPage.aspx A Tabela 4 detalha como ficaram configurados os controles da
pode ser conferido na Figura 16. pgina.

SQL E Isam Uma


Combinao De Sucesso!
Deixe o sistema de sua empresa mais leve e rpido. Conhea as
novidades do c-tree e faa toda a diferena!
U ADICIONE processamento de transaes, recuperao automtica,
backups dinmicos e replicao aos seus aplicativos.
ration

U AMPLIE sua escolha de APIs com C, C++, .NET, ODBC, JDBC, PHP e SQL.
Corpo

U FAA como muitas empresas no mundo todo, lderes em diversos


Com

segmentos como finanas, telecomunicaes e sade, que tm baseado


1 Fair

suas solues crticas na tecnologia c-tree.


201

the right-size Database

Baixe seu SDK grtis


Edio 25 Easy .Net Magazine 21
v>VVUnn
Desenvolvendo um blog com ASP.NET Parte 1

Listagem 11. Marcao HTML para a pgina de gerenciamento

<%@ Page Language=C# MaxLength=100 /><br />


AutoEventWireup=true <asp:RequiredFieldValidator
CodeBehind=BlogStartPage.aspx.cs runat=server
Inherits=BlogEngine.BlogStartPage %> ID=AutorRequiredFieldValidator
<!DOCTYPE html PUBLIC -//W3C//DTDXHTML1.0Transitional//EN ErrorMessage=necessrioinformarumnomeparaoautor.<br/>
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd> Display=Dynamic
<html xmlns=http://www.w3.org/1999/xhtml> ValidationGroup=BlogData
<head runat=server> ControlToValidate=txtAuthor />
<title>BlogEngine- Pginainicial</title> Endereodee-mail
<script type=text/javascript src=scripts.js></script> <asp:TextBox
</head> runat=server
<body> ID=txtMail
<h1>BlogEngine- Gerenciarblog</h1> Columns=100
<a href=Default.aspx>Logoff</a> - Gerenciar MaxLength=100 /><br />
<hr /> <asp:RequiredFieldValidator
Useestapginaparaadmiinistraroseublog.<br /> runat=server
Osdadosabaixopodemsereditados.<hr /> ID=EmailRequiredFieldValidator
<form id=form1 runat=server> ErrorMessage=necessrioinformarumendereodee-mail.<br/>
<table> Display=Dynamic
<tr> ValidationGroup=BlogData
<td style=Width:50%>Dados do blog</td> ControlToValidate=txtMail /><br />
<td>Posts</td> <asp:RegularExpressionValidator
</tr> runat=server
<tr> ID=EmailRegularExpressionValidator
<td valign=top ErrorMessage=Endereodee-mailinvlido.<br/>
style=width:50%> ValidationExpression=^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]
Nome do Blog<br /> {1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$
<asp:TextBox ValidationGroup=BlogData
runat=server ControlToValidate=txtMail />
ID=txtName <asp:CustomValidator
Columns=50 ID=CustomValidatorEmail
MaxLength=50 /><br /> runat=server
<asp:RequiredFieldValidator ErrorMessage=Useoutroe-mail. Estejestsendousado.<br/>
runat=server Display=Dynamic
ID=NameRequiredFieldValidator ControlToValidate=txtMail
ErrorMessage=necessrioinformaronome.<br/> ValidationGroup=BlogData
Display=Dynamic SetFocusOnError=True
ValidationGroup=BlogData onservervalidate=CustomValidatorEmail_ServerValidate />
ControlToValidate=txtName /> <asp:Button
<asp:CustomValidator runat=server
ID=CustomValidatorName ID=btnSend
runat=server OnClientClick=confirmacao(Confirmaaalteraodosdados?);
ErrorMessage=Useoutronome. Estejestsendousado.<br/> Text=Enviar
Display=Dynamic ValidationGroup=BlogData
ControlToValidate=txtName onclick=btnSend_Click />
SetFocusOnError=True </td>
ValidationGroup=BlogData <td valign=top>
onservervalidate=CustomValidatorName_ServerValidate /> <asp:Button
Descriodocontedodoblog<br /> runat=server
<asp:TextBox ID=btnNewPost
runat=server Text=Incluirnovopost
ID=txtDescription ValidationGroup=NewPost onclick=btnNewPost_Click />
Columns=50 <hr />
Rows=5 <asp:GridView
TextMode=MultiLine AutoGenerateColumns=false
MaxLength=1000 /><br /> Width=100%
<asp:RequiredFieldValidator runat=server
runat=server ID=grdPosts>
ID=DescriptionRequiredFieldValidator <Columns>
ErrorMessage=necessrioinformarumadescrio.<br/> <asp:BoundField DataField=post_title />
Display=Dynamic </Columns>
ValidationGroup=BlogData </asp:GridView>
ControlToValidate=txtDescription /> </td>
Nome do autor<br /> </tr>
<asp:TextBox </table>
runat=server </form>
ID=txtAuthor </body>
Columns=100 </html>

22 Easy .Net Magazine Edio 25


Controle Propriedade Valor Observaes
ID txtName
Columns 50
TextBox
MaxLength 50

ID NameRequiredFieldValidator
ErrorMessage necessrio informar o nome.<br />
Display Dynamic
Como na pgina existem dois botes e
para cada click causada uma validao,
RequiredFieldValidator a utilizao de um ValidationGroup
ValidationGroup BlogData
necessria para que cada click em cada
boto faa a validao em um conjunto
especfico de controles.
ControlToValidate txtName
Novamente ser necessrio usar um
controle Custom Validator para verificar
ID CustomValidatorName
se ao alterar o nome do blog no se est
informando um que j esteja cadastrado.
CustomValidator ErrorMessage Use outro nome. Este j est sendo usado.<br />
Display Dynamic
ControlToValidate txtName
SetFocusOnError True
ValidationGroup BlogData
ID txtDescription
Columns 50
TextBox Rows 5
TextMode MultiLine
MaxLength 1000
ID DescriptionRequiredFieldValidator
ErrorMessage necessrio informar uma descrio.<br />
RequiredFieldValidator Display Dynamic
ValidationGroup BlogData
ControlToValidate txtDescription
ID txtAuthor
TextBox Columns 100
MaxLength 100
ID AutorRequiredFieldValidator
ErrorMessage necessrio informar um nome para o autor.<br />
RequiredFieldValidator Display Dynamic
ValidationGroup BlogData
ControlToValidate txtAuthor
ID txtMail
TextBox Columns 100
MaxLength 100
ID EmailRequiredFieldValidator
ErrorMessage necessrio informar um endereo de e-mail.<br />
RequiredFieldValidator Display Dynamic
ValidationGroup BlogData
ControlToValidate txtMail
ID EmailRegularExpressionValidator
ErrorMessage Endereo de e-mail invlido.<br />
^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]
RegularExpressionValidator ValidationExpression
{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$
ValidationGroup BlogData
ControlToValidate txtMail

Tabela 4. Controles da pgina inicial do blog

Edio 25 Easy .Net Magazine 23


Desenvolvendo um blog com ASP.NET Parte 1

Controle Propriedade Valor Observaes


ID CustomValidatorEmail
ErrorMessage Use outro e-mail. Este j est sendo usado.<br />
Display Dynamic
CustomValidator
ControlToValidate txtMail
ValidationGroup BlogData
SetFocusOnError True
ID btnSend
OnClientClick confirmacao(Confirma a alterao dos dados?);
Button
Text Enviar
ValidationGroup BlogData
Este o boto que abre a pgina para
ID btnNewPost
incluso de um novo post.
Text Incluir novo post
Button Note que agora o grupo de validao
outro. Assim, ao clicar neste boto, os
ValidationGroup NewPost
controles referentes aos dados do blog
no sero validados.
AutoGenerateColumns False
GridView Width 100%
ID grdPosts

Continuao: Tabela 4. Controles da pgina inicial do blog

Para o controle GridView foi definida uma coluna na marcao Listagem 12. Cdigo controlando o carregamento da pgina
HTML como est detalhado a seguir:
11 protected void Page_Load(object sender, EventArgs e)
<asp:GridView 12 {
AutoGenerateColumns=false 13 if (Session[UserId] == null)
Width=100% 14 Response.Redirect(Default.aspx);
runat=server 15
ID=grdPosts> 16 if (!Page.IsPostBack)
<Columns> 17 loadBlogData();
<asp:BoundField DataField=post_title /> 18 }
</Columns>
</asp:GridView> Listagem 13. Carregando os dados

20 private void loadBlogData()


A partir da pgina inicial do blog preciso que seja verificado 21 {
se h uma sesso vlida, caso contrrio, por no haver um id que 22 var dataModel = new BlogEngineEntities(ConfigurationManager
armazenado nesta sesso, no ser possvel consultar o banco 23 .ConnectionStrings[BlogEngineEntities].ToString());
24 var blogId = Convert.ToInt32(Session[UserId]);
de dados para realizar as operaes. 25 var blogDataList = (from blog in dataModel.blogs
Existem vrias formas de se validar a sesso. A inicial manu- 26 where blog.id == blogId
almente, usando a validao no servidor com cdigo C#. 27 select new {
28 blog.name,
A Listagem 12 demonstra o evento PageLoad que o primeiro
29 blog.admin_mail,
evento e sempre disparado assim que uma pgina carregada. 30 blog.description,
Ento, este o ponto onde se faz a validao da sesso. 31 blog.admin_name,
O mtodo verifica se a sesso est nula, caso esteja, redireciona 32 blog.posts
33 }).ToList();
o usurio para a pgina de login, caso contrrio, chama outro 34
mtodo para carregar os dados da mesma. 35 if (blogDataList == null || blogDataList.Count == 0)
Na linha 13 verificada a varivel de sesso para verificar se est 36 Response.Redirect(default.aspx);
37
nula. Se voc retornar no artigo e verificar o cdigo referente ao
38 txtName.Text = blogDataList[0].name;
login ver que foi ali onde foi definida esta varivel. 39 txtMail.Text = blogDataList[0].admin_mail;
O cdigo para carregar os dados da pgina pode ser conferido 40 txtDescription.Text = blogDataList[0].description;
na Listagem 13. O mtodo loadBlogData cria uma conexo com o 41 txtAuthor.Text = blogDataList[0].admin_name;
42 grdPosts.DataSource = blogDataList[0].posts;
banco e faz uma consulta usando LINQ. Se os dados retornados 43 grdPosts.DataBind();
forem vlidos, seta estes nos controles da pgina, caso contrrio, 44 }
redireciona o usurio para a pgina inicial.

24 Easy .Net Magazine Edio 25


Na linha 22 temos novamente a criao do Data Model. Em Assim, novamente na linha 62 o cdigo cria uma instncia do
seguida, o id do blog convertido para valor inteiro para poder Data Model. Na linha 64 converte o valor da varivel de sesso
ser usado dentro da consulta LINQ. contendo o id do blog e na linha 65 at a 68 feita a consulta ao
A consulta est contida das linhas 25 at a 33 e nesta pode se banco usando LINQ.
perceber uma das grandes vantagens da utilizao da linguagem Na linha 69 a pgina validada dependendo do resultado da
LINQ e o Entity Framework que a possibilidade de mapear consulta. Com os dados validados chegou a hora de enviar as
objetos relacionados na mesma consulta. Observe a linha 32. A alteraes. O cdigo da Listagem 16 mostra tanto a verificao
partir da linha 27 so selecionadas todas as propriedades que da validao da pgina como j faz o envio dos dados que esto
sero usadas, mas, a da linha 32 seleciona tambm uma lista de carregados para o banco.
posts vinculados com o blog. Mas, se voc se lembra, em nenhum
momento voc definiu uma classe ou mtodo para fazer isto. Listagem 14. Validando a alterao do nome
Na verdade, quando criou a tabela blogs e a tabela posts no seu
banco de dados e fez um relacionamento entre estas, ao fazer 46 protected void CustomValidatorName_ServerValidate(object source,
47 ServerValidateEventArgs args)
o mapeamento destas usando Entity Framework, tambm foi 48 {
criado o relacionamento entre os objetos e o cdigo que faz com 49 var dataModel = new BlogEngineEntities(ConfigurationManager
50 .ConnectionStrings[BlogEngineEntities].ToString());
que ao mapear um objeto blog tambm se consiga mapear os
51 var blogId = Convert.ToInt32(Session[UserId]);
seus posts. 52 var list = from blog in dataModel.blogs
Desta forma, de uma maneira bem transparente trazer os dados 53 where blog.name.ToUpper() == args.Value.ToUpper() &&
54 blog.id != blogId
que so necessrios pode ser realizado de uma s vez (ainda que
55 select blog.name;
em background, estejam sendo executadas consultas extensas 56 args.IsValid = list == null || list.Count() == 0;
para poder realizar o trabalho, o cdigo otimizado para dar a 57 }
melhor performance possvel). Listagem 15. Validando a alterao do e-mail
A consulta finaliza na linha 33 convertendo o resultado origi-
nalmente o um objeto IEnumerable para uma lista genrica. 59 protected void CustomValidatorEmail_ServerValidate(object source,
60 ServerValidateEventArgs args)
Para redirecionar o usurio para a pgina de login usada 61 {
a classe Response.Redirect que recebe o nome da pgina para 62 var dataModel = new BlogEngineEntities(ConfigurationManager
63 .ConnectionStrings[BlogEngineEntities].ToString());
fazer o load.
64 var blogId = Convert.ToInt32(Session[UserId]);
Da linha 38 41 os controles TextBox so preenchidos com os 65 var list = from blog in dataModel.blogs
dados que foram trazidos do banco. Por fim, as linhas 42 e 43 66 where blog.admin_mail.ToLower() == args.Value.ToLower() &&
67 blog.id != blogId
preenchem o controle GridView.
68 select blog.admin_mail;
Com os dados carregados na pgina o usurio pode realizar 69 args.IsValid = list == null || list.Count() == 0;
alteraes nos dados do blog. Quando clicar no boto para enviar 70 }
os dados, algumas validaes vo ser feitas. A primeira a que Listagem 16. Enviando alteraes
verifica se o nome do blog no est duplicado. Este cdigo pode
ser conferido na Listagem 14. 72 protected void btnSend_Click(object sender, EventArgs e)
73 {
Este mtodo est vinculado com o CustomValidator do campo 74 if (!Page.IsValid)
de texto para o ttulo do blog. Sua funo criar a conexo com o 75 return;
banco de dados e verificar se existe outro blog com id diferente do 76
77 var model = new BlogEngineEntities(ConfigurationManager
blog carregado que tenha o mesmo ttulo. Isto porque se simples- 78 .ConnectionStrings[BlogEngineEntities].ToString());
mente comparar o ttulo do blog, vai trazer um registro sempre, 79 var blog = new BlogEngine.blogs()
ou seja, referente ao prprio blog. 80 {
81 id = Convert.ToInt32(Session[UserId]),
Assim, na linha 53 a condio para comparao da instruo 82 admin_mail = txtMail.Text,
LINQ compara o nome do blog fazendo a converso para upper 83 admin_name = txtAuthor.Text,
84 name = txtName.Text,
case antes e tambm o id do blog que foi obtido atravs da vari-
85 description = txtDescription.Text
vel de sesso e convertido para um valor inteiro na linha 51. 86 };
Realizada esta validao, outra que feita no lado do servidor 87 model.AddObject(blogs, blog);
88 model.ExecuteStoreCommand(
usando um componente do tipo customvalidator referente ao
89 UPDATE blogs set admin_mail={0}, admin_name={1}, name={2},
endereo de e-mail. O cdigo para esta validao segue o mesmo description={3} where id={4},
princpio usado na validao do ttulo do blog e pode ser conferido 90 blog.admin_mail, blog.admin_name, blog.name, blog.description, blog.id);
91 Page.ClientScript.RegisterStartupScript(this.Page.GetType(),
na Listagem 15. 92 000,
Este cdigo deve obter o id do blog e verificar se outro blog com 93 <script>alert(Dados atualizados com sucesso.)</script>);
um id diferente do que est carregado possui um endereo de 94 }

e-mail igual ao que foi passado.

Edio 25 Easy .Net Magazine 25


Desenvolvendo um blog com ASP.NET Parte 1

Este mtodo inicia-se verificando a validade da pgina lem-


brando que at chegar neste ponto todos os validadores j foram
disparados antes de continuar com a execuo.
Na linha 77 novamente criado um objeto Data Model para
realizar a conexo.
Da linha 79 86 criado um objeto do tipo blog, contendo os
dados que vo ser alterados. Neste mtodo apenas os campos
que esto disponveis na pgina para alterao que sero
atualizados.
O objeto acrescentado ao Data Model para fazer a atualizao
no banco na linha 87.
Na linha 88 est um ponto muito interessante do Entity
Framework que a capacidade de executar consultas SQL de
atualizao parametrizadas. Note que est sendo definida
uma instruo SQL Update com os parmetros sendo passados
para a instruo semelhante ao formato usado para a instruo
String.Format. Assim, possvel atualizar apenas alguns cam-
pos do banco sem precisar altear o objeto inteiro no banco.
A Linha 91 finaliza a execuo do mtodo fazendo com que seja
gerado um cdigo em JavaScript que para o usurio vai resultar
em uma janela com uma mensagem de alerta do browser.
Com este mtodo finalizam-se os cdigos que atualizam os
dados do blog. A prxima etapa desta pgina chamar a pgi- Figura 17. Pgina para criao do post
na para cadastrar um post novo. Isto feito com um clique no
boto btnNewPost. O cdigo que responde este evento pode
ser conferido na Listagem 17.
a aplicao para a pgina de login, onde a carga da sesso feita
ao autenticar o usurio.
Listagem 17. Chamando pgina para novo post
Seguindo nesta pgina, aps preencher o contedo da publicao
96 protected void btnNewPost_Click(object sender, EventArgs e) e clicar no boto para enviar os dados, a validao da pgina
97 { feita com os validadores que foram definidos no seu layout e o um
98 Response.Redirect(NewPost.aspx);
99 }
mtodo respondendo ao evento click do boto executado.
Este mtodo est descrito na Listagem 20.
O mtodo para manipular o click do boto verifica se a pgina
Este um mtodo bem simples que apenas redireciona o usurio est vlida e chama um segundo mtodo insertNewPost para
para a pgina correta que vai ser descrita a seguir. fazer a insero dos dados no banco.
Este mtodo, descrito a partir da linha 22 cria um novo objeto
Pgina de criao de post referente a publicao usando a classe post (linhas 24 33). Aps
A pgina de criao do post deve disponibilizar os campos isso, instancia o Data Model (linha 34) que far a comunicao
para o usurio inserir uma publicao nova. Como no estamos com o banco de dados e adiciona o objeto criado ao Data Model.
considerando ainda aspectos de formatao, a pgina est bem Em seguida verifica na linha 38 se as mudanas puderam ser
simples e o seu layout pode ser conferido na Figura 17. enviadas para o banco, em caso positivo, novamente executa um
Nesta pgina vo estar disponveis alm dos campos e do boto script dinmico mostrando um alerta para o usurio de operao
para enviar os dados, um link para a pgina de gerenciamento do bem sucedida e limpa os controles para inserir um novo post com
blog. A listagem da marcao HTML para esta pgina pode ser o mtodo clearData linha 43.
conferida na Listagem 18. O mtodo que faz a limpeza dos controles est descrito na
A Tabela 5 contm os detalhes dos controles usados nesta Listagem 21.
pgina. Este mtodo usa um enumerador Page.Form.Controls para
Como j feito na pgina de gerenciamento do blog, necessrio percorrer todos os controles existentes na pgina ASP.NET.
verificar a sesso do usurio nesta pgina. A Listagem 19 de- Na linha 50 faz um testes para verificar o tipo do controle.
monstra o evento Page_Load. Somente os controles do tipo TextBox que podero ser limpos.
Novamente tudo o que o mtodo precisa fazer verificar se h Na linha 51 aps converter o item da enumerao para o tipo
uma varivel de sesso carregada. Caso no exista, redireciona correto, define o contedo da propriedade texto para vazio.

26 Easy .Net Magazine Edio 25


Listagem 18. Marcao HTML da pgina de criao do post
<%@ Page <asp:TextBox
Language=C# runat=server
AutoEventWireup=true ID=txtSubtitle
CodeBehind=NewPost.aspx.cs Columns=100
Inherits=BlogEngine.NewPost %> MaxLength=100 /><br />
<!DOCTYPE html PUBLIC -//W3C//DTDXHTML1.0Transitional//EN Palavraschave<br />
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd> <asp:TextBox
<html xmlns=http://www.w3.org/1999/xhtml> runat=server
<head runat=server> ID=txtKeywords
<title>BlogEngine- Novapublicao</title> Columns=100
<script type=text/javascript src=scripts.js></script> Rows=5
</head> TextMode=MultiLine
<body> MaxLength=1000 /><br />
<h1>BlogEngine- Criarnovapublicao</h1> Texto<br />
<table style=width:100%> <asp:TextBox
<tr> runat=server
<td><a href=BlogStartPage.aspx>Gerenciar Blog</a> ID=txtContent
- Criarnovapublicao</td> Columns=100
<td align=right><a href=Default.aspx>Sair</a></td> TextMode=MultiLine
</tr> Rows=15
</table> MaxLength=5000 /><br />
<hr /> <asp:RequiredFieldValidator
Useestapginaparaenviarumanovapublicao.<br /> runat=server
<form id=form1 runat=server> ID=ContentRequiredFieldValidator
Ttulo<br /> ErrorMessage=necessrioinformarumcontedoparaopost.
<asp:TextBox Display=Dynamic
runat=server ControlToValidate=txtContent /><br />
ID=txtTitle <asp:Button
Columns=100 runat=server
MaxLength=100 /><br /> ID=btnSend
<asp:RequiredFieldValidator OnClientClick=confirmacao(Confirmaoenviodestepost?);
runat=server Text=Enviar
ID=TitleRequiredFieldValidator onclick=btnSend_Click />
ErrorMessage=necessrioinformarumttuloparaopost. </form>
Display=Dynamic </body>
ControlToValidate=txtTitle /><br /> </html>
Subttulo<br />

Controle Propriedade Valor


ID txtTitle
TextBox Columns 100
MaxLength 100
ID TitleRequiredFieldValidator
ErrorMessage necessrio informar um ttulo para o post.
RequiredFieldValidator
Display Dynamic
ControlToValidate txtTitle
ID txtSubtitle
TextBox Columns 100
MaxLength 100
ID txtKeywords
Columns 100
TextBox Rows 5
TextMode MultiLine
MaxLength 1000
ID txtContent
Columns 100
TextBox TextMode MultiLine
Rows 15
MaxLength 5000
ID ContentRequiredFieldValidator
ErrorMessage necessrio informar um contedo para o post.
RequiredFieldValidator
Display Dynamic
ControlToValidate txtContent
ID btnSend
Button OnClientClick confirmacao(Confirma o envio deste post?);
Text Enviar
Tabela 5. Controles da pgina de criao de publicao

Edio 25 Easy .Net Magazine 27


Desenvolvendo um blog com ASP.NET Parte 1

Listagem 19. Carga da pgina

10 protected void Page_Load(object sender, EventArgs e)


11 {
12 if (Session[UserId] == null)
13 Response.Redirect(Default.aspx);
14 }

Listagem 20. Inserindo novo post

16 protected void btnSend_Click(object sender, EventArgs e)


17 {
18 if (Page.IsValid)
19 insertNewPost();
20 }
21
22 private void insertNewPost()
23 {
24 var post = new posts()
Figura 18. Inserindo arquivo de script
25 {
26 id = 0,
27 post_title = txtTitle.Text, Em um projeto ASP.NET voc pode ter vrios arquivos Java
28 post_subtitle = txtSubtitle.Text, Script. Lembrando apenas de usar o que for necessrio.
29 date_created = DateTime.Now,
30 content = txtContent.Text,
Estes arquivos devem ser ligados com suas pginas ASP.NET e
31 keywords = txtKeywords.Text, ao serem carregadas tem tambm o contedo destes carregado
32 id_blog = Convert.ToInt32(Session[UserId]) para o lado do cliente. Ento, quando maior o nmero de scripts,
33 };
34 var model = new BlogEngineEntities(ConfigurationManager maior ser a demora.
35 .ConnectionStrings[BlogEngineEntities].ToString()); A funo (ou mtodo se preferir) para exibir uma janela de con-
36 model.AddObject(posts, post);
37 firmao personalizada pode ser conferida na Listagem 22.
38 if (model.SaveChanges() > 0)
39 {
40 Page.ClientScript.RegisterClientScriptBlock(this.Page.GetType(), Listagem 22. Script
41 001,
42 <script>alert(Post includo com sucesso!)</script>); functionconfirmacao(msg){
43 clearData(); returnconfirm(msg);
44 } }
45 }

Listagem 21. Limpando os controles


Trata-se de um script bastante simples que recebe como argu-
47 private void clearData()
mento uma mensagem que exibida usando o mtodo confirm
48 {
49 foreach (var item in Page.Form.Controls) nativo do JavaScript.
50 if (item is TextBox) Para poder usar este arquivo de script nas pginas do projeto,
51 (item as TextBox).Text = ;
52 } basta adicionar na marcao HTML, junto marcao <HTML>
a tag como abaixo:

Definindo o arquivo de script <head runat=server>


<title>BlogEngine - Nova publicao</title>
Durante a elaborao do projeto voc percebeu que foi usada <script type=text/javascript src=scripts.js></script>
uma referncia para um mtodo escrito em JavaScript em alguns </head>
controles Button:
Concluso
<asp:Button A criao de um gerenciador de blogs extensa e envolve muitos
runat=server
ID=btnSend itens, alguns extremamente complexos que sero deixados de
OnClientClick=confirmacao(Confirma o envio deste post?); lado por enquanto nesta srie. Nesta primeira parte, foi possvel
Text=Enviar
entender a parte bsica de como comear a criar aplicaes Web
onclick=btnSend_Click />
no ASP.NET. Espero vocs nas prximas edies.
O mtodo chamado confirmao exibe uma janela de dilogo
com os botes OK/Cancelar e uma mensagem, que passada para Vladimir Rech
o mesmo como argumento. vladimirrech@yahoo.com.br http://vladimirrech.blogspot.com
Este mtodo est escrito em um arquivo JavaScript que foi acres- Tecnlogo em Desenvolvimento de Sistemas pelo CEFET/UTF-PR,
trabalha com desenvolvimento de sistemas em .NET destacando-se
centado para o projeto usando a janela para adicionar novos itens.
aplicaes Windows, ASP.NET e Webservices. Mantm um blog onde escreve
Os detalhes desta janela esto na Figura 18. sobre diversos assuntos relacionados a programao e ao Framework .NET.

28 Easy .Net Magazine Edio 25


Seo .Net Nesta seo voc encontra artigos bsicos sobre as tecnologias .net

Iniciando com
Threads no C#
T
hreads refere-se tcnica em que a execuo de
um determinado processo (tarefa) dividido em Resumo DevMan
dois ou mais processos, permitindo a execuo
de diversas tarefas de maneira concorrente. De que se trata o artigo:
O conceito de multithreading apresenta um modelo de O artigo trata de como utilizar threads no C#, tornando possvel que sua
programao que permite executar mltiplas tarefas, aplicao execute N tarefas ao mesmo tempo. Desta forma, um processo
compartilhando recursos de um processo e executan- no ir depender de outro para ser executado, por exemplo.
do de forma independente. Logo, o programador deve
evitar que duas ou mais threads operem em um mesmo Em que situao o tema til:
recurso (arquivo, endereo de memria ou conexo A conexo com um banco de dados pode ser um processo demorado e
de rede) Um sistema que utiliza multithreading possui em alguns casos este processo realizado na inicializao de uma aplica-
melhor desempenho em computadores com mltiplos o. Esta demora pode causar ao usurio a impresso de que a aplicao
ncleos de processamento, pois esses ncleos permitem esteja travada. Neste contexto, uma forma de evitar esta situao
que as tarefas de cada thread sejam executadas de forma utilizar uma thread para realizar este processo de conexo, permitindo
simultnea. Este escalonamento de tarefas (multithreads) que a aplicao trabalhe demais processos enquanto a conexo no
permite que threads trabalhem de maneira simultnea e concluda, por exemplo, gerar e exibir formulrios da aplicao. Esse
independente, logo, o programador deve evitar que duas um dos exemplos em que as threads podem ser utilizadas.
ou mais threads operem em um mesmo recurso (arquivo,
endereo de memria ou conexo de rede). Caso acon- Iniciando com Threads no C#:
tea a aplicao apresentar um erro conhecido como O suporte a threads no contexto de aplicaes (softwares) um recurso
deadlock. Theads devem ser programadas para cooperar fornecido pelo prprio Sistema Operacional. Uma thread responsvel
e no competir. O escalonamento (Nota do DevMan 1) por executar tarefas dentro de uma aplicao. O conceito de multithrea-
entre threads segue a mesma lgica do escalonamento ding aplicado quando estas tarefas so divididas em duas ou mais thre-
entre processos. Um mtodo que busca evitar situaes ads, buscando diminuir o tempo de processamento destas tarefas. O .NET
de deadlock conhecido como Thread safety. Este conceito oferece um componente que manipula threads dentro de uma aplicao,
ser abordado no decorrer do artigo. chamado BackgroundWorker. Este artigo introduz o conceito de threads
Para exemplificar threads, ao realizar um Ctrl + Shift + e apresenta uma implementao para conexo com o banco de dados,
Del em seu computador e acessando a opo Iniciar o utilizando uma thread, por meio do componente BackgroundWorker.
Gerenciador de tarefas possvel notar que o sistema
operacional Windows trabalha com vrias tarefas ao
mesmo tempo, como pode ser visto na Figura 1.
Em uma situao onde um determinado processamen- Nota do DevMan 1
to seja realizado por um processador de cinco ncleos,
em teoria, o processador seria capaz de realizar cinco Escalonamento de processos uma atividade organizacional feita pelo escalonador da CPU. O
aplicaes ao mesmo tempo, porm, existem outros di- escalonador escolhe o processo que tem mais prioridade e menos tempo e coloca-o na memria
principal, desta maneira o processador evita ficar ocioso.
versos aplicativos em execuo. Isso possvel porque o
processador consegue trabalhar com todos os aplicativos Para que o multithreading seja manipulado corretamente, as linhas de execuo devem ser
sincronizadas para que os dados sejam processados na ordem correta. Desta maneira trabalhar
e apresentar resultados satisfatrios devidos veloci- com este conceito requer muito cuidado na implementao, pois todas as threads que esto sendo
dade de seu processamento. Sendo assim os aplicativos manipuladas dentro devem funcionar muito bem sincronizadas, principalmente se estiverem
parecem estar em execuo simultaneamente. trabalhando com variveis dependentes. Sendo assim, deve ser respeitada a ordem em que foram
escalonadas, para evitar um possvel deadlock.
Assim como os processos, as threads possuem estados
em seu ciclo de vida, dentro de um sistema as aes e Deadlock caracterizado por um impasse entre dois ou mais processos, sendo assim impedidos de
continuar suas execues, ou seja, bloqueados.
ordens de uma thread so controladas por uma tabela
de threads que armazena informaes de seu fluxo de

Edio 25 Easy .Net Magazine 29


Iniciando com Threads no C#

execuo, o nome desta tabela Thread TCB (Task Control Block) e O uso de threads traz muitos benefcios, alguns deles podem
a mesma contm: ser destacados:
O endereo da pilha; Velocidade de criao das threads: as threads so mais fceis
O contador de programa; de criar e destruir que os processos, pois elas no tm quaisquer
Registrador de instrues recursos associados a elas. Em alguns sistemas criar um thread
Registradores de dados, endereos, flags; pode ser cem vezes mais rpido do que criar um processo.
Endereos das threads filhas; Capacidade de resposta: a utilizao do multithreading pode
Estado de execuo. permitir que um programa continue executando e respondendo
ao usurio mesmo se parte dele est bloqueada ou executando
A comunicao entre threads pode ser realizada por meio de uma tarefa demorada. Por exemplo, enquanto um navegador Web
variveis globais do processo que as criou. Existem tcnicas que carrega uma figura ele permite a interao com o usurio.
podem ser utilizadas para realizar o sincronismo das mesmas, Compartilhamento de recursos: todos os recursos alocados e
como monitores e semforos, que possuem recursos capazes utilizados pelo processo aos quais pertencem so compartilhados
de indicar a ordem de execuo dos processos e so utilizadas pelas threads.
para evitar condies concorrncia. A Figura 2 apresenta um Economia: como as threads compartilham recursos dos processos
exemplo de processos com apenas uma ou com mltiplas threads aos quais pertencem, mais econmico criar e realizar a troca de
(multithreading). contexto de threads (Nota do DevMan 2).

Nota do DevMan 2
Troca de contexto de threads uma ao onde uma thread pode sair do perodo de processamento
e outra pode assumir seu lugar, sem que sua tarefa esteja concluda. Quando a thread retomar
seu processo, ela ser restaurada do ponto onde parou. Este termo tambm conhecido como
chaveamento ou mudana de contexto.

Utilizao de arquiteturas com multiprocessadores: possvel


executar cada uma das threads criadas para um mesmo processo
em paralelo, usando multiprocessadores. Isso aumenta bastante
os benefcios do esquema multithreading.
Desempenho: obtido quando h grande quantidade de com-
putao e E/S, as threads permitem que essas atividades se so-
breponham e consequentemente que melhore o desempenho da
aplicao.

Threads em C#
Todos os programas desenvolvidos em C# possuem uma
thread, conhecida como thread principal, que responsvel
por controlar a execuo total de um programa. Porm, em
muitos casos esta thread principal acaba sendo sobrecarregada
devido ao acmulo de tarefas que necessitam ser executadas ao
Figura 1. Gerenciador de tarefa do MS Windows.
mesmo tempo. Para estes casos, aplica-se multithreading, onde
os processos so divididos e assim seu tempo de execuo
reduzido. Por exemplo, enquanto a thread principal se encar-
rega de trabalhar interfaces com o usurio, como carregar
formulrios e componentes dos mesmos, uma segunda pode
se responsabilizar por manter a conexo com o banco de dados
(Nota do DevMan 3).
Existem inmeras maneira de implementar threads em softwa-
res. Talvez a mais simples seja criar um mtodo exclusivo para
execuo da tarefa desejada dentro de uma classe, como pode ser
Figura 2. Processos utilizando uma ou mltiplas threads visto na Listagem 1.

30 Easy .Net Magazine Edio 25


ou dados incorretos, pois uma thread pode desfazer o que outra
Nota do DevMan 3 thread realizou. Existem tcnicas que podem auxiliar para que
as threads operem em modo thread-safety. Para representar estas
O processo de comunicao com o banco de dados ou o aguardo de alguma instruo de I/O so tcnicas, ser utilizado o mesmo mtodo ExecutarThread() j
timos casos para serem processados em uma nova thread (delegada pela thread principal), pois visto na Listagem 1.
desta maneira evita-se que uma thread principal fique travada, aguardando a resposta do banco de
dados ou de uma instruo de I/O. Utilizando o mtodo lock() os recursos sero bloqueados at que
a thread que o est utilizando termine o seu processo, como pode
ser visto na Listagem 3.

Listagem 1. Gerenciando uma thread. Listagem 3. Mtodo thread safety lock().

01 publicclassExemploThread 01 privatevoidExecutarThread()
02{ 02 {
03publicvoidChamarThread() 03 objectbloqueador=newobject();
04{ 04 boolok;
05System.Threading.ThreadStartts= 05
06newSystem.Threading.ThreadStart(ExecutarThread); 06 lock(bloqueador)
07System.Threading.Threadt= 07 {
08newSystem.Threading.Thread(ts); 08 if(!ok)
09t.IsBackground=true; 09{
10t.Start(); 10MessageBox.Show(Exemplobloqueiodethreads);
11} 11ok=true;
12 12}
13privatevoidExecutarThread() 13 }
14{ 14 }
15//Cdigoaserexecutadopelathread
16}
17}
Enquanto a thread estiver em estado bloqueado (lock), como foi
Listagem 2. Iniciando uma thread. aplicado na linha 6, ela no consome recursos do sistema. O estado
01 ExemploThreadet=newExemploThread(); lock muito utilizado onde existe muita condio de concorrn-
02 et.ChamarThread(); cia para evitar que um programa entre em estado de deadlock.
Outra maneira de realizar essa espera entre threads utili-
zando o mtodo Join(), que tem seu funcionamento parecido ao
A thread t, criada na linha 7, tem a responsabilidade de iniciar a lock(). Porm no mtodo Join() quando a thread atual finalizar
execuo de uma nova thread em segundo plano. Desta maneira, sua execuo, a thread em espera ir retomar automaticamente
assim que a thread em primeiro plano terminar sua execuo, sua execuo. Na Listagem 4 nota-se que a thread principal ir
automaticamente as aes da thread t (que opera em segundo aguardar a execuo total do mtodo atribudo a thread ts, para
plano) so interrompidas. ento prosseguir a execuo do sistema.
O mtodo Start() o responsvel por executar a thread t, e quando
executado uma propriedade da thread chamada IsAlive marca- Listagem 4. Mtodo thread safety Join().
da como true, indicando que a thread est em execuo. Quando
01 publicvoidChamarThread()
esta thread terminar seu trabalho o valor desta propriedade ser 02 {
false. Neste exemplo, a thread t responsvel por executar todo o 03 System.Threading.ThreadStartts=
04 newSystem.Threading.ThreadStart(ExecutarThread);
bloco de instrues presente no mtodo ExecutarThread(), como
05 System.Threading.Threadt=
foi definido na linha 5 e a propriedade IsBackground indica que 06 newSystem.Threading.Thread(ts);
a thread t ser executada em segundo plano. Desta maneira, as 07 t.IsBackground=true;
08 t.Start();
aes da thread t sero escalonadas juntamente com as aes da
09 t.Join();
thread principal e a thread t ser interrompida assim que a thread 10 Console.WriteLine(aThreadtfinalizousuaexecuo!);
principal terminar de executar suas tarefas. 11 }
12
A Listagem 2 apresenta a classe ExemploThread instanciada e 13 privatevoidExecutarThread()
a chamada ao ChamarThread()que inicia a thread. 14 {
15 for(inti=0;i<10;i++)
16 Console.WriteLine(contando:+i+/n);
Thread safety 17 }
Este conceito aplicado para programas multithreading e diz-se
que um cdigo thread-safety quando ele executado simultanea-
mente de maneira correta entre vrias threads. Caso o cdigo no Na Figura 3 pode ser visto o resultado da execuo deste mto-
seja thread-safety, o programa pode apresentar erros inesperados do, utilizando o mtodo Join(), onde exibida a contagem que

Edio 25 Easy .Net Magazine 31


Iniciando com Threads no C#

apresentada a cada vez que ocorre uma iterao, e apenas ao Na aplicao proposta para este artigo ser utilizado este compo-
realizar o final da contagem o programa finalizado. nente para realizar uma conexo com o banco de dados segura, no
Na Figura 4 o mesmo mtodo da Listagem 4 apresentado, consumindo processamento da thread principal do programa. Esta
porm sem utilizar o mtodo Join(). Note ento que a thread t, tarefa ficar sob total responsabilidade do BackgroundWorker.
responsvel pela contagem, foi bloqueada e finalizada assim Desta maneira, caso o acesso ao banco de dados seja lento, o
que a thread principal terminou sua execuo, sem finalizar a programa no ficar travado. Para este projeto ser utilizada uma
contagem. aplicao Windows Form Application com o Visual Studio 2010.
Na Figura 5 possvel visualizar a tela j finalizada do sistema
onde, aps a conexo com o banco de dados ser bem sucedida, uma
barra de progresso (componente ProgressBar) ser carregada,
alm de alterar o texto de um label de status para conectado
caso a conexo com o banco de dados seja bem sucedida.

Nota do DevMan 4
O componente BackgroundWorker nativo da biblioteca .NET e se encontra no grupo Components
dentro da Toolbox .
Figura 3. Resultado do mtodo ExecutarThread(), utilizando Join()

Figura 4. Resultado do mtodo ExecutarThread(), sem utilizar Join()

Ao ser utilizado o mtodo Sleep(),recebe-se um valor como


parmetro que ir atribuir um tempo de espera para manter a
thread em estado bloqueado. Desta maneira, ela no ir consumir
recursos da CPU. Na Listagem 5 o mtodo ExecutarThread() ser
executado aps trs mil milissegundos (convertidos para segun-
dos, trs segundos).

Listagem 5. Mtodo thread safety Sleep().

1 System.Threading.ThreadStartts=
Figura 5. Componentes do projeto
2newSystem.Threading.ThreadStart(ExecutarThread);
3 System.Threading.Threadt= Para realizar a conexo com o banco de dados, sero utili-
4newSystem.Threading.Thread(ts);
5 t.Sleep(3000);
zados os seguintes namespaces: System.Data e System.Data.
SqlClient. Os mesmos possuem classes para a manipulao de
dados, mas especificamente o SqlClient, utilizado para realizar
Os mtodos Lock(), Join() e Sleep() so muito teis para tratar conexo com o banco de dados. Ambas fazem parte do ADO
o conceito de multithreading de maneira segura, ou seja, aplicar o .NET (Nota do DevMan 5).
thread safety.

Nota do DevMan 5
Tutorial
A plataforma .NET dispe de um extenso conjunto de recursos para tarefas relacionadas ao acesso
a dados. Exemplos so as tecnologias ADO.NET (ActiveX Data Object for .NET) e LINQ to SQL. No
caso do ADO.NET, os principais bancos de dados do mercado oferecem suporte para a construo de
Iniciando a aplicao solues .NET baseadas nos mesmos. Embora o ADO.NET conte com uma ampla gama de recursos que
O C# oferece um componente que realiza a manipulao de threads atendem praticamente qualquer tipo de demanda, o mesmo no possui um mecanismo nativo para
de maneira confivel, o BackgroundWorker (Nota do DevMan 4). o tratamento de dados por meio de tcnicas de orientao a objetos.

32 Easy .Net Magazine Edio 25


Evento Descrio
Realizando a conexo
Aps o BackgroundWorker ser iniciado, se este
A base de dados utilizada neste projeto uma base de dados de
DoWork evento estiver habilitado, todo o cdigo existente
exemplo disponibilizada diretamente no site da Microsoft, cha-
nele ser executado.
mada de Northwind. O endereo para download se encontra na Ocorre quando o mtodo ReportProgress() do
sesso Links deste artigo. Basta realizar o download e sua insta- ProgressChanged
BackgroundWorker chamado.
lao, caso seja utilizado os procedimentos normais da instalao, Ocorre quando o evento DoWork for concludo, o
a base de dados est disponvel em C:\SQL Server 2000 Sample RunWorkerCompleted BackgroundWorker for cancelado ou se uma excep-
Databases\NORTHWND.DBF. Para facilitar a manipulao do tion for disparada.
banco de dados exemplo, copie o arquivo NORTHWND.DBF para Tabela 1. Aes do componente BackgroundWoker()
a pasta /bin/debug do projeto criado no Visual Studio 2010.
Para manipular o banco de dados sero utilizados um DataSet
e um SqlConnection (Nota do DevMan 6). Veja na Listagem 6 a
declarao destes atributos e tambm da string de conexo com
o banco de dados.

Nota do DevMan 6
O SqlConnection um componente que representa uma conexo de rede com o banco de dados
SQL Server e o DataSet um componente da arquitetura ADO.NET responsvel por manipular e
representar as tabelas de banco de dados.

Figura 6. Diagrama de atividade do componente BackgroundWorker

Listagem 6. Declarao dos atributos DataSet, SqlConnection e da string de


conexo. Listagem 7. Mtodo construtor do formulrio Form1.

1 publicpartialclassForm1:Form
01 publicForm1()
2 {
02 {
3 publicDataSetds;
4 SqlConnectionconn; 03 InitializeComponent();
5 04
6 publicstringConexao=DataSource=.\\SQLEXPRESS; 05 //Ajusta
AttachDbFilename=+Environment.CurrentDirectory+ 06 this.backgroundWorker=newBackgroundWorker();
\\NORTHWND.mdf;IntegratedSecurity=True;ConnectTimeout=30; 07 this.backgroundWorker.DoWork+=
UserInstance=True; 08 newDoWorkEventHandler(backgroundWorker_DoWork);
7 } 09 this.backgroundWorker.ProgressChanged+=
10 newProgressChangedEventHandler(backgroundWorker_ProgressChanged);
11 this.backgroundWorker.RunWorkerCompleted+=
As aes do componente BackgroundWorker so controla- 12 newRunWorkerCompletedEventHandler(
das por meio de trs eventos: DoWork(),ProgressChanged() e 13 backgroundWorker_RunWorkerCompleted);
14 this.backgroundWorker.WorkerReportsProgress=true;
RunWorkerCompleted(). A compreenso destes eventos extre-
15 this.backgroundWorker.RunWorkerAsync();
mamente necessria, pois a partir deles sero aplicadas as regras 16 }
de negcio para a conexo com o banco de dados. Veja como os
mesmos funcionam na Tabela 1.
Uma forma mais detalhada da ordem dos mtodos do Back- Eventos do BackgroundWorker
groundWorker pode ser visualizada em um Diagrama de ativi- Na Listagem 7 o componente BackgroundWorker foi instanciado
dade, que pode ser visto na Figura 6. e na sequncia seus trs eventos de manipulao foram invocados.
Uma dica muito interessante no uso do BackgroundWorker A propriedade WorkerReportProgress foi alterada para true, ou seja,
no manipular objetos de interface de usurio dentro do evento o BackgroundWorker habilitado para reportar atualizaes que
DoWork(). Para realizar estas tarefas recomendvel utilizar o ocorram no seu andamento. Por fim, o mtodo RunWorkerAsync()
evento ProgressChanged(). Existe uma maneira de manipular foi invocado. Este mtodo responsvel pelo incio da execuo
interfaces de usurio no evento DoWork() e ser apresentada do BackgroundWorker, ou seja, inicia em uma nova thread todas
ainda neste artigo. aes que sero geradas.
No mtodo construtor do Form1 sero implementadas a execu- Na Listagem 8 possvel notar que o evento DoWork() respon-
o destes trs eventos do BackgroundWorker. Na Listagem 7 svel por realizar a conexo com o banco de dados NORTHWND.
possvel verificar o mtodo construtor do Form1. DBF que foi adicionado ao /bin/debug do projeto, porm, alm

Edio 25 Easy .Net Magazine 33


Iniciando com Threads no C#

de realizar esta conexo, alguns componentes do .NET foram


inseridos para demonstrar o sucesso dessa conexo, como um Nota do DevMan 7
Label e um ProgressBar. O ProgressBar ter sua barra de status
carregada para demonstrar a conexo realizada e o Label ter O BeginInvoke() um mtodo assncrono e se responsabiliza por estabelecer a comunicao com
sua propriedade Text alterada para conectado!! e seu campo componentes ou recursos que se encontram em outra thread de forma imediata.
ForeColor para verde, indicando o sucesso da conexo com o
arquivo de banco de dados.
Nota do DevMan 8
Listagem 8. O evento DoWork.
Excees (Exceptions) so objetos gerados como resultado de eventos inesperados durante a
01 privatevoidbackgroundWorker_DoWork(objectsender, DoWorkEventArgse) execuo de um sistema. Tais ocorrncias podem ser reflexas de falhas motivadas por dados invlidos
02 { fornecidos por usurios, operaes incorretas por parte deste ou ainda, pelo acesso do programa
03 this.backgroundWorker.ReportProgress(0); considerado a recursos indisponveis num dado momento (como bancos de dados relacionais ou Web
04 conn= newSqlConnection(Conexao); Services). A classe Exception (pertencente ao namespace System) a base para a representao de
05 quaisquer erros dentro de aplicaes construdas atravs da plataforma .NET.
06 try
07 { Tipos que derivem de Exception podem ser classificados em:
08 conn.Open(); Excees pr-definidas: representam erros previstos pelo prprio .NET Framework, herdando da
09 this.BeginInvoke( classe SystemException (implementao derivada do tipo bsico Exception);
10 newAction(() =>
11 { Excees customizadas: podem basear-se diretamente em Exception, porm recomenda-se que voc
12 this.lblStatus.Text= Conectado!!; evite a herana (direta ou no) do tipo SystemException. Com isto torna-se possvel diferenciar erros
13 this.lblStatus.ForeColor= Color.Green; definidos por desenvolvedores para o atendimento de necessidades especficas daquelas produzidas
14 }) por estruturas prprias da plataforma .NET.
15 );
16 }
17 catch (Exceptionex)
18 {
No evento ProgressChanged() o argumento e recebe o va-
19 MessageBox.Show(Erro + ex.Message); lor fornecido pelo mtodo ReportProgress(), que neste caso,
20 } representa uma porcentagem a qual atribuda ao componente
21 this.backgroundWorker.ReportProgress(100);
22 }
ProgressBar, indicando a porcentagem 0 no incio do mtodo e
100 ao realizar a conexo com o banco de dados.
Realizados estes passos, o processo para realizar a conexo com
Na linha 3 da Listagem 8 possvel verificar que o Background o banco de dados est pronto e j possvel interagir com ele,
Worker invoca o mtodo ReportProgress() passando por parmetro porm, erros podem ocorrer quando esta conexo for realizada,
o valor 0 (zero) e, aps realizar toda a tarefa de conexo na linha 21, e neste projeto o evento responsvel por verificar erros o evento
o valor 100 passado. Quando este mtodo invocado, o evento RunWorkerCompleted(), como pode ser visto na Listagem 10.
ProgressChanged() disparado e esses valores so atribudos Lembrando que este evento chamado aps a execuo do evento
para representar a porcentagem de progresso da ao. Quando DoWork().
o valor 100 atribudo, a ProgressBar totalmente carregada.
Porm, foi utilizada uma tcnica no convencional para realizar Listagem 9. O evento ProgressChanged.privatevoidbackgroundWorker_
ProgressChanged(objectsender,ProgressChangedEventArgse)
esta tarefa, pois o lblStatus pertence ao formulrio principal
e o mesmo se encontra na thread principal do programa, visto {
que o this se refere ao Form1 e para alterar seu estado no this.progressBar.Value=e.ProgressPercentage;
}
mtodo DoWork() (mtodo que executa as aes do Background
Worker) necessr io ut il i zar o mtodo Beg i n Invoke() Listagem 10. O evento RunWorkerCompleted.
(Nota do DevMan 7), que pode ser visto na linha 9 e respon-
privatevoidbackgroundWorker_RunWorkerCompleted(objectsender,Run-
svel por realizar uma interao com a thread principal (a thread WorkerCompletedEventArgse)
principal responsvel por manipular o Form1 e seus compo- {
nentes) de maneira assncrona, ou seja, mesmo o mtodo sendo if(e.Error!=null)
{
disparado de outra thread a ao ser realizada. Caso esta intera- MessageBox.Show(e.Error.Message);
o entre threads seja realizada sem utilizar o mtodo BeginIn- }
}
voke(), uma exception (Nota do DevMan 8) principal atravs de
uma thread secundria. Na linha 8 o atributo conn estabelece
uma conexo com o banco de dados, utilizando o mtodo Open(). Na Listagem 10 tambm pode ser visto que o evento RunWorker-
O evento ProgressChanged()pode ser visualizado na Listagem 9, Completed() apresenta a exception por meio do argumento
lembrando que este evento disparado quando o mtodo e apresentando sua propriedade Error e caso o mtodo
ReportProgress utilizado pelo BackgroundWorker. CancelAsync()do BackgroundWorker seja invocado, cancelando a

34 Easy .Net Magazine Edio 25


thread. Esta ao tambm poderia ser capturada por e.Cancel. Para novo formulrio e, caso a conexo esteja travada, este formulrio
testar este evento, altere sua string de conexo forando para que iria abrir independente disso.
a mensagem da exception seja apresentada em um MessageBox, Na Listagem 11 possvel verificar como o componente Sql-
como pode ser visto na Figura 7. DataAdapter do C# instancia uma instruo select, passando
A classe MessageBox utilizada para mostrar dilogos na tela, por parmetro a instruo em forma de string e o atributo que
sua utilizao acontece em projetos do tipo Windows Forms (Nota recebeu a conexo com o banco de dados no evento DoWork() do
do DevMan 9), por exemplo. A mesma possui um mtodo deno- BackGroundWorker.
minado de Show, onde voc deve informar alguns parmetros,
por exemplo, a mensagem a ser exibida.

Figura 8. Conectado com sucesso

Figura 7. Erro ao realizar conexo com o banco de dados. importante salientar que no exemplo anterior no foi adiciona-
do nenhum parmetro em nossa query. Caso isso fosse necessrio,
uma boa prtica de programao no concatenar diretamente
Nota do DevMan 9 os valores da query, visto que sua aplicao se tornaria vulne-
rvel a um ataque via SQL Injection (Nota do DevMan 10). Na
Windows Forms uma tecnologia do .NET Framework presente desde as primeiras verses da
Listagem 12 possvel visualizar um exemplo vulnervel. Isso
plataforma, sendo um dos principais meios para o desenvolvimento de aplicaes dotadas de
interfaces grficas. Estas so acionadas atravs da execuo de programas executados a partir do acontece pelo fato do usurio mal intencionado ter a possibilidade
ambiente Windows. O Windows Forms corresponde, basicamente, continuao na plataforma de colocar todos os tipos de caractere por um campo de entrada
.NET do conjunto de padres e recursos que eram empregados na construo de aplicaes visuais
por meio do Visual Basic clssico e de outras ferramentas como Delphi. O desenvolvimento nesta da aplicao.
tecnologia gira em torno da construo de formulrios (janelas), as quais herdam o tipo bsico
Form (namespace System.Windows.Forms). Dentro do Visual Studio existe um excelente suporte Listagem 11. Select na tabela Categories do banco de dados NORTHWND.
para a elaborao de aplicaes baseadas em Windows Forms. Esta IDE oferece uma ampla gama de
controles visuais como botes, caixas de texto/seleo, grids etc.Tais componentes sendo combinados
SqlDataAdapterda=newSqlDataAdapter(SELECT*FROMCategories,conn);
e inseridos em formulrios, de forma a criar aplicaes com interfaces leves, com um aspecto visual
satisfatrio e que atendam aos mais variados tipos de demanda.
ds=newDataSet();

//PreencheoDataSetcomoSqlDataAdapter
Buscando dados do banco de dados da.Fill(ds);

Porm, se tudo ocorrer normalmente e nenhuma exception for


//exibidonoDataGridViewasinformaesda tabela Categories
apresentada, aps conexo com o banco de dados, os componentes dataGridView1.DataSource=ds.Tables[0];
Label e ProgressBar sero apresentados da forma como pode ser
Listagem 12. Exemplo Vulnervel.
visto na Figura 8.
Uma vez que a conexo esteja disponvel, as interaes com SqlDataAdapter da = new SqlDataAdapter(SELECT * FROM Categories WHERE
o banco de dados podem ocorrer de maneira normal, pois o Name = + txtNome.Text + , conn);
BackgroundWorker tratou essa questo em uma thread separada
ds=newDataSet();
e tornou esta funcionalidade mais dinmica. Na Listagem 10
possvel visualizar o cdigo que contm no evento click do boto //PreencheoDataSetcomoSqlDataAdapter
Listar categorias onde, aproveitando a conexo realizada, o da.Fill(ds);
DataGridView recebe um select, listando as categorias do banco
de dados NORTHWND. Uma forma de realizar o teste clicando //exibidonoDataGridViewasinformaesda tabela Categories
dataGridView1.DataSource=ds.Tables[0];
no boto Form2, onde o mesmo responsvel por instanciar um

Edio 25 Easy .Net Magazine 35


Iniciando com Threads no C#

Caso fosse necessrio a utilizao de parmetros no exemplo a compreenso de forma clara sobre a seqencia de processamen-
da Listagem 12, voc poderia utilizar a classe SqlCommand to e o que est sendo realizado pela thread e tambm possvel
em conjunto com o SqlDataAdapter, conforme o exemplo da aplicar um controle de erros ou um controle de transio atravs
Listagem 13. destes eventos, evitando assim deadlocks.
Na aplicao modelo pode ser visto como o BackgroundWorker
realizou o tratamento de uma conexo com o banco de dados,
Nota do DevMan 10 aplicando um controle de exception nesta conexo, aumentando
assim seu desempenho e sua usabilidade do programa. Outro
SQL Injection (termo tambm conhecido em portugus como Injeo de SQL) uma forma de ponto forte foi combinar o componente ProgressBar com o Back-
ataque que busca explorar vulnerabilidades em aplicaes que utilizem bancos de dados relacionais. groundWorker, visto que o ProgressBar um componente muito
Assim, um usurio interessado em promover aes deste gnero, procura inserir caracteres especiais
e comandos SQL em parmetros que so enviados a uma base (a partir de formulrios de cadastro ou til dentro de um sistema para manter o usurio informado que o
filtros em telas de pesquisa), de maneira que o processamento de tais instrues leve a alteraes e mesmo no est travado e quanto ser a espera de tarefas. Os even-
outros danos indesejveis a um banco de dados. tos do BackgroundWorker facilitam a aplicao da ProgressBar.

Everton Coimbra de Arajo


Listagem 13. Exemplo com parmetros
everton@utfpr.edu.br http://twitter.com/evertonfoz
// Cria um Sql Adapater Desde 1987 atua na rea de treinamento e desenvolvimento. mestre
SqlDataAdapter da = new SqlDataAdapter(); em Cincia da Computao, e professor efetivo da UTFPR, Campus
Medianeira. Tem atuado tambm em cursos de EaD oferecidos pela UAB e
// SqlCommand para atribuir o comando SQL e referenciar os parmetros ETEC. Tem se dedicado s disciplinas relacionadas ao desenvolvimento de
SqlCommand cmd = new SqlCommand(SELECT * FROM Categories +
WHERE Name = @Name AND City = @City, conn);
aplicaes web e na persistncia de objetos, focando seus estudos e pesquisas na plataforma
Java (JSP, Servlets, JSF), .NET (ASP.NET e Windows Forms) e AJAX. autor da Visual Books,
// Adiciona os parmetros com seus devidos tipos com seis livros j publicados. Tem oferecido palestras em seminrios de informtica, voltados
cmd.Parameters.Add(@Name, SqlDbType.NVarChar, 50); tanto para o meio acadmico como para o empresarial.
cmd.Parameters.Add(@City, SqlDbType.NVarChar, 30);

// Atribui o SqlCommand ao Data Adapater


da.SelectCommand = cmd; Giuvane Conti
giuvane.conti@gmail.com
// Cria o DataSet
DataSet ds = new DataSet(); Graduando em Tecnologia em Anlise e Desenvolvimento de
Sistemas pela UTFPR Campus Medianeira. Trabalha na era de
// Preenche o DataSet com o SqlDataAdapter desenvolvimento de sistemas com uma certa experincia em C#, PHP, Entity
da.Fill(ds); Framework e LINQ e conhecimento em banco de dados SQL Server e MySQL.
// exibido no DataGridView as informaes da tabela Categories
Atualmente seu interesse na rea de desenvolvimento de aplicaes na plataforma .NET
dataGridView1.DataSource = ds.Tables[0]; e Geoprocessamento, utilizando C#.

Concluso MSDN. BackgroundWorker


Neste artigo foi demonstrado o funcionamento e os benefcios http://msdn.microsoft.com/en-us/library/system.componentmodel.
do uso de threads em um sistema, como aumentar o seu desem- backgroundworker.aspx
penho, j que threads, assim como processos, trabalham com MSDN. THREADS
escalonamento de tarefas, dividindo seu tempo de processamento http://msdn.microsoft.com/en-us/library/system.threading.thread.aspx
e aumentando sua velocidade de processamento.
O BackgroundWorker mantm o controle de threads dentro de Banco de dados NORTHWIND
um sistema de forma organizada, seus mtodos e eventos facilitam http://www.microsoft.com/en-us/download/details.aspx?id=23654

36 Easy .Net Magazine Edio 25


Seo .Net Nesta seo voc encontra artigos bsicos sobre as tecnologias .net

Primeiros passos com o


namespace System.IO
Conhea as classes para leitura

T Resumo DevMan
rabalhar com arquivos, diretrios e operaes
de IO uma tarefa considerada trivial para
desenvolvedores. Certamente a grande maioria De que se trata o artigo:
das aplicaes ainda necessita realizar o tratamento de O artigo apresenta as classes que o .NET framework dispe para realizar-
arquivos, diretrios, leitura de imagens, vdeos e outros mos o tratamento de arquivos, diretrios do sistema e drives instalados
dados que esto armazenados tanto no disco rgido no sistema operacional, utilizando prticas que podem melhorar o de-
como em bancos de dados relacionais. A m utilizao sempenho e manter a segurana nas atividades relacionadas a operaes
de comandos para estas operaes podem comprometer IO (entradas e sadas) em aplicaes .NET.
a estrutura de uma aplicao inteira. Desta forma, para
facilitar as operaes I/O em aplicaes .NET, o .NET Em que situao o tema til:
framework dispe de um namespace especfico para Na grande maioria dos sistemas desenvolvidos, existe a necessidade
estas tarefas. Trata-se do namespace System.IO. Com as de trabalharmos com arquivos organizados em diretrios no disco
classes disponibilizadas neste namespace, o desenvol- rgido da mquina ou leitura de drives e localizao, manipulao e
vedor pode manipular diretrios, arquivos e drivers armazenamento de informaes. Quando necessitamos manter alguma
do sistema operacional, alm de manipular leitura e informao que no seja em bancos de dados relacionais, precisamos
reproduo de udio, vdeo, imagens etc. manter estas informaes organizadas de uma forma que permita a
Este conjunto de classes so derivadas do tipo FileSys- leitura pela aplicao.
temClass, que nada mais que um conjunto de classes
especializadas em manipulao de informao para Primeiros passos com o namespace System.IO:
arquivos, drivers e diretrios. Alm deste conjunto de Neste artigo veremos quais as classes disponveis no .NET framework
classes, este namespace disponibiliza uma srie de ou- que possibilitam a manipulao/edio e excluso de arquivos fsicos e
tras classes, que tratam das mais variadas operaes de diretrios de sistema em conjunto com as funcionalidades disponveis
I/O possveis, como escrita e leitura em arquivos. pelo sistema operacional. Vamos entender a leitura das informaes
importantes de arquivos, diretrios e drives como, por exemplo, localiza-
A Classe FileSystemInfo o, verificao de propriedades, tamanho, espao disponvel no sistema
No namespace System.IO temos uma srie de classes operacional e monitoramento de alteraes.
distintas, sendo cada uma aplicada a um tipo de objeto
diferente no sistema operacional.
A classe FileSystemInfo, a princpio, serve apenas como
classe base, conforme os princpios da Orientao a Ob- A Classe FileInfo
jetos, onde temos uma classe mais generalizada para dar A classe destinada a fornecer informaes de armazenamento
origem classes mais especficas. Ela foi implementada de arquivos no sistema operacional a classe FileInfo. Com ela
justamente para que suas classes filhas (especializadas conseguimos obter, a partir do endereo de um arquivo, a data
como FileInfo) possuam um conjunto de propriedades de criao do arquivo, nome, extenso, atributos etc. Ela possui
e mtodos em comum, no sendo necessrio reescrever todos os mtodos e propriedades da classe FileSystemInfo (j que
os mesmos mtodos em cada classe filha. FileInfo herda de FileSystemInfo), porm, ela tambm possui as
Para conhecermos melhor as propriedades e mtodos suas propriedades e mtodos especficos, caso contrrio, no se
da classe FileSystemInfo, vamos analisar a Tabela 1, onde justificaria a sua criao. Para conhecermos melhor estes mtodos
so listadas as propriedades e a Tabela 2, onde so apre- e propriedades, podemos analisar a Tabela 3 e Tabela 4, onde so
sentados os seus mtodos. mostrados os atributos e mtodos respectivamente.

Edio 25 Easy .Net Magazine 37


Primeiros passos com o namespace System.IO

Propriedade Descrio
permite manipular informaes dos atributos do arquivo ou diretrio que est sendo analisado. Atributos so um conjunto de informaes
utilizadas tanto pelo sistema operacional, aplicaes ou at mesmo pelo usurio, para definir comportamentos de arquivo ou diretrio. Um
Attributes
exemplo de atributo de um arquivo o famoso Somente Leitura. Para verificar todos os atributos possveis de um arquivo ou diretrio,
podemos analisar o enumerador contido no mesmo namespace da classe FileSystemInfo, denominado FileAttributes.
CreationTime permite informar ou ler informao da data em que o arquivo ou diretrio foi criado.
tem como nico objetivo retornar se o arquivo ou diretrio analisado atravs do endereo informado existe ou no no sistema operacional.
Exists
Neste caso a propriedade somente retorna valor e no permite ser alimentada (modificada).
Extension retorna a extenso de um arquivo, por exemplo, em arquivo com o nome File.txt retornar a extenso txt.
retorna o caminho completo do arquivo ou diretrio no sistema operacional, desde o drive inicial at o nome do arquivo ou diretrio no
FullName
sistema.
LastAccessTime informa a data e hora do ltimo acesso de um arquivo ou diretrio.
LastWriteTime informa a data e hora da ltima manipulao de escrita realizada em um arquivo ou diretrio no sistema operacional.
Name diferente da FullName, esta propriedade retorna apenas o nome do arquivo ou diretrio, sem o caminho ou extenso do mesmo.

Tabela 1. Propriedades da classe FileSystemInfo


Mtodo Descrio
Delete responsvel por excluir o arquivo ou diretrio do sistema operacional.
Refresh atualiza as informaes (referente ao armazenamento) do arquivo ou diretrio no sistema operacional.

Tabela 2. Mtodos da classe FileSystemInfo


Propriedade Descrio
retorna uma instncia da classe DirectoryInfo, que responsvel pelas informaes do diretrio onde o arquivo est armazenado no sistema
Directory
operacional. A classe DirectoryInfo ser vista mais adiante.
DirectoryName informa o nome do diretrio onde o arquivo est gravado no sistema operacional.
IsReadOnly define se o arquivo analisado est marcado para Somente Leitura ou no. No pode ser alterada, pois uma propriedade de somente leitura.
Lenght retorna a informao do tamanho do arquivo analisado, em bytes.

Tabela 3. Propriedades da classe FileInfo.

Mtodo Descrio
AppendText retorna uma instncia da classe StreamWriter, que a classe responsvel por permitir que sejam escritas ou adicionadas informaes no arquivo.
CopyTo fornece a funcionalidade de copiar o arquivo analisado para uma nova localizao no sistema operacional.
cria um arquivo baseado nas informaes definidas para a classe FileInfo ao qual este executado. utilizado quando estamos criando
Create
novos arquivos.
CreateText alm de criar um arquivo, permite escrever um texto no mesmo. Esta funcionalidade ser vista em maior detalhe mais adiante.
Decrypt utilizado para descriptografar um arquivo criptografado.
Encrypt realiza a criptografia de um arquivo.
MoveTo permite que o arquivo que est sendo analisado, seja movido (no cria cpia) para outra localizao no sistema operacional.
Open acessa o arquivo analisado com privilgios especficos, como leitura, escrita etc.
OpenRead permite acessar o arquivo analisado somente como leitura.
OpenText acessa o arquivo analisado e retorna uma instncia da classe StreamReader a qual permite realizar a leitura do contedo de um arquivo.
OpenWrite acessa o arquivo com permisso somente de escrita, ou seja, somente permitido incluir informaes no arquivo.
Replace utilizado para substituir informaes do arquivo.

Tabela 4. Mtodos da classe FileInfo

Neste momento j conhecemos as funcionalidades e possibilida- Caso o desenvolvedor tente instanciar a mesma, receber um erro
des que a classe FileInfo nos permite na manipulao de informa- j em modo de design no cdigo.
es dos arquivos. Referente classe FileSystemInfo, ela no per- Para ilustrar a utilizao da classe FileInfo, podemos verificar
mite ser instanciada, ou seja, no possvel criar um objeto deste o cdigo da Listagem 1, onde estamos retornando informaes
tipo, pois como sua principal funo ser a base de outras classes, de um arquivo denominado Teste.txt localizado no drive C:\ do
esta foi criada como uma classe abstrata (Nota do DevMan 1). sistema operacional. Para fins de exemplo, o arquivo em questo

38 Easy .Net Magazine Edio 25


foi marcado para "Somente Leitura". Logo aps ler as informaes FileInfo, esta classe tambm herda da classe base FileSystemInfo.
do arquivo Teste.txt, vamos criar uma cpia do mesmo, alterando Da mesma forma que a classe FileInfo, a classe DirectoryInfo
a extenso para .doc. tambm possui suas propriedades e mtodos especficos, de-
senvolvidos para permitir a manipulao exclusiva de diretrios
do sistema. Como diretrios so apenas containers de arquivos,
Nota do DevMan 1 esta classe oferece menos opes, porm o que ela possui su-
ficiente para suprir as necessidades de diretrios. Na Tabela 5
Classes Abstratas (abstract) so classes definidas com o modificador abstract e tem por objetivo podemos verificar as propriedades desta classe e na Tabela 6
oferecer um padro estrutural para um conjunto de classes filhas ou herdadas. Elas representam seus mtodos.
um conjunto de objetos que possuem caractersticas similares definidas nesta classe. Um exemplo
de aplicao de uma classe abstrata uma classe Pessoa que pode possuir as propriedades Nome e
Idade, por exemplo. Sendo esta a base para as classes filhas como Aluno, Funcionrio, Gerente, Cliente
etc, as quais tambm tero as propriedades Nome e Idade e mais as suas propriedades especficas.
Neste caso, as propriedades comuns no precisam ser definidas nas classes herdadas, pois j esto
Nota do DevMan 2
definidas na classe abstrata. Classes abstratas permitem a definio de propriedades e mtodos,
porm no podem ser instanciadas e sim herdadas por outras classes. Console Applications so aplicaes normalmente acionadas a partir do Prompt de Comandos do
Windows, no contando com a interface grfica, que to caractersticas de aplicaes Windows
Forms ou ASP.NET. Projetos deste tipo costumam ser utilizados na implementao de utilitrios que
executam tarefas sem a interao direta de um usurio.
Como podemos verificar na Listagem 1, instanciamos um ob-
jeto com a classe FileInfo e j informamos o path do arquivo a ser
analisado/manipulado. Depois, por uma questo de segurana, Listagem 1. Manipulando Informaes de Arquivo
a fim de evitar uma exceo, verificamos se o arquivo realmente
01 using System;
existe no sistema operacional, conforme o path informado antes
02 using System.IO;
de iniciarmos a leitura das informaes do mesmo. Isto reali- 03 namespace Exemplo
zado atravs da propriedade Exists. Caso o arquivo exista, lemos 04 {
as informaes de Nome, Path e Somente Leitura do arquivo. 05 class Program
06 {
Como tnhamos marcado a propriedade "Somente Leitura" dele,
07 static void Main(string[] args)
ser retornado como "True". Aps realizar as leituras, utilizamos 08 {
o mtodo CopyTo para realizar uma cpia do arquivo e alteramos 09 FileInfo file = new FileInfo(@C:\Teste.txt);
a extenso do mesmo apenas retirando a extenso anterior (txt) e 10 if (file.Exists)
incluindo a nova desejada (doc). 11 {
12 Console.WriteLine(Nome do arquivo: {0} , file.Name);
Note que os exemplos desse artigo esto sendo construdos a
13 Console.WriteLine(Path (Caminho) do arquivo: {0}, file.FullName);
partir de um projeto Console Application (Nota do DevMan 2). 14 Console.WriteLine(Somente leitura? --> {0}, file.IsReadOnly.ToString());
Mas, nada impede de voc utilizar outro tipo de projeto, como 15 Console.Read();
ASP.NET ou Windows Forms. 16 file.CopyTo(@C:\Teste.doc);
17 }
18 }
A Classe DirectoryInfo 19 }
Para a manipulao de diretrios no sistema operacional, o .NET 20 }
framework dispe da classe DirectoryInfo. Assim com a classe

Propriedade Descrio
retorna uma instncia da classe DirectoryInfo que refere-se ao diretrio pai do diretrio analisado, ou seja, o diretrio um nvel acima. Caso
Parent
acima do diretrio atual esteja apenas o drive ou tambm conhecido como raiz, esta propriedade retorna em branco.
Root retorna a raiz do diretrio, independente do nvel em que o mesmo se encontra.
Tabela 5. Propriedades da classe DirectoryInfo
Mtodo Descrio
Create responsvel por criar um novo diretrio baseado no objeto DirectoryInfo atual.
CreateSubdirectory Como o nome deste mtodo sugere, ele realiza a criao de um subdiretrio, ou seja, um diretrio filho do diretrio atualmente analisado.
utilizado para retornar um conjunto de diretrios filhos do diretrio analisado. Retorna os diretrios em formato de array de objetos do tipo
GetDirectories
DirectoryInfo.
similar ao mtodo GetDirectories, porm ao contrrio de retornar um array com os diretrios, retorna um array dos arquivos contidos no
GetFiles
diretrio analisado. Retorna um array de objetos do tipo FileInfo.
retorna um array de objetos do tipo FileSystemInfo contidos no diretrio analisado, ou seja, retorna arquivos e diretrios, todos em um mesmo
GetFileSystemInfos
array utilizando a classe base de ambos objetos.
MoveTo da mesma forma que trabalha com arquivos, este mtodo realiza a alterao da localizao do diretrio corrente para outro local no sistema operacional.

Tabela 6. Mtodos da classe DirectoryInfo

Edio 25 Easy .Net Magazine 39


Primeiros passos com o namespace System.IO

Os mtodos e propriedades da classe DirectoryInfo so bem similarmente como fizemos com a classe FileInfo. Conforme
intuitivos, porm para vermos como a classe trabalha na prtica, possvel realizar com arquivos, tambm podemos adicionar a
vamos analisar o exemplo da Listagem 2, onde estamos realizando verificao se os diretrios existem, para que no tenhamos uma
a leitura de todos os arquivos contidos no diretrio C:\Windows e exceo em nosso cdigo, conforme a linha 10. Para que possamos
apresentando os mesmos em uma listagem no console. realizar a leitura dos arquivos que o diretrio analisado possui,
Como pode ser verificado na Listagem 2, inicialmente estamos precisamos utilizar o mtodo GetFiles() do objeto do diretrio. Na
criando uma instncia da classe DirectoryInfo e j no momento de linha 12 estamos percorrendo todos os objetos do tipo FileInfo,
instanciar a mesma estamos informando o path deste diretrio, retornados pelo mtodo GetFiles() e em seguida, estamos exibindo
o nome de cada arquivo do diretrio criando uma listagem com
os mesmos.
Listagem 2. Lista de Arquivos em C:\Windows

01 using System;
A Classe DriveInfo
02 using System.IO; Como comentamos no incio deste artigo, alm de permitir a
03 namespace Exemplo manipulao de arquivos e diretrios, o namespace System.IO
04 {
05 class Program
tambm possui a classe DriveInfo (um tanto lgico), especializada
06 { para a manipulao de drives do sistema operacional. Para enten-
07 static void Main(string[] args) dermos melhor o funcionamento da classe, veja suas propriedades
08 {
09 DirectoryInfo diretorio = new DirectoryInfo(@C:\Windows); e mtodos conforme a Tabela 7 e Tabela 8, respectivamente.
10 if (diretorio.Exists) A utilizao da classe DriveInfo no difere em praticamente nada
11 { com a classe DirectoryInfo ou a classe FileInfo. Basta instanciar
12 foreach (FileInfo file in diretorio.GetFiles())
13 { um objeto com a classe e realizar a manipulao das proprieda-
14 Console.WriteLine(Arquivo: {0}, file.Name); des e mtodos disponveis para a mesma. Para exemplificar, na
15 }
Listagem 3, vamos implementar a leitura de todos os drives ins-
16 Console.Read();
17 } talados no sistema e apresent-los em forma de lista, similarmente
18 } como fizemos com os arquivos do diretrio na Listagem 2. Alm
19 }
do nome do driver, vamos apresentar na listagem o tipo de cada
20 }
drive atravs da propriedade DriveType do mesmo.

Propriedade Descrio
retorna o espao livre do drive que est sendo analisado. Esta propriedade pode retornar um valor diferente da propriedade TotalFreeSpa-
AvaliableFreeSpace
ce, pois considera as cotas do drive por usurio.
DriveFormat retorna o tipo de formatao do drive, como NTFS ou FAT32.
retorna o tipo do drive que esta sendo analisado. Para o tipo do drive, o .NET framework possui o enumerador DriveType, o qual est loca-
lizado no mesmo namespace da classe DriveInfo (System.IO). Este enumerador pode ter os seguintes valores:
CDRom um drive ptico como leitor de CD, DVD, Blu-Ray etc.
Fixed um disco rgido local.
DriveType Network um drive mapeado na rede.
NoRootDirectory um drive que no possui um diretrio raiz.
Ram um drive do tipo RAM.
Removable um drive removvel, por exemplo, um pendrive.
Unknown um drive desconhecido. Se encaixa nesta categoria qualquer drive que no se encaixe nas demais acima citadas.
IsReady indica se o drive est pronto para ser acessado.
Name retorna o nome do drive.
RootDirectory retorna um objeto do tipo DirectoryInfo contendo as informaes do diretrio raiz do drive analisado.
TotalFreeSpace retorna o espao livre total do drive (sem considerar cotas de usurios).
TotalSize retorna o tamanho total do drive analisado.
VolumeLabel retorna ou define o rtulo para o drive analisado (somente pode setar esta informao para drives que no so somente leitura).

Tabela 7. Propriedades da classe DriveInfo

Mtodo Descrio
um mtodo esttico (Nota DevMan 3), ou seja, no necessita de uma instncia da classe para ser chamado e, tem o objetivo de retornar um array
GetDrives
de objetos do tipo DriveInfo contendo todos os drives instalados no sistema no momento da execuo.

Tabela 8. Mtodo da classe DriveInfo

40 Easy .Net Magazine Edio 25


Como podemos perceber no cdigo da Listagem 3, para chamar Listagem 3. Lista de Drives Instalados
o mtodo GetDrives, no necessitamos instanciar uma varivel do
tipo DriveInfo, pois o mtodo esttico. 01 using System;
02 using System.IO;
03 namespace Exemplo
04 {

Nota do DevMan 3 05
06
class Program
{
07 static void Main(string[] args)
08 {
Mtodos Estticos (static): so mtodos declarados com o modificador static, o qual tem por objetivo
09 foreach (DriveInfo drive in DriveInfo.GetDrives())
definir que estes mtodos podem ser invocados por outro objeto, sem a necessidade de que a classe
10 {
ao qual estes pertencem seja instanciada primeiramente. Quando um mtodo no esttico, a sua
11 Console.WriteLine(Drive: {0} - Tipo: {1}, drive.Name, drive.DriveType.
execuo est restrita necessidade da classe onde este est definido, devendo estar instanciada em
ToString());
um objeto, caso contrrio no podem ser invocados.
12 }
13 Console.Read();
14 }
A Classe FileSystemWatcher 15 }
16 }
Para finalizar a seo de classes de informao, temos a classe
FileSystemWatcher. Esta classe utilizada para monitorao de
diretrios. Quando desejamos monitorar as alteraes realizadas
em um determinado diretrio do sistema, podemos implementar Vamos verificar as principais propriedades e mtodos da classe
um objeto do tipo FileSystemWatcher. Com este objeto podemos FileSystemWatcher que esto listadas na Tabela 9 e 10 respectiva-
definir o diretrio a ser monitorado, os tipos de alteraes a serem mente. Nesta classe, alm das propriedades e mtodos, temos os
verificadas e qual ao dever ser tomada quando a alterao mo- eventos, conforme a Tabela 11.
nitorada for realizada no diretrio. Um bom exemplo de utilizao Para exemplificar a utilizao da classe FileSystemWatcher, na
da classe FileSystemWatcher a criao de uma lista de log's de Listagem 4 podemos ver a implementao de um monitora-
alterao de um determinado diretrio no sistema. mento no diretrio "C:\" do sistema operacional, onde estamos

Propriedade Descrio
contm a definio se o objeto deve disparar ou no os eventos, ou seja, a definio se estamos monitorando ou no o diretrio especifi-
EnableRaisingEvents
cado. Com isso podemos iniciar e parar o monitoramento conforme desejarmos.
em muitos casos no estamos interessados em monitorar alteraes de todos os arquivos contidos no diretrio analisado, e sim, apenas as alteraes
realizadas em alguns arquivos. Para auxiliar nesta definio, esta propriedade define um filtro para o monitoramento, onde podemos determinar
quais tipos de arquivos que desejamos monitorar. Esta propriedade recebe uma string, conforme a definio de filtro que voc deseja aplicar.
Filter
Por exemplo, se quiser filtrar um arquivo especfico, basta colocar o nome dele nesta propriedade; se deseja monitorar tipos de arquivos, como
arquivos com extenso txt pode alimentar a propriedade com o texto *.txt, porm, o uso de mltiplos filtros, como na string *.txt|*.doc no
suportada. Quando esta propriedade no for informada, realizar a monitorao de todos os arquivos por padro.
IncludeSubdirectories define se o monitoramento dever ser realizado tambm nos subdiretrios do diretrio informado.
define o tipo de alteraes a serem verificadas no monitoramento. Por padro, todas as alteraes de excluso, renomeao e modificao
de arquivos esto habilitadas. Para alimentarmos esta propriedade, o .NET framework dispe do enumerador NotifyFilter que possui as
seguintes opes:
FileName notifica alteraes no nome dos arquivos.
DirectoryName notifica alteraes no nome do diretrio.
NotifyFilter Attributes notifica alteraes em atributos dos arquivos.
Size notifica alteraes no tamanho dos arquivos.
LastWrite notifica alterao na data de ltima alterao do contedo dos arquivos.
LastAccess notifica alterao na data de ltimo acesso dos arquivos.
CreationTime notifica alterao na data de criao dos arquivos.
Security notifica alteraes nas definies de segurana dos arquivos.
Path define o endereo do diretrio a ser monitorado.

Tabela 9. Propriedades da classe FileSystemWatcher


Mtodo Descrio
Este o principal mtodo da classe FileSystemWatcher. um mtodo sncrono que retorna uma estrutura contendo informaes especficas sobre a
alterao ocorrida, onde informamos o tipo de alterao a ser monitorada como parmetro. Ele espera indefinidamente at que a alterao que est
WaitForChanged
sendo monitorada seja realizada ao menos uma vez, ento ele retorna os dados desta alterao. Este mtodo tambm possui uma segunda assinatura
onde podemos informar alm do tipo da alterao a ser monitorada, o tempo que o mesmo dever esperar por uma alterao.

Tabela 10. Mtodos da classe FileSystemWatcher

Edio 25 Easy .Net Magazine 41


Primeiros passos com o namespace System.IO

Eventos Descrio
Changed disparado quando ocorre alguma alterao em arquivo ou diretrio contido no diretrio monitorado.
Created disparado quando algum objeto (arquivo ou diretrio) criado no diretrio monitorado.
Deleted disparado quando algum objeto excludo do diretrio monitorado.
Renamed disparado quando algum objeto possui seu nome alterado no diretrio monitorado.
Error ocorre quando h um erro interno no monitoramento do diretrio.

Tabela 11. Eventos da classe FileSystemWatcher

verificando todas as alteraes (sem filtros) e estamos dispa- Na Listagem 4 iniciamos criando uma instncia da classe
rando um evento quando um arquivo ou diretrio criado ou FileSystemWatcher. Ento definimos qual o endereo do diretrio
ento quando alterado no diretrio monitorado. que desejamos monitorar, que em nosso caso o diretrio "C:\",
O acoplamento um conceito computacional que indica o grau na propriedade Path do objeto. Nas linhas 11 e 12 estamos adi-
de relacionamento entre diferentes partes de uma aplicao. cionando um manipulador de eventos, conhecido como delegate
Um alto acoplamento implica em um nvel de alta dependncia (Nota do DevMan 4) e, neste caso, do tipo EventHandler, para os
eventos de criao de arquivos e diretrios (Created) e de alterao
de arquivos e diretrios (Changed).
Listagem 4. Monitorando Diretrio

01 using System; Nota


02 using System.IO;
03 namespace Exemplo importante salientar que neste artigo no estamos centralizados nossas classes em outras, visto
04 {
que o objetivo apenas mostrar exemplos prticos. Mas, uma boa prtica de programao no
05 class Program
06 { acoplar tudo em apenas uma nica classe.
07 static void Main(string[] args)
08 {
09 FileSystemWatcher watcher = new FileSystemWatcher();
10 watcher.Path = @C:\;
11
12
watcher.Created += new FileSystemEventHandler(watcher_Created);
watcher.Changed += new FileSystemEventHandler(watcher_Changed);
Nota do DevMan 4
13 watcher.EnableRaisingEvents = true;
14 Console.Read(); Delegate um tipo que referencia um mtodo. Permite definirmos um mtodo que pode ser apontado
15 } por este tipo de objeto, similarmente como um ponteiro em linguagens como C ou C++. Os delegates
16 static void watcher_Changed(object sender, FileSystemEventArgs e) podem ser de vrios tipos, dependendo da sua utilizao:
17 {
18 Console.WriteLine(Alterado o arquivo {0}. Tipo da alterao: {1}., e. * EventHandler Delegate um tipo de delegate que tem por objetivo fazer uma referncia a um
Name, e.ChangeType.ToString()); mtodo que far o tratamento do evento disparado, ou seja, quando o evento ao qual este delegate
19 } est definido for disparado, o mtodo assinado no delegate ser executado. um tipo muito utilizado
20 static void watcher_Created(object sender, FileSystemEventArgs e) quando desejamos alterar ou incluir um comportamento diferente para um evento em nossa
21 { aplicao. Um exemplo de EventHandler Delegate a declarao e vnculo do mtodo Click de um
22 Console.WriteLine(Criado o arquivo {0}, e.Name); boto em uma formulrio .NET
23 }
24 }
25 }
Em seguida, acrescentamos a este manipulador de eventos, como
sinal de incremento += um FileSystemEventhandlerl, o qual recebe
entre os diversos componentes envolvidos, fato este que pode por parmetro um mtodo que ser invocado quando este evento
resultar em dificuldades na manuteno futura das funciona- for disparado. Em nosso exemplo, ao adicionarmos um manipula-
lidades envolvidas. Logo, o ideal que exista um baixo nvel dor para o evento de criao (Created) estamos apontando para o
de acoplamento entre as estruturas. O acoplamento est ligado mtodo watcher_Created, o qual deve receber um parmetro do tipo
a outro conceito de grande importncia na rea de software: a object, identificando de quem est sendo chamado e um objeto
coeso. Esta ltima deve ser entendida como a medida com a do tipo FileSystemEventArgs, onde esto os argumentos do evento.
qual um item (classe ou componente) atende ao objetivo inicial O mesmo fizemos com o evento de alterao (Changed) que est
que justificou a sua construo. Uma alta coeso indica que o apontando para o mtodo watcher_Changed. Estes manipuladores
elemento que se est considerando no acumula responsabili- podem ser includos de forma automtica pelo Visual Studio, para
dades alm daquelas para as quais foi especificado, sendo esta isto basta voc adicionar o sinal de incremento "+=", logo aps o
uma caracterstica perseguida por todos os projetos de software nome do evento e pressionar duas vezes a tecla TAB que os mto-
que procuram ser bem estruturados. Geralmente, um baixo dos so automaticamente criados e vinculados para voc.
acoplamento consequncia direta de um alto grau de coeso Nos mtodos, tanto de alterao quanto de criao, estamos
ao se considerarem os componentes de um sistema. exibindo informaes das alteraes realizadas no objeto

42 Easy .Net Magazine Edio 25


monitorado. Como recebemos um parmetro com os argumen- conhecermos as possibilidades que esta classe oferece, vamos
tos do tipo FileSystemEventArgs, podemos informar o nome do verificar a Tabela 12 que apresenta os mtodos desta classe, que
arquivo e o tipo de alterao, os quais esto contidos nestes possui apenas mtodos estticos.
argumentos, dentre outros possveis. Na Listagem 5 temos um exemplo de utilizao da classe Path
Por fim, na linha 13, estamos definindo o incio do monitora- onde, primeiramente, verificamos um path analisado e poste-
mento atravs da propriedade EnableRaisingEvents. Na linha 14 riormente criamos um novo path, substituindo a extenso deste
adicionamos uma leitura para que o aplicativo no termine a por outra, a fim de criarmos uma cpia do arquivo com uma
execuo, logo aps habilitar o monitoramento, assim permitindo extenso diferente.
que faamos algumas alteraes em arquivos no diretrio "C:\" e Verificando a Listagem 5, temos a criao de uma string que
vejamos as informaes apresentadas. contm o nosso path analisado. Nas linhas 10 e 11 informamos

A Classe Path
Listagem 5. Alterando extenso de Path
o estudo de todas as classes vistas anteriormente, podemos
N
verificar a existncia de uma propriedade que sempre funda- 01 using System;
mental ao funcionamento destas. Trata-se da propriedade Path. 02 using System.IO;
03 namespace Exemplo
Esta propriedade a que define o endereo do que estamos mani-
04 {
pulando, visualizando ou criando. Tendo esta importncia, o .NET 05 class Program
framework no poderia deixar de possuir uma classe especfica 06 {
para a manipulao desta propriedade. Um Path nada mais que 07 static void Main(string[] args)
08 {
um endereo de algo no sistema operacional, podendo ser um 09 string path1 = @C:\Teste.txt;
arquivo, diretrio ou drive. Se verificarmos o estudo das demais 10 Console.WriteLine(Path analisado: {0}, path1);
classes acima, veremos que ele sempre foi alimentado com uma 11 Console.WriteLine(Extenso original: {0}, Path.GetExtension(path1));
12 Console.WriteLine(Novo path, com extenso .ini: {0}, Path.
cadeia de caracteres como C:\, a qual indicou o local para onde
ChangeExtension(path1, ini));
desejamos apontar no sistema operacional. 13 Console.Read();
Para a manipulao de paths, o .NET framework dispe da 14 }
classe Path, que fornece mtodos para manipulaes em arquivos 15 }
16 }
do sistema utilizando apenas o endereo (path) do mesmo. Para

Mtodo Descrio
permite gerarmos um novo endereo de path a partir de um existente, alterando apenas a extenso do arquivo contido no path original.
ChangeExtension Este mtodo no altera a extenso do arquivo, e sim, somente a extenso do path retornado. Pode ser utilizado quando desejamos obter
o path para uma cpia de um determinado arquivo, alterando a extenso deste.
Combine permite combinar vrias strings para resultar em uma string contendo um path combinado de todas estas.
retorna o path do diretrio pai contido no path analisado. O path retornado sempre apontar para o diretrio acima do arquivo ou
GetDirectoryName
diretrio analisado no path informado.
retorna a extenso do arquivo apontado pelo path informado. Quando o path informado se refere a um diretrio ou um arquivo que est
GetExtension
sem extenso, retornada uma string em branco.
retorna o nome do arquivo especificado pelo path informado. O nome do arquivo que retornado inclui a extenso do mesmo. Quando o
GetFileName
path analisado apontar para um diretrio, retornado uma string em branco.
GetFileNameWhithout tem o mesmo objetivo do mtodo anterior, porm, o nome do arquivo retornado no possui a extenso adicionada, ou seja, retirada a
Extension informao da extenso do arquivo no nome retornado.
retorna o path completo do local onde a aplicao est sendo executada, adicionando um nome de arquivo, por exemplo. Exemplo: su-
pondo que desejamos criar um novo arquivo chamado teste.txt e que este deva estar no mesmo diretrio da aplicao que est criando
GetFullPath
o arquivo, no precisamos verificar o diretrio da aplicao para montar o path do arquivo, e sim chamar este mtodo passando o nome
do arquivo criado que o mesmo retornar o path completo do arquivo localizado no mesmo diretrio da aplicao executada.
GetPathRoot retorna o diretrio raiz do path informado.
GetRandomFileName gera um nome de arquivo randomizado, ou seja, cria um nome aleatrio para o novo arquivo, por exemplo.
retorna o path para a criao de um novo arquivo temporrio aleatoriamente utilizando o diretrio de arquivos temporrios definido para
GetTempFileName
o sistema/usurio.
GetTempPath retorna o path definido no sistema/usurio como diretrio de arquivos temporrios.
HasExtension retorna a informao se o path analisado possui uma extenso.
IsPathRooted retorna a informao se o path analisado possui um diretrio raiz.

Tabela 12. Mtodos da classe Path

Edio 25 Easy .Net Magazine 43


Primeiros passos com o namespace System.IO

o path analisado para o usurio e a extenso do mesmo com a Fabio Rosa


utilizao do mtodo esttico GetExtension da classe Path. Por fabiorosa.net@gmail.com
fim, na linha 12 estamos informando ao usurio o novo path Analista Programador h 4 anos, da equipe de desenvolvimento da
com a extenso alterada para ".ini", utilizando o mtodo esttico empresa Lgica Informtica. Domnio em UML, SQL Server, WPF,
ChangeExtension da classe Path. Silverlight, Windows Forms e GeneXus. Cursando Anlise e Desenvolvi-
mento de Sistemas pela UNOPAR.
Concluso
este artigo foi possvel entender as classes para a manipula-
N .NET Framework System.IO
o de informaes referentes a arquivos, diretrios e drives no http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-
sistema operacional. Com estas classes o leitor ter condies de US&k=k(SYSTEM.IO);k(TargetFrameworkMoniker-%22.NETFRAMEWORK%
iniciar trabalhos em verificaes, manipulaes de informaes 2cVERSION%3dV4.0%22);k(DevLang-CSHARP)&rd=true
do sistema operacional e at mesmo criar um sistema de log's de Classe FileInfo - .NET Framework 4.5
alteraes em determinados diretrios no sistema operacional. http://msdn.microsoft.com/pt-br/library/system.io.fileinfo.aspx
As classes apresentadas neste artigo no so a totalidade das
classes de manipulao de informaes disponibilizadas no na- Namespace System.IO.Compression
mespace System.IO do .NET framework, e sim, apenas as classes http://msdn.microsoft.com/pt-br/library/system.io.compression.aspx
mais relevantes deste namespace, pois existem muitas classes a ASP.Net - Usando a Classe System.IO.Path
mais disponibilizadas neste. http://www.baboo.com.br/conteudo/modelos/ASPNet-Usando-a-Classe-
Podemos verificar que o .NET framework possuiu uma total SystemIOPath_a48104_z396.aspx
integrao com o sistema operacional, o que permite que qual-
Artigo DriveInfo Class
quer alterao de IO (entrada e sada) seja possvel ao usurio/
http://msdn.microsoft.com/en-us/library/system.io.driveinfo.aspx
desenvolvedor atravs dele, permitindo que as aplicaes possam
conversar com o sistema operacional de uma maneira segura, DriveInfo.GetDrives Method
simples e estruturada. http://msdn.microsoft.com/en-us/library/system.io.driveinfo.getdrives.aspx

44 Easy .Net Magazine Edio 25


Edio 25 Easy .Net Magazine 45

Anda mungkin juga menyukai