Você está na página 1de 47

Sumrio

.NET 06 Criptografia Segurana de dados com .NET


[ Ericksen Viana Sampaio ]

15 - System.Diagnostics Parte 1
.Net

Boa Ideia
[ Fabio Gouw ]

Ol, eu sou o DevMan! Desta p-


gina em diante, eu estarei lhe aju-

.Net 27 Desenvolvendo um blog com ASP.NET Parte 2 dando a compreender com ainda
[ Vladimir Rech ] mais facilidade o contedo desta
edio. Ser um prazer contar com
sua companhia! Confira abaixo o
que teremos nesta revista:
Expediente Editorial

EDITORIAL

O
l pessoal, a segurana da informao um assunto cada vez mais discuti-
do na comunidade e no mercado de T.I e justamente por este motivo que
trouxemos na capa desta edio um artigo sobre criptografia de dados em
.NET, do nosso amigo Ericksen Sampaio, onde o mesmo aborda os principais concei-
tos a respeito desta tcnica e nos demonstra com um exemplo prtico como sim-
ples e fcil implementar rotinas de criptografia em nossos sistemas .NET, visto que o
mesmo j encapsula os algoritmos de criptografia mais difundidos no mercado.
Ano 3 - 27 Edio 2013 - ISSN 2179624-6
Alm disso, Fabio Gouw inicia uma srie onde nos dar uma verdadeira aula sobre
como implementar logs e realizar um monitoramento eficiente e elegante de nossas
aplicaes .NET, com a primeira parte do artigo sobre o uso de logs de eventos e dos
contadores de desempenho do Windows, nos apresentando os principais conceitos
Corpo Editorial por trs do mesmo. Com este artigo do Fbio voc com certeza ter muito mais
armas para combater problemas de desempenho e estabilidade de suas aplicaes,
alm de conseguir atuar de maneira preventiva se antecipando a possveis proble-
mas que possam vir a ocorrer em seus sistemas. Este artigo imperdvel.
Editor Geral
Ricardo Coelho (rcoelhorj@gmail.com) E para finalizar, dando continuidade ao artigo sobre a construo de blogs no ASP
.NET Vladimir Rech aborda aspectos de usabilidade com um breve uso do AjaxCon-
trolToolKit, alm de destacar aspectos fundamentais da interface com o usurio, nos
Jornalista Responsvel
apresentando conceitos e tcnicas extremamente valiosas do uso de folhas de estilo.
Kaline Dolabella - JP24185

Espero que gostem desta edio, um grande abrao e uma excelente leitura para
Na Web todos!
www.devmedia.com.br/revista-easy-dotnet-magazine

Atendimento ao Leitor Ricardo Coelho


A DevMedia conta com um departamento exclusivo para o atendimento ao leitor. Se voc tiver algum
Ricardo Coelho rcoelhorj@gmail.com
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: Editor Chefe da .net Magazine e Easy .net Magazine
www.devmedia.com.br/central
(21) 3382-5038

Publicidade
Para informaes sobre veiculao de anncio na revista ou no site e para fechar parcerias ou aes
Fale com o Editor!
especficas de marketing com a DevMedia, entre em contato com:
muito importante para a equipe saber o que voc est achando da revista: que tipo de artigo voc
gostaria de ler, que artigo voc mais gostou e qual artigo voc menos gostou. Fique a vontade para
Cristiany Queiroz
entrar em contato com os editores e dar a sua sugesto!
publicidade@devmedia.com.br
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:

Ricardo Coelho Editor da revista


rcoelhorj@gmail.com

Assine agora e tenha acesso a


todo o contedo da DevMedia:
www.devmedia.com.br/mvp
Criptografia
Criptografando dados em .NET

H Resumo DevMan
pouco tempo, quando a tecnologia ainda
no era muito presente em nosso cotidiano,
as informaes e grande parte dos processos Criptografia:
organizacionais eram geridos basicamente no papel, A criptografia uma tcnica utilizada h anos que com o passar
sendo armazenados em armrios ou cofres protegidos do tempo evoluiu a ponto de oferecer solues eficazes no que diz
por cadeados ou senhas. respeito segurana da informao. Hoje, ela uma ferramenta de
Atualmente este paradigma mudou, pelo menos para segurana amplamente utilizada nos meios de comunicao e consiste
uma parcela significativa da sociedade. As informaes basicamente na transformao de determinado dado ou informao
so processadas e armazenadas em meios digitais, a fim de ocultar seu real significado.
criando uma forte dependncia entre os sistemas de Este artigo apresenta os conceitos sobre criptografia, seus tipos, apli-
informao e as organizaes. Com o advento da in- cabilidade e como ela empregada no .NET por meio do namespace
ternet, os dados trafegam em meios pblicos, podendo System.Security.Cryptography. Ao final do artigo ser desenvolvida
ser interceptado por qualquer um que esteja mal inten- uma aplicao para criptografar dados usando um algoritmo simtrico.
cionado. Neste cenrio, uma falha na segurana destes Alm disso, iremos criar uma DLL contendo a classe de criptografia
contedos pode acarretar em enormes prejuzos para implementada, que poder ser reutilizada em outros projetos.
uma corporao. Ento, o que fazer para garantir tal
segurana? Existem diversos meios de proteo e um Em que situao o tema til:
deles o uso da criptografia. Ela no vai impedir que A criptografia pode ser utilizada em aplicaes e ambientes cuja
uma determinada informao seja interceptada, mas segurana das informaes algo relevante para o projeto, prin-
tem o objetivo de dificultar a compreenso do dado cipalmente em sistemas WEB, onde o dado trafega em um meio
capturado. Mas como isso feito? H vrios algoritmos pblico correndo um risco maior de ser interceptado, fato este que
de criptografia que cumprem este papel, cada um com pode gerar prejuzos enormes para uma organizao. O domnio
suas particularidades, porm a ideia central a mesma: das tcnicas de criptografia no algo complexo quando estamos
modificar a informao de forma que apenas o destina- trabalhando com o paradigma orientado a objetos, sendo essencial
trio consiga compreender a que foi transmitido. para a criao de aplicaes seguras.
Vale ressaltar que a criptografia no aplicada apenas
quando um dado enviado de um local a outro, ela
utilizada tambm em dispositivos de armazenamento
de dados (ex: discos rgidos, pen drives, storages), que
so alvos de ataques e roubos. Ou seja, de uma forma ento faz uso do algoritmo para descriptografar a mensagem e
geral, a criptografia vai garantir a confidencialidade aplica a mesma chave que foi utilizada pelo emissor para voltar
da informao. Nos prximos tpicos, veremos alguns mensagem em sua forma original. Sem a mesma, no possvel
conceitos relacionados a esta tcnica. decifrar a informao recebida.
Uma forma muita utilizada por invasores para descobrir esta
Criptografia simtrica chave utilizando a fora bruta, onde so utilizadas inmeras
A criptografia simtrica foi o primeiro tipo de cripto- combinaes de caracteres na tentativa de uma delas ser a chave
grafia criado. Os algoritmos que a utilizam tm como do algoritmo. Veja na Figura 1 o processo de criptografia simtri-
caracterstica principal o uso de uma mesma chave ca. Observe que a mesma chave utilizada nos algoritmos para
criptogrfica (Nota do DevMan 1) para criptografar cifragem e decifragem do texto.
ou descriptografar uma informao, por isso o adjetivo Como vantagens deste mtodo podemos citar a simplicidade na
simtrico d nome a esta tcnica. Exemplificando um sua implementao, uma vez que utilizada uma nica chave no
pouco este conceito, quando um emissor cifra uma men- processo de cifragem e decifragem do dado, alm da velocidade
sagem com um algoritmo de criptografia simtrico, ele deste processo em relao criptografia assimtrica, que vere-
utiliza uma chave, que representada por uma senha ou mos nos prximos tpicos, possibilitando assim que uma grande
um conjunto de bits para codificar os dados. O receptor quantidade de dados seja encriptada em pouco tempo.

6 Easy .Net Magazine Edio 27


aquela informao foi cifrada pelo dono da chave privada, uma
Nota do DevMan 1 vez que esta deve ser mantida em segredo e sob posse de seu
dono. Pelo fato desta tcnica garantir a autoria e autenticidade
Chave criptogrfica um conjunto de caracteres formando uma sequncia de bits que trabalhando em da mensagem e de seu proprietrio os algoritmos de chave assi-
conjunto com um algoritmo de criptografia iro determinar o resultado final do processo de cifragem mtrica so utilizados no processo de assinatura digital (Nota
e decifragem da mensagem. O nvel de segurana da codificao depende tanto do algoritmo quanto
do tamanho da chave escolhida (total de bits que ela possui). do DevMan 2). A Figura 2 demonstra o processo realizado pela
criptografia assimtrica.
A segurana no processo de distribuio de chaves uma das
vantagens da criptografia assimtrica em relao simtrica, j
que a chave privada no precisa ser compartilhada, apenas as
chaves pblicas. Mas toda esta segurana tem um custo, o que
gera algumas desvantagens. Podemos destacar a complexidade
dos algoritmos, que precisam reconhecer as duas chaves para
realizar a cifragem e decifragem, fator este que acaba causando
lentido nestes processos.
Alguns algoritmos simtricos conhecidos so: DH (Diffie-Hell-
man), ECDH (Elliptic Curve Diffie-Hellman) ElGamal, RSA.

Figura 1. Processo de criptografia simtrica. Nota do DevMan 2


Assinatura digital um mtodo utilizado para garantir a autenticidade e integridade da informao
or outro lado este modelo de criptografia apresenta algumas
P em documentos e arquivos digitais, muito utilizado no envio de documentos pela rede pblica.
falhas que esto relacionadas gerao e compartilhamento das Essa garantia resultado de um processo criptogrfico que utiliza um algoritmo e chaves pblicas
e privadas para autenticar e permitir a leitura da informao. Vale destacar que assinatura digital
chaves: no primeiro caso uma chave muito simples pode ser fa- no o mesmo que assinatura digitalizada. Esta ltima refere-se a uma imagem da assinatura de
cilmente quebrada utilizando um algoritmo de fora bruta. J na determinada pessoa, sem nenhuma segurana ou amparo legal.
segunda situao deve-se atentar para a forma como as chaves
so compartilhadas entre os interessados na informao, a fim de
evitar que a mesma seja obtida por um invasor.
Alguns algoritmos de criptografia simtrica bem conhecidos
so: DES (Data Encryption Standart), Triple DES, AES (Advan-
ced Encryption Standard), IDEA (International Data Encryption
Algorithm), Blowfish, RC4.

Criptografia assimtrica
A criptografia assimtrica, tambm denominada como cripto-
grafia de chave pblica, possui como caracterstica bsica o uso
de duas chaves ao invs de uma, sendo elas:
Chave pblica: Chave que pode ser distribuda para outros
usurios.
Chave privada. Chave que deve ser mantida em segredo.

Neste modelo de criptografia temos dois cenrios:


1 - Texto cifrado pela chave pblica que somente poder ser de- Figura 2. Processo de criptografia assimtrica
cifrado com a chave privada.
2 - Texto cifrado pela chave privada que apenas a chave pblica Criptografia x Codificao
conseguir decifrar a mensagem. Quando falamos em criptografia importante destacar sua dife-
rena em relao codificao de um texto. Na codificao no
Observe que no primeiro caso atingimos um requisito da necessrio nenhum tipo de chave para transformar a informao
segurana da informao, a confidencialidade, pois apenas o e o sigilo da mensagem no o objetivo desta tcnica, at porque
proprietrio da chave privada conseguir ler a mensagem. J os meios para decodificar a mensagem so pblicos e de simples
na segunda situao conseguimos observar outro requisito, execuo. A codificao est mais relacionada com a interpretao
a autenticidade, pois quem possui a chave pblica sabe que da mensagem por outros sistemas.

Edio 27 Easy .Net Magazine 7


Criptografia

Como exemplos de padres de codificao conhecidos, podemos Other Project Types => Visual Studio Solution. O template Blank
citar: Base64, ASCII e Unicode Solution ir aparecer. Nossa solution ter o nome de Criptogra-
J a criptografia tem como principal meta o sigilo da informao, fiaEasyNet. Veja os passos descritos anteriormente na Figura 3.
fazendo uso de algoritmos complexos e sistema de chaves para
atingir seu propsito.

Criptografia em .NET
O .NET oferece uma srie de classes para trabalharmos com
criptografia simtrica e assimtrica em nossas aplicaes. Todas
estas classes esto presentes no namespace System.Security.
Cryptography.
Este namespace fornece uma gama de classes de algoritmos
de criptografia, dentre eles podemos citar os algoritmos RSA e
DAS, para criptografia assimtrica. J na criptografia simtrica
ele oferece, dentre outras, a classe Rijndael, que ser apresentada
nos prximos tpicos deste artigo durante a implementao da
aplicao para criptografia de dados.

Aplicao
Aps toda a teoria apresentada, vamos parte prtica. O objetivo
criar uma aplicao simples em ASP .NET onde primeiramente Figura 3.Template Blank Solution
ser realizado um cadastro de usurios contendo apenas o nome
e senha. A senha ser criptografada utilizando o algoritmo de Agora que temos uma soluo vazia criada, devemos adicionar
criptografia simtrico Rijndael e gravada em um banco de dados, a Class Library e o projeto web na mesma. Para isso, basta clicar
juntamente com o nome do usurio. Depois esta senha ser re- com o boto direito em cima da solution e escolher a opo Add =>
cuperada e descriptografada utilizando o mesmo algoritmo, para New Project. Desta vez, tanto o template da Class Library quanto
autenticar o acesso do usurio. o do projeto web (ASP.NET Web Application), esto localizados
A arquitetura da aplicao ser composta pelo projeto WEB, no mesmo sub menu: Visual Studio C#. O nome dado a Class
onde estaro presentes as pginas da aplicao e uma classe para Library e Web Application foram, respectivamente, Seguranca
a persistncia dos dados, e outra camada criada especialmente e CriptografiaWEB.
para conter a classe de criptografia. A estrutura do projeto fica como na Figura 4. Observe que
Vale ressaltar que esta no uma arquitetura ideal para o de- em nossa Solution temos os dois projetos criados. Um passo
senvolvimento de aplicaes, pois a classe de persistncia est importante que deve ser feito referenciarmos a Class Library
localizada na mesma camada das interfaces. Porm, como foco (Nota do DevMan 3) no projeto WEB. Para isto, basta clicar com
do artigo a criptografia, no iremos nos preocupar com esta o boto direito no projeto WEB e selecionar Add Reference. Na
questo. janela que ser apresentada, clique na aba Projects e selecione o
projeto Seguranca. Veja que na pasta references da aplicao web
j aparece o arquivo segurana incluso. Desta forma, podemos
usar as classes criadas no projeto Seguranca dentro do projeto
Tutorial CriptografiaWeb, bastando apenas fazer uma referncia utilizando
a clusula using.

Estrutura do projeto Nota do DevMan 3


Vamos inicialmente criar uma soluo vazia para o projeto onde
sero acrescentados o projeto WEB, e uma Class Library, que ser Uma Class Library, ou biblioteca de classes, so classes que podem ser utilizadas nos projetos .NET
disponibilizando servios para o desenvolvimento das aplicaes. O Visual Studio fornece um template
o repositrio da classe responsvel pela criptografia. A ideia de para a criao de uma Class Library. O resultado da compilao deste tipo de projeto uma DLL que
isolarmos esta classe em outra camada possibilitar que depois pode ser utilizada em outros projetos, independente da linguagem utilizada, desde que seja .NET.
de compilado o Class Library, a DLL que for gerada possa ser
utilizada em outros projetos, permitindo que a criptografia seja
reaproveitada em outras aplicaes .NET. A classe de criptografia
Para criar uma soluo vazia, abra o Visual Studio, clique em A classe de criptografia ficar no projeto Segurana, para que
File => New Project. Na lista de templates apresentada, selecione este projeto possa ser reutilizado para outras aplicaes .NET.

8 Easy .Net Magazine Edio 27


Para criptografar os dados ser utilizado o algoritmo de cripto- baseado em uma mesma chave. A vantagem desta tcnica que ela
grafia simtrico Rijndael. O algoritmo faz parte da especificao dificulta o trabalho de quem tenta obter a chave inserida a partir
de encriptao AES (Advanced Encryption Standard), padro do dado transformado, uma vez que trar resultados diferentes.
este mundialmente utilizado. O Rijndael suporta chaves de 128, Por fim, os bytes do texto a ser cifrado so atribudos a varivel
192 e 256 bits. Por exemplo, se quisermos criar uma chave de 128 bytesTexto (declarada na linha 4).
bits, podemos utilizar 16 caracteres em sua confeco (1byte=8bits Perceba que todas as variveis so declaradas com o modifica-
16bytes=128bits). Lembrando que no ser demonstrado o algo- dor de acesso private, pois apenas a prpria classe ter acesso a
ritmo interno utilizado pelo Rijndael para criptografar os dados, elas.
vamos apenas utilizar seus mtodos para realizar tal tarefa. As atribuies a estas variveis so feitas pelo mtodo setaVa-
Em primeiro lugar, sero definidas algumas variveis e constan- lores, conforme pode ser visto na Listagem 2.
tes para a classe. A Listagem 1 apresenta estas estruturas:
Listagem 2. Mtodo SetaValores

Listagem 1. Variveis da classe Criptografia


01 private static void SetaValores(string texto, string operacao,
02 ref byte [ ] pBytesChave,
1 private const string chave = ChaveRijndael128;
03 ref byte [ ] pBytesVetorInicializacao,
2 privatebyte[ ] bytesChave = null;
04 ref byte [ ] pBytesTexto)
05 {
3 privatebyte[ ] bytesVetorInicializacao = null;
06 try
07 {
4 privatebyte[ ] bytesTexto = null;
08 UTF8Encoding objUTF8Encoding = new UTF8Encoding();
09 pBytesChave = objUTF8Encoding.GetBytes(chave);
10 pBytesVetorInicializacao = objUTF8Encoding.GetBytes(chave);
11 if(operacao==criptografia)
12 pBytesTexto = objUTF8Encoding.GetBytes(texto);
13 else
14 pBytesTexto = Convert.FromBase64String(texto);

15 }
16 catch (Exception)
17 {
18 throw;
19 }
20 }

O primeiro conceito a ser observado neste mtodo so seus


parmetros. Veja que trs deles so passados como referncia,
possuindo a palavra reservada ref antes do tipo. A passagem por
referncia faz com que as alteraes realizadas nestas variveis
dentro do mtodo reflitam fora dele tambm. um meio geral-
mente utilizado quando se deseja retornar mais de um valor.
Figura 4. Solution do projeto Basicamente a funo deste mtodo obter os bytes a serem
atribudos nas variveis descritas anteriormente. Os bytes da
Na linha 1 declarada uma constante do tipo string que ser chave e do vetor de inicializao so obtidos por meio da utiliza-
utilizada para criar a chave do algoritmo, ou seja, a chave usada o do mtodo getBytes(), presente na classe UTF8Encoding, que
no processo de criptografia. A varivel foi declarada como uma retorna um array de bytes baseado na chave que foi definida no
constante, pois seu valor no ser alterado em tempo de execu- incio da classe de criptografia: ChaveRijndael128. A estrutura
o. Veja que j foi atribudo um valor a ela, ChaveRijndael128. condicional If else criada nas linhas 11 a 14 verifica se a operao
Este valor poderia ser uma sequncia de caracteres qualquer ou a ser realizada de criptografia ou descriptografia. No primeiro
ser gerado a partir de outra classe, como por exemplo a classe caso feita a obteno dos bytes utilizando o objeto da classe
Rfc2898DeriveByte, que pode realizar este papel. Para simplificar UTF8Encoding (linha 12). Caso o processo seja de descriptografia,
vamos deix-la com o valor jdefinido. A partir desta chave, sero como o texto passado j estar criptografado, basta convert-lo
obtidos os bytes da mesma e atribudos a varivel bytesChave utilizando o mtodo FromBase64String() (linha 14).
(declarada na linha 2). A Listagem 3 refere-se ao mtodo CriptografarTexto(), que
A varivel bytesVetorInicializacao (declarada na linha 3) tem responsvel pela criptografia de uma determinada informao.
o objetivo de armazenar os bytes do vetor de inicializao (VI) Perceba que ele recebe um nico parmetro do tipo string, que
utilizado pelo Rijndael. O VI uma matriz de bytes cuja funo exatamente o texto a ser criptografado. Na linha 5 invocado
forar o algoritmo a encriptar um mesmo texto de forma diferente, o mtodo SetaValores passando como parmetros: o texto a ser

Edio 27 Easy .Net Magazine 9


Criptografia

criptografado, o tipo do processo, que ser neste momento de Listagem 3. Mtodo de criptografria
criptografia, e a referncia das variveis criadas na classe.
01 public string CriptografarTexto(string texto)
Na linha 10 instanciado um objeto da classe RijndaelManaged,
02 {
que herda da classe abstrata Rijndael. A classe RijndaelManaged 03 try
responsvel por criar o objeto de encriptao com base na chave e no 04 {
05 SetaValores(texto,
vetor de inicializao obtidos por meio do mtodo CreateEncryptor 06 criptografia,
(linha 11). Na linha 13, criado um objeto do tipo Memory Stream, 07 ref bytesChave,
cuja funo ser armazenar o texto criptografado na memria. Veja 08 ref bytesVetorInicializacao,
09 ref bytesTexto);
que ele foi adicionado dentro de um bloco using. Esta estrutura faz
com que os recursos sejam liberados automaticamente ao final do 10 Rijndael rijndael = new RijndaelManaged();
bloco, ou seja, o objeto do tipo Memory Stream que estava ocupando
11 ICryptoTransform IEncryptor = rijndael.CreateEncryptor
espao na memria, aciona o mtodo Dispose() implicitamente, que (bytesChave, bytesVetorInicializacao);
tem o papel de efetuar a liberao de recursos do objeto.
Nas linhas 15 a 20 so realizadas a criptografia e a escrita do texto 13 using (MemoryStream objMemoryStream = new MemoryStream())
14 {
criptografado no objeto objMemoryStream, por meio da classe
CryptoStream. Veja nas linhas 15 a 18 que esta classe recebe como 15 CryptoStream encryptor = new CryptoStream(
16 objMemoryStream,
parmetros de seu construtor o objeto do tipo Memory Stream
17 IEncryptor,
criado (linha 16), o objeto encriptador IEncryptor (linha 17) e o 18 CryptoStreamMode.Write);
modo como vai operar, que ser de escrita pois sua funo ser 19
20 encryptor.Write(bytesTexto, 0, bytesTexto.Length);
escrever o texto criptografado no objeto objMemoryStream, como
21 encryptor.Close();
pode ser visto na linha 20. 22 return Convert.ToBase64String(objMemoryStream.ToArray());
Por fim o mtodo retorna o texto criptografado obtido atravs 23 }
24 }
do mtodo ToArray() da classe MemoryStream (linha 22). 25 catch (Exception ex)
O mtodo para descriptografar o texto semelhante ao de 26 {
criptografia, conforme apresentado na Listagem 4. As diferenas 27 throw ex;
28 }
esto na chamada ao mtodo SetaValores, que agora recebe como 29 }
parmetro do tipo de operao o valor descriptografia. Outra
alterao est na linha 11, onde desta vez criado o objeto de Listagem 4. Mtodo de descriptografria

decriptao por meio do mtodo CreateDecryptor(). Por ltimo, 01 public string DescriptografarTexto(string texto)
retornado o texto original, onde os bytes referentes ao texto 02 {
decifrado so convertidos para string a partir do array de bytes 03 try
04 {
obtidos da memria (linha 22).
05 SetaValores(texto,
Em resumo a classe de Criptografia contm trs mtodos: Se- 06 descriptografia,
taValores(), CriptografarTexto e DescriptografarTexto. Observe 07 ref bytesChave,
que o processo para criptografar e decriptografar os dados no 08 ref bytesVetorInicializacao,
09 ref bytesTexto);
complexo, basta apenas realizar algumas converses e utilizar
10 Rijndael rijndael = new RijndaelManaged();
os mtodos presentes na classe Rijndael, que faz todo o restante 11 ICryptoTransform IDEcryptor = rijndael.CreateDecryptor
do trabalho. (bytesChave, bytesVetorInicializacao);
Ao realizar um Build no projeto verifique na pasta bin do mesmo 12
o arquivo Criptografia.dll gerado. Ele pode ser referenciado em 13 using (MemoryStream objMemoryStream = new MemoryStream())
14 {
outros sistemas para realizar o processo de cifragem de dados. 15 CryptoStream decryptor = new CryptoStream(
O prximo tpico destinado ao projeto WEB, contendo a classe 16 objMemoryStream,
de persistncia e as pginas da aplicao. Neste contexto, a classe 17 IDEcryptor,
Criptografia ser acionada no processo de cifragem e decifragem 18 CryptoStreamMode.Write);
19 decryptor.Write(bytesTexto, 0, bytesTexto.Length);.
de senhas. 20 decryptor.Close();
21 UTF8Encoding utf8 = new UTF8Encoding();
Persistncia 22 return utf8.GetString(objMemoryStream.ToArray());
As interfaces da aplicao consistem em trs pginas: uma para 23 }
24 }
cadastrar usurio e senha, outra para efetuar o login no sistema, 25 catch (Exception ex)
e uma terceira pgina que informa se o login foi realizado com 26 {
sucesso. Todas so pginas bem simples, pois o que realmente 27 throw ex;
importa a criptografia da senha, no momento do cadastro, e sua 28 }
29 }
descriptografia, no momento do login.

10 Easy .Net Magazine Edio 27


A classe responsvel pela persistncia dos dados tambm est SQLCommand (Nota do DevMan 4) e SqlParameter inibe ataques
inserida no Web Application, denominada AcessaDados.cs, e do tipo SQL Injection (Nota do DevMan 5), pois os parmetros
contm apenas dois mtodos: um para cadastrar o usurio com no so inseridos diretamente na query. Dessa forma, so tratados
sua senha e outro para buscar a senha criptografada do usurio como dados e no como comandos, impedindo assim de serem
na base de dados. Foi criada uma tabela utilizando banco de da- executados.
dos SQL Server, denominada TBUsuario, contendo apenas dois
campos do tipo varchar, sendo eles: Usuario, referente ao nome
do usurio cadastrado, e Senha, referente senha do mesmo. Nota do DevMan 4
Veja na Listagem 5 o cdigo que faz a persistncia destes campos
por meio do mtodo InserirUsurio(). Ele inicia com a declarao SQLCommand uma classe disponibilizada pelo framework .NET que tem a funo de executar
dos objetos para conexo com o banco de dados (linha 3) e para comandos SQL, seja ele de insero, alterao, recuperao ou deleo de dados. Esta classe contm
trs mtodos bastante utilizados para realizar as tarefas citadas anteriormente, sendo eles:
execuo de comandos (linha 4). J dentro do bloco try catch, uti-
ExecuteReader: Tem a funo de executar um comando SQL, e o resultado popula um objeto
lizado para capturar alguma exceo que possa ocorrer, a string SQLDataReader.
strConexao recebe o valor da conectionString criada no web.con-
ExecuteNonQuery:Executa um comando SQL e retorna apenas o nmero de linhas afetados pela
fig, referente ao nome do banco, usurio e senha para acesso. operao, geralmente utilizado em instrues de insero, atualizao e deleo.
ExcecuteScalar: Utilizado em instrues que retornam apenas uma linha ou coluna como resultado.
Listagem 5. Mtodo para inserir um novo usurio

01 public void InserirUsuario(string usuario, string senha)


02 {
03 SqlConnection conn = null; Nota do DevMan 5
04 SqlCommand cmd = null;
05 try
06 {
SQL Injection um tipo de ataque a sistemas web onde instrues SQL so inseridas em inputs
07 string strConexao =System.Configuration. ConfigurationManager.
do usurio com o objetivo de forar a aplicao a executar estes comandos em conjunto com as
ConnectionStrings [ConnectionString].ConnectionStrig;
instrues SQL j existentes, podendo recuperar, alterar, remover os dados de uma base de dados ou
08
causar algum outro tipo de dano a mesma.
09 conn = new SqlConnection(strConexao);
10 string querysql = @INSERT INTO TBUsuario (Usuario,Senha)
values (@Usuario,@Senha);
12 conn.Open(); A linha 16 executa o comando, via mtodo ExecuteNonQuery()
13 cmd = new SqlCommand(querysql, conn);
da classe SqlCommand.
14 cmd.Parameters.Add(new SqlParameter(@Usuario, usuario));
15 cmd.Parameters.Add(new SqlParameter(@Senha, senha)); A Listagem 6 exibe o mtodo BuscarSenhaUsuario(). A sua
16 cmd.ExecuteNonQuery(); construo parecida com a estrutura apresentada anteriormente.
17 }
Entretanto, desta vez o mtodo possui um retorno que a senha
18 catch (SqlException sqlEx)
19 { recuperada do banco. Ressalta-se que, por enquanto, a senha
20 throw sqlEx; ainda se encontra criptografada, e a descriptografia ocorrer em
21 }
22 finally
outro momento. Alm disso, outra diferena est na execuo do
23 { comando (linha 14). Veja que desta vez foi utilizado o mtodo
24 cmd.Connection.Close(); ExecuteScalar(), pois ser retornado um valor, no caso, a senha
25 conn.Close();
26 }
do usurio.
27 }
Interfaces
As interfaces da aplicao consistem em trs pginas: uma para
Na linha 9 o objeto de conexo recebe as configuraes para cadastrar usurio e senha, outra para efetuar o login no sistema,
acessar o banco. A instruo SQL para inserir os dados na tabela e uma terceira pgina que informa se a operao foi realizada
criada (linha 10 e 11). A conexo com o banco de dados aberta com sucesso.
(linha 12), e o objeto responsvel pela execuo do comando A pgina para cadastrar um novo usurio e senha apresentada
instanciado (linha 13). Observe que na instruo SQL criada os pa- na Figura 5. Ela contm apenas dois controles do tipo TextBox para
rmetros foram passados com o caractere @ antes do nome dos os inputs do nome do usurio e da senha e o boto Cadastrar que
parmetros. Eles sero substitudos pelos valores passados para ir acionar o evento responsvel pela criptografia e persistncia
a classe SqlParameter e este ser adicionado ao objeto cmd, para destes dados.
execuo da query, conforme apresentado nas linhas 14 e 15. Veja na Listagem 7 o cdigo referente ao code behind da pgina.
Mas por que os parmetros no foram inseridos diretamente Observe que na linha 5 o namespace Segurana foi referenciado.
na query concatenando as variveis junto a query? A resposta : No evento btnCadastrar_Click (linhas 13 a 29), o nome do usurio e
segurana. A passagem de parmetros utilizando-se as classes a senha informados pelo usurio so armazenados nas variveis

Edio 27 Easy .Net Magazine 11


Criptografia

usuario e senha (linhas 17 e 18), na linha 19 temos um objeto Listagem 7. Code behind pgina CadastrarUsuarios.aspx
da classe Criptografia sendo instanciado e em seguida temos o
01 using System;
mtodo CriptografarTexto() sendo executado recebendo como pa-
02 using System.Web;
rmetro a senha do usurio (linha 20). Este mtodo ento retorna 03 using System.Web.UI;
a senha criptografada pelo algoritmo Rijndael. Por fim, os dados 04 using System.Web.UI.WebControls;
do usurio so persistidos na base de dados por meio do mtodo 05 using Seguranca;
InserirUsuario (linha 22). 06 namespace CriptografiaWeb
07 {
08 public partial class CadastrarUsuario :System.Web.UI.Page
Listagem 6. Mtodo para recuperar a senha do usurio 09 {
10 protected void Page_Load(object sender, EventArgs e)
01 public string BuscarSenhaUsuario(string usuario) 11 {
02 { 12 }
03 SqlConnection conn = null; 13 protected void btnCadastrar_Click(object sender, EventArgs e)
04 SqlCommandcmd = null; 14 {
05 string senha = string.Empty; 15 try
06 try
16 {
{
17 string usuario = txtUsuario.Text;
07 StringstrConexao =System.Configuration.ConfigurationManager.
ConnectionStrings[ConnectionString].ConnectionString; 18 string senha = txtSenha.Text;
09 conn = new SqlConnection(strConexao); 19 Criptografia objCriptografia = new Criptografia();
10 string querysql = @SELECT Senha from TBUsuario where 20 string senhaCriptografada =objCriptografia.
Usuario=@Usuario; CriptografarTexto(senha);
11 conn.Open(); 21 AcessaDados objAcessaDados = new AcessaDados();
12 cmd = new SqlCommand(querysql, conn); 22 objAcessaDados.InserirUsuario(usuario,senhaCriptografada);
13 cmd.Parameters.Add(newSqlParameter(@Usuario, usuario)); 23 Mensagem(Usurio inserido com sucesso);
14 senha = (string)cmd.ExecuteScalar();
24 }
15 return senha;
25 catch (Exception ex)
16 }
17 catch (SqlException sqlEx) 26 {
18 { 27 Mensagem(Falha ao inserir usurio: +ex.Message);
19 throw sqlEx; 28 }
20 } 29 }
21 finally 30 private void Mensagem(string pMensagem)
22 { 31 {
23 cmd.Connection.Close(); 32 ScriptManager.RegisterStartupScript(Page, Page.GetType(),
25 conn.Close();
33 Cadastro, alert( + pMensagem + );, true);
26 }
34 }
27 }
35 }
36 }

A outra interface da aplicao a pgina de login.aspx (Figura 6),


onde ser validado o acesso do usurio. Perceba que uma pgina
bem simples, quase idntica a interface de cadastro, a diferena
agora que os dados informados sero validados ao invs de serem
persistidos. A pgina tambm possui um link que redireciona
para a pgina de cadastro. Conforme j foi dito, o objetivo aqui
a criptografia, portanto, questes relacionadas a design e demais
funcionalidades no sero abordados.
O cdigo da pgina referente validao dos dados apresenta-
Figura 5. Pgina de cadastro de usurio: CadatrarUsuario.aspx do na Listagem 8. Veja que na linha 21 a senha do usurio que foi
cadastrado na base de dados recuperada pelo mtodo Buscar-
O outro mtodo desta classe, denominado Mensagem(), tem SenhaUsuario(). Porm a senha est criptografada e precisamos
a funo de emitir uma mensagem no browser utilizando o comparar a mesma como a senha informada no textbox. Para isso,
comando alert do JavaScript, por meio do mtodo Resgister- necessrio descriptograf-la (linha 22). Uma vez obtido o texto
ClientScriptBlock, da classe ScriptManager, cuja funo registrar original, basta compararmos com a senha digitada pelo usurio
e executar scripts em pginas web. Observe que ele foi utilizado para efetuar o login. Se forem idnticas o usurio redirecionado
tanto para informar o sucesso na insero dos dados do usurio para a pgina acesso.aspx (Figura 7), que tem a funo apenas
quanto no bloco catch para informar algum erro que possa ter de informar que o acesso foi autorizado. Caso contrrio, uma
ocorrido no processo. mensagem informa a irregularidade no login.

12 Easy .Net Magazine Edio 27


Listagem 8. Code behind pgina Login.aspx

01 using System; objAcessaDados.BuscarSenhaUsuario (usuario);


02 using System.Web; 22 senhaCadastrada =criptografa.DescriptografarTexto
03 using System.Web.UI; (senhaCadastrada);
04 using System.Web.UI.WebControls; 23 if (senhaInformada == senhaCadastrada)
05 using Seguranca; 24 Response.Redirect(Acesso.aspx);
06 namespace CriptografiaWeb 25 else
07 { 26 Mensagem(Login invlido.);
08 public partial class Login :System.Web.UI.Page 27 }
09 { 28 catch (Exception ex)
10 protected void Page_Load(object sender, EventArgs e) 29 {
11 { 30 Mensagem(Falha ao validar usurio: +ex.Message);
12 } 31 }
13 protected void btnCadastrar_Click(object sender, EventArgs e) 32 }
14 { 33 private void Mensagem(stringpMensagem)
15 try 34 {
16 { 35 ScriptManager.RegisterStartupScript(Page, Page.GetType(),
17 string usuario = txtUsuario.Text; Login, alert( + pMensagem+ );, true);
18 string senhaInformada = txtSenha.Text; 37 }
19 Criptografia criptografa = new Criptografia(); 38 }
20 AcessaDados objAcessaDados = new AcessaDados(); 39 }
21 string senhaCadastrada =

pgina CadastrarUsuario.aspx e selecionar a opo Set as Start


Page. Feito isso, necessrio executar o projeto utilizando a de-
purao, acessando o menu Debug => Start Debugging. Iniciada
a execuo, vamos cadastrar um novo usurio com os seguintes
dados:
Usurio: teste
Senha: testecriptografia

Aps clicar no boto cadastrar, o evento click do mesmo aciona-


do e a execuo parada onde o breakpoint foi inserido, conforme
pode ser visualizado na Figura 8. Neste momento a linha no foi
processada ainda. Pressionando a tecla F10 a linha executada e
Figura 6. Login do usurio
o cursor para na prxima instruo. Agora j podemos ver o va-
lor da varivel senhaCriptografada, que recebeu o texto cifrado do
mtodo CriptografarTexto. Para isso, basta posicionarmos o cursor
em cima da varivel e o valor da mesma ser apresentado, como
pode ser visto na Figura 9. Portanto, o resultado da criptogra-
fia da senha testecriptografia, utilizando o algoritmo Rijndael
Figura 7.Interface acesso.aspx foi 6nlChzqFhh/fSzD2dHy+PWOgn5fBB7hJvY8c328WXxA=.
A senha criptografada ser ento gravada na base de dados.
Execuo
Para a execuo do sistema, ser mais interessante avaliarmos
o que est ocorrendo internamente e no apenas na interface. Por Nota do DevMan 6
isso, sero adicionados dois breakpoints nas pginas. O primeiro
dever ser inserido na linha 20 da pgina CadastrarUsuario.aspx, Breakpoint (ponto de parada) um recurso utilizado na depurao das aplicaes que permite
para verificarmos o resultado da criptografia. O segundo, na interromper a execuo do cdigo em um determinado ponto, possibilitando, entre outras funes,
navegar pelo mesmo e verificar o estado dos objetos e valores carregados nas variveis.
pgina Login.aspx, onde veremos o resultado da descriptografia,
que ser inserido na linha 22.
Para adicionar um breakpoint (Nota do DevMan 6), basta cli-
car com o boto direito na linha desejada e selecionar a opo O mesmo processo ser feito na pgina de login. Ao executarmos
Breakpoint => Insert Breakpoint. a mesma e informar os dados referentes conta criada, a senha
Vamos iniciar a execuo da aplicao pela pgina de cadastro que fora gravada no banco de dados, recuperada e descripto-
de usurio. Para isso, basta clicar com o boto direito em cima da grafada. Veja na Figura 10 esta etapa. Observe que a senha obtida

Edio 27 Easy .Net Magazine 13


Criptografia

passou pelo processo de criptografia e voltou ao seu valor original Ericksen Viana Sampaio
testecriptografia. Desta forma, a senha ser igual informada ericksen.sampaio@gmail.com
na pgina de login, e o usurio ser redirecionado para a pgina Ericksen Viana Sampaio analista desenvolvedor de sistemas.
acesso.aspx. Atua na rea de desenvolvimento WEB utilizando ASP.NET C#.
Possui o ttulo de MCTS (ASP.NET 4.0). graduado em Cincia da
Computao pela Faculdade Pedro Leopoldo e ps-graduado em
Anlise de Sistemas pela UFMG.

String Encryption and Decryption in C#


http://vinothnat.blogspot.com.br/2007/10/string-encryption-and-
decryption-in-c.html
Figura 8. Breakpoint antes de o texto ser criptografado Encrypt and Decrypt Data Using a Symmetric (Rijndael) Key
http://www.obviex.com/samples/Encryption.aspx
Classe Rijndael
http://msdn.microsoft.com/pt-br/library/system.security.cryptography.rijndael.aspx
Criptografia e lgebra
http://www.mat.ufmg.br/~marques/criptografia.pdf
Figura 9. Resultado da criptografia Tutorial sobre criptografia e certificao digital - Criptografia
http://www.hsbc.com.br/1/2/portal/pt/footer/seguranca/artigos/criptografia
Criptografia simtrica
http://www.gta.ufrj.br/grad/07_2/delio/Criptografiasimtrica.html
.NET Framework Cryptography Model
http://msdn.microsoft.com/en-us/library/0ss79b2x.aspx
Criptografia de dados em .NET
Figura 10. Senha descriptografada http://blog.ohashi.com.br/post/Criptografia-de-dados-em-NET.aspx
O que Assinatura Digital
Concluso http://www.jf.jus.br/cjf/tecnologia-da-informacao/identidade-digital/o-que-e-
A criptografia em .NET bem simples de ser implementada. assinatura-digital
Toda a complexidade dos algoritmos de cifragem de dados fica Cryptography in .NET
abstrada, facilitando assim a vida do desenvolvedor. Este artigo http://www.codeproject.com/Articles/3740/Cryptography-in-NET-part-1
apresentou um pouco da classe Rijndael para realizar a cifragem
de dados, algoritmo este muito utilizado mundialmente. Mas isso
Data Confidentiality
http://msdn.microsoft.com/en-us/library/ff650720.aspx
no impede de voc leitor explorar outras classes de criptografia,
pois o .NET disponibiliza diversas solues tanto para criptografia
simtrica quanto assimtrica.

14 Easy .Net Magazine Edio 27


Namespace System.
Diagnostics - Parte 1
Monitorando aplicaes .NET com log de eventos
e contadores de desempenho

Este artigo faz parte de um curso


Resumo DevMan
Namespace System.Diagnostics:

O
ciclo de vida de um sistema no termina Neste artigo veremos como utilizar as classes de contadores de
quando a ltima linha de cdigo escrita e desempenho (Performance Counters) e log de eventos (Event Log)
o usurio d o aceite no que foi feito. Aps do Windows, mostrando tambm algumas dicas para tirar o melhor
o processo de desenvolvimento, que envolve proveito delas. Para exemplificar os conceitos aqui apresentados va-
as fases de levantamento de requisitos, programao e mos desenvolver uma aplicao do tipo windows service que fornece
homologao, entra uma nova etapa que a operao. informaes para seu monitoramento.
nela que vemos efetivamente o nosso esforo dar
resultados e o investimento feito dar retorno, pois Em que situao o tema til:
neste momento os nossos usurios passam a usufruir As classes do namespace System.Diagnostics podem ser utilizadas
dos benefcios que a aplicao desenvolvida traz. Por no fornecimento de dados para que a equipe de operaes possa
exemplo, uma aplicao de fora de vendas permite que monitorar a sade dos sistemas desenvolvidos, de forma a antecipar
os vendedores sejam mais rpidos nas suas operaes, qualquer problema que possa acontecer com as aplicaes como por
consequentemente fazendo mais pedidos por dia. exemplo desempenho inadequado ou falta de recursos para um bom
importante que a aplicao desempenhe seu papel funcionamento (espao em disco, memria, etc.).
corretamente. De nada vai adiantar nosso trabalho se o
sistema comear a apresentar problemas ou no conseguir
atender a demanda exigida pelos usurios. Uma aplicao nas classes de contadores de desempenho e log de eventos (Perfor-
de vendas que demora em seu tempo de resposta ir atrasar mance Counters e EventLog, respectivamente).
o trabalho dos vendedores. Um dos pontos chaves da fase Nosso exemplo ser uma aplicao do tipo windows services
de operao de um sistema consiste no seu monitoramento. que processa dados para calcular a comisso diria dos vende-
Apesar de isso ser responsabilidade do time de operao, dores. Mas antes de prosseguir com ele, precisamos explicar o
necessrio que o sistema disponibilize os dados necessrios que so os contadores de desempenho, log de eventos e tambm
para permitir que o monitoramento seja realizado. Mas os windows services.
como podemos fornecer os indicadores para que esse time
possa tomar as aes necessrias quando alguma coisa foge Windows services
do comportamento desejado? Windows services so um tipo de aplicao na qual no ne-
aqui que entra a utilidade das classes disponveis cessria uma sesso de usurio ativa no computador para que
no namespace System.Diagnostics. Elas permitem o ele execute. Como elas no precisam de interao com o usurio
fornecimento de dados a respeito do desempenho atual so largamente utilizadas para executar processamentos em se-
da aplicao (por exemplo, quantas requisies ela est gundo plano, geralmente executando tarefas de longa durao.
processando por segundo) e tambm detalhes de eventu- Aps ser instalado em um computador, possvel configurar o
ais problemas que ocorrem durante sua execuo, como windows service para que ele inicie e comece a trabalhar assim
falhas em conexo com o banco de dados. Daremos foco que a mquina seja ligada.

Edio 27 Easy .Net Magazine 15


Namespace System.Diagnostics

Existem vrios windows services executando na sua mquina.


Por exemplo, se voc tiver o SQL Server Express instalado, ele
est rodando como um servio. Para ver quais so os servios
instalados no seu computador basta digitar o comando services.
msc na linha de comando do Windows (boto Start Run...).
Isso abrir o Service Control Manager (SCM), interface na qual,
alm de podermos ver quais so os windows services existentes
na mquina, possvel configur-los, parar algum que esteja exe-
cutando ou iniciar algum que esteja parado. Vemos um exemplo
desta tela na Figura 1.

Figura 2. Propriedades gerais de um windows service

Na Figura 3, vemos a aba Log on. Ela permite configurar sob


qual conta (usurio) que o servio ser executado. Isso importan-
te para trabalharmos com mais segurana. Por exemplo, imagine
que um servio precise ler e gravar arquivos em uma pasta na rede.
Podemos dar permisso de leitura e escrita para uma conta no
domnio e configur-la, passando seu login e senha, para que seja
executada junto do windows service. Se no fosse isso, teramos
Figura 1. Windows services disponveis
que dar permisso de leitura e escrita para todos os usurios da
rede (Everyone), o que no recomendado, pois qualquer pessoa
mal intencionada poderia ir nesta pasta e modificar, ou mesmo
Vamos agora dar uma olhada nas propriedades de um servio apagar, arquivos importantes.
para entender melhor as opes que temos disponveis. Para
acess-las, basta clicar com o boto direito sobre o windows ser-
vice escolhido e clicar em Properties.
A primeira aba das propriedades que vemos a da Figura 2. Ela
possui detalhes como o nome do servio, descrio e o caminho
do executvel (afinal, um windows service nada mais que um
arquivo EXE). Alm disso, possvel definir qual o comportamen-
to que o windows service deve ter quando o computador iniciar
(Startup type). Podemos escolher os seguintes valores:
A utomatic O windows service iniciar automaticamente junto
com o boot do computador.
D isabled O windows service est desativado e no ser
executado.
M anual O windows service iniciar parado no boot do com-
putador e um usurio pode escolher inici-lo manualmente.
Delayed start O windows service iniciar um pouco depois do
boot do computador, exatamente para evitar um momento onde
vrios servios esto inicializando. Esta opo est disponvel nas
verses mais novas do Windows.

Ainda na aba General possvel iniciar, parar ou pausar um


windows service em execuo. Figura 3. Propriedades de logon de um windows service

16 Easy .Net Magazine Edio 27


Prosseguindo, temos a aba Recovery na Figura 4. Ela permite Log de eventos
configurar uma srie de opes que tratam de erros na execuo Uma prtica muito comum quando precisamos guardar infor-
do windows service. Caso haja algum erro no processamento maes de execuo de processos longos ou detalhes de erros
do servio podemos escolher para que o windows service seja ocorridos gravar esses dados em um arquivo no disco local.
iniciado novamente (Restart the service); que a mquina seja rei- Entretanto esta no a forma mais indicada, pois existe um re-
niciada (Restart the computer); que um programa seja executado positrio melhor para armazenar esse tipo de informaes: o log
(Run a program) para que, por exemplo, um e-mail de alerta seja de eventos (Event Log).
enviado para o administrador do ambiente; ou mesmo que no O log de eventos um componente do sistema operacional
seja tomada nenhuma ao. Windows que funciona como se fosse um banco de dados, onde
possvel guardar informaes sobre o que acontece com nossas
aplicaes de forma centralizada. Da mesma maneira que um
banco de dados pode ter vrias tabelas, o log de eventos tambm
pode ter vrios logs distintos, o que facilita a organizao. Com
a instalao do Windows, alguns logs j so criados por padro,
como por exemplo, os logs Application, Security e System. O log
Application genrico e serve para as aplicaes gravarem seus
eventos. J o log Security armazena eventos como logons de usu-
rios na mquina. O log System guarda informaes do prprio
sistema operacional, como windows services que so iniciados
ou problemas de disco.
Alm da questo da organizao, a separao em diversos logs
tambm ajuda na segurana, j que possvel dar permisses para
as pessoas apenas enxergarem alguns logs. Logs como o System
ou Security podem conter informaes que no so de interesse
dos analistas de sistema, ficando apenas a cargo das equipes de
segurana e infra-estrutura.
Figura 4. Propriedades de recuperao de um windows service Para facilitar mais a organizao, cada evento dentro de um log
possui uma fonte (source), que identifica quem efetuou a gravao
Finalizando, temos a aba Dependencies (Figura 5) que mostra da informao. O log Application, que genrico, ficaria muito
quais so os outros windows services que dependem ou que so bagunado se no soubssemos de qual sistema um registro de
dependncia para o servio cujas propriedades estamos visu- erro gravado. Por isso, podemos especificar a origem deste log,
alizando. No nosso exemplo, o servio do SQL Server Express rastreando qual a aplicao que est com problemas. A Figura 6
depende do SQL Server Agent, ou seja, se este ltimo no estiver mostra como a tela de visualizao do log de eventos, que pode
disponvel no poderemos utilizar o banco de dados. ser acessada digitando eventvwr na linha de comando do Win-
dows (boto Start Run...). Do lado esquerdo temos a relao de
todos os logs disponveis para visualizao, tanto os que j vm
criados na instalao do Windows quanto os que as aplicaes
criaram. Ao clicar em qualquer um desses logs, podemos ver a
relao de todos os eventos armazenados neles no centro da tela.
Esses eventos contm os seguintes dados no seu detalhamento,
entre outros:
N ome do log
Source (a aplicao que o gravou)
A data em que o registro ocorreu
O tipo do log (se erro, se um aviso ou apenas uma informao)
A mensagem do erro

Se estivssemos procurando um registro especifico seria muito


trabalhoso percorrer os milhares de eventos, olhando um por
um para saber se o que procuramos. Para resolver isso, existe a
opo de filtrar o log. A Figura 7 mostra a tela de filtro, que pode
ser acessada clicando-se com o boto direito sobre o log, na parte
esquerda da tela administrativa, escolhendo a opo Filter....
Figura 5. Dependncias de um windows service

Edio 27 Easy .Net Magazine 17


Namespace System.Diagnostics

Nesse filtro, podemos escolher praticamente por todas as infor- pelo log de eventos: se os registros mais velhos sero excludos
maes de detalhe dos eventos, permitindo assim encontrar mais automaticamente, dando espao aos mais novos; ou ao contrrio,
rapidamente o dado que procuramos. se nenhum registro removido. Nesta ltima opo, quando a
aplicao tentar gravar o log, ela receber um erro.

Figura 6. Log de eventos de aplicaes

Figura 8. Propriedades de um log de eventos

Contadores de desempenho
Contador de desempenho (Performance Counters) um outro
componente do Windows que permite o monitoramento do que
acontece na mquina. Eles funcionam como o velocmetro de
um carro, mostrando em tempo real o que est acontecendo no
sistema. Existem inmeros contadores de desempenho que j vm
instalados com o sistema operacional. Eles exibem informaes a
respeito da memria, uso de CPU, disco, rede, etc. Por exemplo, na
Figura 9 temos um contador que mostra a porcentagem de uso do
processador. um grfico que atualizado a cada segundo onde
no eixo X temos o tempo e no eixo Y o valor do contador (neste
caso, vai de 0% a 100%). Alm disso, temos as informaes do l-
timo valor do contador monitorado, o mnimo, mximo e a mdia
apurada. Se em uma mquina esse grfico estiver constantemente
no topo, ela est trabalhando no limite da sua capacidade e nesta
situao interessante analisar se no seria melhor comprar um
Figura 7. Filtrando o log de eventos novo processador.
Da mesma forma que os windows services e o log de eventos,
Finalizando, vamos olhar as propriedades do log (Figura 8). a tela de visualizao dos contadores de desempenho tambm
Uma caracterstica importante que temos a definio de como pode ser acessada atravs da linha de comando do Windows,
o Windows ir controlar o espao em disco destinado aos logs (no digitando-se perfmon.
final das contas, o log de eventos guarda as suas informaes em Podemos remover um contador clicando nele e depois no boto
arquivos). Se uma aplicao ficar gravando eventos, uma hora ou X (vermelho). De forma similar, podemos adicionar um novo
outra essas informaes chegaro ao limite de armazenamento. contador clicando no boto + (verde). Isso ir abrir a janela mos-
Neste ponto, podemos definir qual o comportamento esperado trada na Figura 10. Para se escolher um contador de desempenho,

18 Easy .Net Magazine Edio 27


Nota

Neste artigo demonstramos como acessar as telas de visualizao dos windows services, log de
eventos e contadores de desempenho atravs da linha de comando do Windows. Essa a forma mais
rpida de encontr-los. Entretanto, todas as telas esto disponveis atravs do Painel de Controle do
Windows, nas Ferramentas Administrativas.

basta clicar em Add e depois em Ok, que o grfico passar a


exibir os dados do contador recm adicionado.
A respeito do grfico, um detalhe que temos que observar para
uma boa visualizao dos dados a escala utilizada. Por exemplo,
se tivermos uma escala de 0 a 100 e escolhermos um contador que
monitore a quantidade de bytes utilizados da memria, o grfico
sempre ficar no topo, j que atualmente nenhum computador tem
menos que 100 bytes de RAM. A escala pode ser mudada nas pro-
Figura 9. Contador de desempenho do uso de CPU da mquina priedades do monitor dos contadores de desempenho, clicando-se
com o boto direito sobre o grfico, escolhendo Properties e
indo na aba Graph (Figura 11).

Figura 10. Selecionando contadores para visualizao

primeiro precisamos selecionar qual mquina ser monitorada.


Por padro, a mquina que aparece a prpria que estamos
usando, mas nada nos impede de acessar e visualizar contadores
de outras mquinas. Em seguida selecionamos a categoria do
contador. Exemplos de categoria so Memory, Physical Disk, ASP.
NET, entre outros. Dentro dessas categorias que esto agrupados Figura 11. Propriedades do grfico dos contadores de desempenho
os contadores. Por exemplo, dentro da categoria Physical Disk,
encontramos os contadores de taxa de transferncia de dados,
mdia de leitura de disco, mdia de gravao de disco, etc. De-
Tutorial
pois de selecionado o contador, escolhemos qual instncia vamos
monitorar. As instncias esto disponveis ou no de acordo com
o tipo do contador. O contador de bytes disponveis de memria
geral do ambiente e por isso no possui instncia. J um contador Exemplo prtico: Processando arquivos em segundo plano
que mostra a quantidade de objetos armazenados na memria Aqui comeamos a nossa aplicao de exemplo. Trata-se de um
gerenciada do .NET ter uma instncia para cada aplicativo em servio que processa arquivos em segundo plano. Esse exemplo
.NET que esteja em execuo no momento. Selecionada a instncia, interessante para ns, pois se trata de uma aplicao que

Edio 27 Easy .Net Magazine 19


Namespace System.Diagnostics

executada sem interveno direta de um usurio. Ento, a me- de dados e a remoo do arquivo texto (linha 19). Cada passo
lhor forma de monitorarmos essa aplicao atravs dos regis- feito por um mtodo prprio.
tros de eventos que ela deixa e dos contadores que medem seu O primeiro mtodo o CriarObjetoComissao (linha 22). A pri-
funcionamento. meira coisa que ele faz pegar o nome do arquivo, utilizando para
Mas antes de entrar em detalhes do windows service, log de isso o mtodo utilitrio do .NET Path.GetFileNameWithoutExtension
eventos e contadores de desempenho, vamos entender melhor a (linha 24) do namespace System.IO, e extrair a data das vendas e
regra de negcio por trs do processamento da nossa aplicao o nome do vendedor. Depois, o arquivo lido com o uso da classe
de exemplo. StreamReader (linha 30), para se recuperar os valores das vendas.
O nosso sistema fictcio atende uma rede de lojas de instrumen- Como cada informao na linha separada pelo caractere |,
tos musicais. Todo final de dia, as filiais enviam para a matriz, utilizamos o mtodo Split do .NET para transformar a linha em
onde se encontra a central de processamento de dados, vrios um array com 4 posies. Como o que nos interessa est na lti-
arquivos de texto contendo os dados das vendas que ocorreram ma posio, o valor total da venda, ento convertemos esse dado
no dia, separados por vendedor. para o tipo double e o somamos na propriedade TotalVendas do
Existem vrias contabilizaes que a empresa precisa fazer, mas objeto Comissao.
a que ns estamos interessados agora a totalizao das comisses Carregadas as informaes, efetuamos o clculo da comisso
de cada vendedor. Essas comisses so calculadas como sendo pelo mtodo CalcularValorComissaoVendas (linha 45). Esse m-
6% do total de vendas que cada pessoa fez no dia. Assim que todo bem simples, atualizando o valor da comisso com 6% do
consolidados, esses valores so armazenados numa base de dados total de vendas.
para depois serem consumidos pelo sistema de pagamentos. Ao Em seguida, o mtodo SalvarComissao (linha 51) ir guardar
observarmos o cdigo da Listagem 1, vemos a classe Comissao os dados em uma base de dados SQL Server CE, dentro da tabela
que contm essas informaes: nome do vendedor, data, total de Comissoes. A primeira coisa a ser realizada recuperar a string
vendas e valor da comisso. de conexo para este banco de dados, armazenada no arquivo de
configurao (linha 54). Com isso, podemos abrir uma conexo
com esta base, executando o comando INSERT para incluir os
Listagem 1. Classe de Comisso
dados (linha 53 63. Note que estamos utilizando um comando
01 usingSystem; parametrizado, ou seja, ao invs de passar os dados a serem inclu-
02 usingSystem.Collections.Generic;
dos direto no comando SQL, fazemos uso de parmetros que so
03 usingSystem.Linq;
04 usingSystem.Text; adicionados execuo da query pelo mtodo ExecuteNonQuery.
05 Isso uma boa prtica, pois impede ataques de injeo de SQL
06 namespaceComissaoVendas.Entidades
na aplicao.
07 {
08 publicclassComissao Por fim, o mtodo RemoverArquivo (linha 71) simplesmente
09 { apaga o arquivo que j foi processado, utilizando para isso o
10 publicstringNomeVendedor{get;set;}
11 publicDateTimeData{get;set;}
mtodo Delete da classe File.
12 publicdoubleTotalVendas{get;set;}
13 publicdoubleValorComissao{get;set;} Criando o windows service
14 }
15 } Um windows service nada mais que uma aplicao executvel
que roda em segundo plano. Entretanto, necessria uma srie
de configuraes especiais para que esse executvel possa ser
Na Listagem 2 temos o cdigo para processar os arquivos de tratado como um servio pelo Windows. Felizmente o Visual
venda. Para identificar cada arquivo, convencionou-se que eles Studio j nos fornece um modelo especialmente criado para este
viriam com a data das vendas e o nome do vendedor. Por exemplo, tipo de aplicao, disponvel como um projeto em New Project
um arquivo com nome 20121119FULANO.txt representa todas as Installed Templates Visual C# Windows Windows
vendas de FULANO no dia 19/11/2012. Dentro do arquivo, linha Service. Este modelo j cria a base para o windows service, na
por linha, vm as informaes de cada venda: nome do produto, qual inclumos o cdigo da Listagem 3.
valor unitrio, quantidade vendida e total da venda, separadas
pelo caractere pipeline |. Um windows service possui dois mtodos principais. O primeiro
Para cada arquivo criado uma instncia da classe Processador- o mtodo OnStart (linha 26), que chamado no momento em
ArquivoVendas, responsvel por toda regra de clculo e persis- que o servio inicia, seja automaticamente pelo boot do sistema
tncia dos dados. Veja que o mtodo ProcessarArquivo (linha 13) operacional ou pela ao manual de um usurio.
desta classe, que recebe como parmetro o caminho do arquivo a como se ele fosse o mtodo Main de uma aplicao Console, po-
ser processado, dividi-se em 4 partes: a criao do objeto (linha 16) dendo at receber parmetros de linha de comando (Nota do
que armazena os dados de comisses, o clculo das comisses DevMan 1). importante citar que no neste mtodo que o
(linha 17), a gravao dos dados (linha 18) totalizados no banco cdigo de processamento do servio deve ficar, mas sim apenas

20 Easy .Net Magazine Edio 27


Listagem 2. Classe de processamento de arquivos

01 usingSystem; 42 returncomissao;
02 usingSystem.IO; 43 }
03 usingComissaoVendas.Entidades; 44
04 usingSystem.Data.SqlServerCe; 45 privateComissaoCalcularValorComissaoVendas(Comissaocomissao)
05 usingSystem.Configuration; 46 {
06 47 comissao.ValorComissao=comissao.TotalVendas*0.06;
07 namespaceComissaoVendas.RegrasNegocio 48 returncomissao;
08 { 49 }
09 publicclassProcessadorArquivoVendas 50
10 { 51 privatevoidSalvarComissao(Comissaocomissao)
11 privatestring_caminhoArquivo; 52 {
12 53 stringcomandoInsert=
13 publicvoidProcessarArquivo(stringcaminhoArquivo) INSERT INTO Comissoes (Vendedor, Data, TotalVendas, ValorComissao)
14 { VALUES (@Vendedor, @Data, @TotalVendas, @ValorComissao);
15 _caminhoArquivo=caminhoArquivo; 54 SqlCeConnection conexao = new SqlCeConnection(
16 Comissaocomissao=CriarObjetoComissao(); ConfigurationManager.ConnectionStrings[db].ConnectionString );
17 comissao=CalcularValorComissaoVendas(comissao); 55 SqlCeCommandcomando=newSqlCeCommand
18 SalvarComissao(comissao); (comandoInsert,conexao);
19 RemoverArquivo(); 56 comando.Parameters.AddWithValue(@Vendedor,comissao.
20 } NomeVendedor);
21 57 comando.Parameters.AddWithValue(@Data,comissao.Data);
22 privateComissaoCriarObjetoComissao() 58 comando.Parameters.AddWithValue(@TotalVendas,comissao.
23 { TotalVendas);
24 stringnomeArquivo=Path.GetFileNameWithoutExtension 59 comando.Parameters.AddWithValue(@ValorComissao,
(_caminhoArquivo); comissao.ValorComissao);
25 Comissaocomissao=newComissao() 60 conexao.Open();
26 { 61 try
27 Data=DateTime.Parse(nomeArquivo.Substring(0,10)), 62 {
28 NomeVendedor=nomeArquivo.Substring(10) 63 comando.ExecuteNonQuery();
29 }; 64 }
30 using(StreamReadersr=newStreamReader(_caminhoArquivo)) 65 finally
31 { 66 {
32 string conteudoArquivo = sr.ReadToEnd(); 67 conexao.Close();
33 string[] linhas = conteudoArquivo.Split(new [] 68 }
{ Environment.NewLine },StringSplitOptions.RemoveEmptyEntries); 69 }
34 foreach(stringlinhainlinhas) 70
35 { 71 privatevoidRemoverArquivo()
36 string[ ]partesLinha=linha.Split(|.ToCharArray()); 72 {
37 //Ex.: VIOLO|2|450,00|900,00 73 File.Delete(_caminhoArquivo);
38 doublevalorVenda=double.Parse(partesLinha[3]); 74 }
39 comissao.TotalVendas+=valorVenda; 75 }
40 } 76 }
41 }

a sua inicializao. Ou seja, precisamos de uma forma de manter


uma verificao constante de existncia de arquivos. Podemos Nota do DevMan 1
conseguir isso criando uma nova thread (Nota do DevMan 2)
e colocando nela o loop necessrio para ficar processando os Uma coisa bem til que podemos fazer ao passar parmetros para um windows service definir
arquivos disponveis. No nosso exemplo, este trecho de cdigo uma constante para permitir uma depurao mais fcil do servio. Como um windows service
inicia automaticamente, s vezes fica complicado efetuar o debug de mtodos que ocorrem logo
que ser executado em paralelo o mtodo ProcessarLoop. Ento, no incio do processamento. Dentro do mtodo OnStart da Listagem 3, quando identificado que
dentro de OnStart, simplesmente inicializamos a thread com o est passando a palavra debug para o windows service, automaticamente feita uma chamada ao
depurador (Visual Studio) com um breakpoint exatamente no ponto onde ocorreu a execuo do
nome deste mtodo e a colocamos para rodar.
mtodo Debugger.Launch. E para configurar essa passagem de valor basta apenas inclu-lo na caixa
O segundo mtodo o OnStop (linha 32), que utilizado ao parar de texto Start parameters das propriedades do windows service, como mostrado na Figura 12.
o processamento do servio. No nosso caso, precisamos que a exe-
cuo do mtodo ProcessarLoop seja interrompida. Para isso, basta
alterar o valor do campo _emProcessamento para false (linha 34),
pois a instruo while contida no mtodo ProcessarLoop sempre Nota do DevMan 2
valida o contedo deste campo. Assim que ele se torna falso, a
execuo do mtodo termina, junto com a thread. O mtodo ProcessarArquivo da Listagem 2 tem vrios passos que so executados um aps o outro,
sequencialmente, dentro de uma linha do tempo. Essa linha do tempo na qual um programa roda
Vamos agora olhar com mais detalhes o mtodo ProcessarLoop nada mais que uma thread. No .NET possvel trabalhar com mais de uma thread ao mesmo tempo,
(linha 49). Como vimos, ele ter uma execuo cclica enquanto o fazendo com que duas atividades possam ser executadas em paralelo, de forma que a execuo de
valor do campo _emProcessamento for verdadeiro. Dentro desta uma sequncia de comandos no precisa esperar pelo trmino de outra para iniciar sua execuo.
Essa a chamada programao multi-thread.
execuo, ele utiliza a classe Directory (do namespace System.IO)

Edio 27 Easy .Net Magazine 21


Namespace System.Diagnostics

para recuperar todos os arquivos TXT existentes na pasta con- possamos consultar o mesmo posteriormente. E o melhor lugar
figurada no windows service. Isto feito chamando o mtodo para isso o log de eventos.
esttico GetFiles (linha 53). Para cada arquivo encontrado, feita O acesso ao log de eventos, dentro do .NET, feito basicamen-
uma chamada ao mtodo ProcessarArquivo (linha 62). Quando te atravs da classe EventLog, presente no namespace System
todos os arquivos tiverem sido processados, faz-se uma pausa .Diagnostics. O mtodo WriteEntry recebe como argumento o
na execuo deste loop, para economizar processamento, e o nome do source na qual o registro do evento ser categorizado,
ciclo recomea. a mensagem que ser gravada e o tipo da mensagem (erro, aler-
ta ou informao). este o mtodo que usamos no cdigo de
GravarErroLogWindows (Listagem 3, linha 78).
Em primeiro lugar, a mensagem a ser gravada no log formatada
para conter o caminho (linha 81) do arquivo que estava sendo proces-
sado quando o erro ocorreu e os detalhes do erro (linha 83) contido
na exceo gerada pelo .NET. sempre bom guardar o mximo de
informaes disponveis para ajudar na identificao do problema.
Em seguida, verificamos se o tamanho da mensagem no ex-
cedeu o limite mximo de caracteres (l.inha 85) que podem ser
guardados no log de eventos (este valor gira em torno de 32000
bytes, dependendo da verso do Windows). O motivo que a
chamada ao WriteEntry no trunca o texto e teremos um erro
caso muita informao tente ser gravada. Isso um problema
para ns, visto que perderamos a mensagem de erro. Outra
causa comum de no se poder gravar eventos no log a falta de
permisso do usurio.
A Figura 13 mostra um exemplo do log gravado da nossa apli-
cao de clculo de comisso de vendas. Nela, o erro encontrado
foi impossibilidade de se acessar o arquivo da base de dados SQL
Server CE.
Figura 12. Debuggando o windows service

O mtodo ProcessarArquivo cria uma instncia da classe


ProcessadorArquivoVendas (Listagem 1) e repassa para ela o ca-
minho completo do arquivo pendente. ProcessarArquivo muito
importante no nosso exemplo, pois nele em que vamos fazer o
uso do log de eventos e do contador de desempenho.
Alguns dos mtodos da Listagem 3 fazem uso de algumas cons-
tantes. Estas constantes esto definidas na Listagem 4 e foram
criadas para evitar a definio de strings hard code no sistema.

Log de eventos
Quando ocorre um erro em uma aplicao do tipo Windows
Forms, geralmente o prprio usurio pode fornecer detalhes do
que aconteceu simplesmente tirando um print screen da mensa-
gem que ele recebe. J no caso de windows services importante
termos uma forma de armazenar os detalhes dos erros ocorridos
pois esse tipo de aplicao no tem interao com usurio, e con- Figura 13. Exemplo personalizado do log de eventos
sequentemente no temos como depender de uma pessoa para
nos reportar o erro. Contadores de desempenho
Dentro do nosso exemplo, vamos supor que os arquivos penden- Como a nossa aplicao de exemplo um rob para processa-
tes comeassem a se acumular na pasta de processamento. Qual mento de arquivos, vamos incluir um contador de desempenho
seria a causa? Sem o detalhamento do erro no teramos como que gere um indicador de quantos arquivos esto na pasta de
saber se o problema a falta de permisso de escrita na pasta, processamento esperando para serem lidos. O nome deste conta-
se h algum erro de programao, etc. Por isso, importante dor personalizado Arquivos pendentes, agrupado dentro da
armazenarmos os detalhes dos erros em algum lugar para que categoria ComissaoVendas.

22 Easy .Net Magazine Edio 27


Listagem 3. Windows Service de processamento de arquivos

01 usingSystem.ServiceProcess; 44 _contador.RawValue=arquivos.Length;
02 usingSystem.Threading; 45 Thread.Sleep(1000);
03 usingSystem.IO; 46 }
04 usingComissaoVendas.RegrasNegocio; 47 }
05 usingSystem; 48
06 usingSystem.Configuration; 49 privatevoidProcessarLoop(objectstate)
07 usingSystem.Diagnostics; 50 {
08 usingSystem.ComponentModel; 51 while(_emProcessamento)
09 usingSystem.Text; 52 {
10 53 string[]arquivos=Directory.GetFiles(
11 namespaceComissaoVendas.WindowsService _diretorioArquivos,*.txt);
12 { 54 foreach(stringarquivoinarquivos)
13 publicpartialclassServicoComissaoVendas:ServiceBase 55 {
14 { 56 ProcessarArquivo(arquivo);
15 privatestring_diretorioArquivos; 57 }
16 privateThread_threadProcessamento; 58 Thread.Sleep(1000);
17 privateThread_threadContador; 59 }
18 privatevolatilebool_emProcessamento=false; 60 }
19 private PerformanceCounte _contador= new PerformanceCounter( 61
.NOME_CATEGORIA_CONTADOR, Constantes.NOME_CONTADOR,false); 62 privatevoidProcessarArquivo(stringarquivo)
20 63 {
21 publicServicoComissaoVendas() 64 try
22 { 65 {
23 InitializeComponent(); 66 if(File.Exists(arquivo))
24 } 67 {
25 68 ProcessadorArquivoVendasprocessador=
26 protectedoverridevoidOnStart(string[]args) newProcessadorArquivoVendas();
27 { 69 processador.ProcessarArquivo(arquivo);
28 if(args.Length>0&&args[0]==debug) 70 }
29 Debugger.Launch(); 71 }
30 _diretorioArquivos= 72 catch(Exceptionex)
ConfigurationManager.AppSettings[DiretorioArquivos]; 73 {
31 _emProcessamento=true; 74 GravarErroLogWindows(arquivo,ex);
32 _threadProcessamento=newThread(ProcessarLoop); 75 }
33 _threadContador=newThread(ProcessarContagem); 76 }
34 _threadProcessamento.Start(); 77
35 _threadContador.Start(); 78 privatevoidGravarErroLogWindows(stringarquivo,Exceptionex)
30 } 79 {
31 80 StringBuildersb=newStringBuilder();
32 protectedoverridevoidOnStop() 81 sb.AppendFormat(ARQUIVO:{0},arquivo);
33 { 82 sb.AppendLine();
34 _emProcessamento=false; 83 sb.AppendFormat(ERRO:{0},ex.ToString());
35 _threadContador.Join(); 84 stringmensagem=sb.ToString();
36 _threadProcessamento.Join(); 85 if(mensagem.Length>=Constantes.TAM_MAXIMO_CHARS_LOG)
37 } 86 mensagem=mensagem.Substring(0,
38 Constantes.TAM_MAXIMO_CHARS_LOG);
39 privatevoidProcessarContagem() 87 EventLog.WriteEntry(Constantes.SOURCE_EVENTLOG,mensagem,
40 { EventLogEntryType.Error);
41 while(_emProcessamento) 88 }
42 { 89 }
43 string[]arquivos= 90 }
Directory.GetFiles(_diretorioArquivos,*.txt);

Na classe ServicoComissaoVendas (Listagem 3) existe um mem- Listagem 4. Constantes


bro chamado _contadorMedia (linha 19), do tipo PerformanceCoun-
namespaceComissaoVendas
ter, que vamos usar para a comunicao entre nosso sistema e o
{
contador de desempenho. Esse campo inicializado passando-se o publicstaticclassConstantes
nome da categoria e o nome do contador. Alm disso, informado {
publicstaticreadonlystringEVENTLOG=ComissaoVendasApp;
se o contador deve ser considerado como somente leitura ou no. publicstaticreadonlystringSOURCE_EVENTLOG=ComissaoVendas;
Como no nosso caso queremos gravar informaes no contador, publicstaticreadonlyintTAM_MAXIMO_CHARS_LOG=30000;
informamos que ele no deve ser somente leitura.
publicstaticreadonlystringNOME_CATEGORIA_CONTADOR=ComissaoVendas;
Os contadores de desempenho podem ser de vrios tipos, desde publicstaticreadonlystringNOME_CONTADOR=Arquivospendentes;
os mais simples que exibem valores fixos at alguns mais com- }
plexos, que efetuam clculos de mdias. Os mais comuns so: }

Edio 27 Easy .Net Magazine 23


Namespace System.Diagnostics

NumberOfItems32 e NumberOfItems64 Estes tipos de con- na Figura 14 o grfico resultante: quando ele sobe, quer dizer
tadores podem ser utilizados para se rastrear a quantidade de que arquivos novos esto sendo colocados na pasta para proces-
itens existentes no momento. Por exemplo, o contador Memory\ samento; quando ele desce, os arquivos esto sendo consumidos
Available Bytes deste tipo. No nosso exemplo, o contador que pelo nosso windows service.
mostra a quantidade de arquivos que esto pendentes de proces-
samento no momento. A diferena entre os dois contadores que
o com final 32 trabalha com nmeros com 4 bytes, e o de final 64
trabalha com 8 bytes.
RateOfCountsPerSecond32 e RateOfCountsPerSecond64
Este tipo mostra a mdia de operaes que ocorrem em uma
determinada unidade de tempo. Ele calculado automaticamente
pelo sistema operacional e na nossa aplicao de exemplo poderia
ser um contador que mostrasse a taxa de arquivos processados por
segundo. O contador System\ File Read Operations/sec tambm
deste tipo.
AverageTimer32 J este tipo mostra o tempo mdio em que
uma operao leva para ser finalizada. Tambm calculado pelo
sistema operacional, mas necessita de outro contador de desem-
penho auxiliar (AverageBase) para funcionar. Poderamos ter um
contador que mostrasse quanto tempo gasto para se processar 1
GB de arquivos. Um exemplo deste tipo que j existe no Windows Figura 14. Contador de desempenho de arquivos pendentes de processamento
o PhysicalDisk\ Avg. Disk sec/Transfer.
Instalando o servio, o log e o contador
Nota Aps criar o windows service e efetuar as chamadas aos conta-
dores de desempenho e log de eventos, chega o momento em que
Apesar do nosso exemplo apenas demonstrar a escrita em um contador de desempenho, as classes
precisamos instalar esses componentes para que o servio possa
do namespace System.Diagnostics permitem tambm a leitura desses dados. Um sistema poderia,
ser executado. Isso pode ser feito utilizando-se uma classe do
por exemplo, obter informaes da quantidade trafegada na rede atravs dos contadores. De
tipo Installer, adicionada junto classe do windows service. Para
maneira similar, apesar de apenas estarmos escrevendo no log de eventos, tambm possvel ler
cri-la, basta clicar com o boto direito sobre a classe do windows
o contedo de um log do Windows.
service e selecionar a opo Add Installer (Figura 15).

Para alterar o valor de um contador de desempenho possvel


utilizar seguintes mtodos / propriedades, de acordo com o tipo
e o clculo executado pelo prprio sistema operacional para a
exibio dos dados.
I ncrement Adiciona uma unidade ao valor atual do contador
de desempenho.
Decrement Remove uma unidade do valor do contador de
desempenho.
IncrementBy Adiciona ou remove a quantidade de unidades
especificada ao valor do contador de desempenho.
RawValue o valor cru do contador, sem que nenhum clculo
tenha sido executado.

Junto da thread responsvel pelo processamento dos arqui-


vos, no evento OnStart do windows service tambm iniciada Figura 15. Adicionando um instalador em um windows service
uma thread responsvel por alimentar os dados do contador de
desempenho (linha 33) que guarda a quantidade de arquivos Aps escolhida essa opo, automaticamente criada uma classe
pendentes para processamento. este o cdigo que existe no chamada ProjectInstaller. Junto com esta classe so criados dois
mtodo ProcessarContagem (linha 39), que executado a cada componentes responsveis por informar os detalhes de como ser
segundo. Nele feita uma contagem de quantos arquivos TXT feita a instalao do windows service (Figura 16). O primeiro,
existem na pasta de processamento. Esse valor ento passado serviceInstaller1, permite que sejam configurados detalhes como o
para a propriedade RawValue do objeto _contador. Vemos ento nome do windows service, sua descrio e o tipo de inicializao.

24 Easy .Net Magazine Edio 27


J o segundo, o serviceProcessInstaller1, permite que seja informado cdigo para instalar o log e o contador, e o segundo servir para
o usurio que executar o servio. Podemos escolher as opes remov-los quando o windows service no for mais necessrio.
de executar com os usurios locais, como Network Service Isso importante, pois se removermos o windows service do
ou Local system, ou um usurio personalizado, que deve ser computador,no faz mais sentido manter o contador e o log de
informado no momento da instalao. eventos disponveis na mquina.
Vamos primeiro olhar o evento AfterInstall. Nele, a primeira
coisa que feita a verificao da existncia do log de eventos
ComissaoVendasApp (linha 17) e tambm do seu source Co-
missaoVendas. Isso feito utilizando os mtodos estticos Exists
e SourceExists, da classe EventLog. Constatado que ambos no
existem, efetuamos ento a criao do log de eventos e do source,
atravs do mtodo CreateEventSource (linha 18), passando como
parmetros seus nomes.

Nota

Tambm possvel a criao de logs de eventos e contadores de desempenho atravs do uso de


classes Installer especficos (EventLogInstaller e PerformanceCounterInstaller, respectivamente).

Figura 16. Propriedades de instalao do windows service Em seguida temos a criao da categoria ComissaoVendas e
do contador de desempenho Arquivos pendentes. Para se criar
A classe Installer disponibiliza uma srie de eventos nos quais a categoria necessrio agrupar um ou mais objetos contendo os
podemos incluir cdigo para personalizar a instalao. Iremos dados dos contadores (CounterCreationData) dentro de uma cole-
utilizar alguns desses eventos para a criao do log de eventos o (CounterCreationDataCollection). Esta coleo passada en-
ComissaoVendasApp e do contador de desempenho Arquivos to para o mtodo esttico Create (linha 33) da classe Performan-
pendentes. Vamos olhar a Listagem 5, que mostra o cdigo por ceCounterCategory, que efetua ento a criao do(s) contador(es).
trs da classe ProjectInstaller. Nessa listagem vamos utilizar dois Uma dvida pode surgir nesse momento: a criao desses dois
eventos: AfterInstall e AfterUnistall. No primeiro vamos colocar o itens no poderia ser feita quando o windows service iniciasse?

Listagem 5. Classe ProjectInstaller

01 usingSystem.ComponentModel; 24
02 usingSystem.Configuration.Install; 25 CounterCreationDatacontadorMedia=newCounterCreationData()
03 usingSystem.Diagnostics; 26 {
04 27 CounterName=Constantes.NOME_CONTADOR,
05 namespaceComissaoVendas.WindowsService 28 CounterHelp=Constantes.NOME_CONTADOR,
06 { 29 CounterType=PerformanceCounterType.NumberOfItems32
07 [RunInstaller(true)] 30 };
08 publicpartialclassProjectInstaller:System.Configuration.Install.Installer 31 colecaoContadores.Add(contadorMedia);
09 { 32
10 publicProjectInstaller() 33 PerformanceCounterCategory.Create( Constantes.NOME_CATEGORIA_
11 { CONTADOR,Constantes.NOME_CATEGORIA_CONTADOR,
12 InitializeComponent(); 34 PerformanceCounterCategoryType.SingleInstance,colecaoContadores);
13 } 35 }
14 36 }
15 privatevoidProjectInstaller_AfterInstall(objectsender, InstallEventArgse) 37
16 { 38 privatevoidProjectInstaller_AfterUninstall(objectsender,InstallEventArgse)
17 if(!EventLog.Exists(Constantes.EVENTLOG)||!EventLog.SourceExists 39 {
( Constantes.SOURCE_EVENTLOG)) 40 if(EventLog.Exists(Constantes.EVENTLOG))
18 EventLog.CreateEventSource(Constantes.SOURCE_EVENTLOG, 41 EventLog.Delete(Constantes.EVENTLOG);
Constantes.EVENTLOG); 42
19 43 if(PerformanceCounterCategory.Exists( Constantes.NOME_CATEGORIA_
20 if(!PerformanceCounterCategory.Exists( Constantes.NOME_ CONTADOR))
CATEGORIA_CONTADOR)) 44 PerformanceCounterCategory.Delete( Constantes.NOME_CATEGORIA_
21 { CONTADOR);
22 45 }
23 CounterCreationDataCollectioncolecaoContadores= 46 }
newCounterCreationDataCollection(); 47 }

Edio 27 Easy .Net Magazine 25


Namespace System.Diagnostics

A princpio a resposta sim, mas ela traz um problema. As consumir os dados que eles fornecem. Existem ferramentas que
criaes de logs de eventos e de contadores de desempenho automatizam o processo de coleta e anlise desses indicadores,
precisam ser efetuadas com permisses administrativas na como por exemplo, o System Center da Microsoft ou mesmo
mquina. Se fossemos colocar a criao deles junto da execuo recursos prprios do Windows. Por exemplo, seria possvel criar
do windows service seria necessrio configurar um usurio com uma configurao para nosso contador de arquivos pendentes,
alto privilgio para execuo do servio, e isso um problema de forma que quando o mesmo ultrapassar o valor 100, seja en-
de segurana. viado um alerta ao administrador do ambiente, para que ele possa
J no evento ProjectInstaller_AfterUninstall fazemos o contr- proativamente verificar se h algum problema com os servidores
rio. Caso exista o log e o contador, ambos so removidos. Para o ou mesmo entrar em contato com a equipe de desenvolvimento
primeiro usamos o mtodo EventLog.Delete (linha 41), passando antes mesmo de o erro ser percebido pelos usurios.
o nome do log. J para o segundo, usamos PerformanceCounter- recomendvel sempre que haja um novo projeto, que seja
Category.Delete (linha 44), passando o nome da categoria. conversado e combinado entre as equipes de desenvolvimento e
Compilado o windows service com a nova classe Installer, pode- operaes como ser feito o monitoramento da aplicao e quais
mos instalar o servio, o log de eventos e o contador de desempenho so os indicadores mais significativos. nesta integrao entre
utilizando o utilitrio installutil. Ele um aplicativo que vem junto essas duas equipes que reside a grande vantagem de se utilizar
do .NET Framework e pode ser encontrado na pasta C:\Windows\ essas classes do namespace System.Diagnostics.
Microsoft.NET\Framework\v4.0.30319\. Note que o caminho des-
ta pasta pode ser diferente, dependendo de como o Windows foi Fabio Gouw
instalado e de qual verso do .NET estamos trabalhando. fabiogouw@gmail.com
Executamos ento a instalao do servio passando como ar- http://galorebr.blogspot.com
gumento o caminho do executvel (exemplo na Figura 17). Este Certificado Microsoft (MCTS, MCPD), trabalha com TI h nove anos.
aplicativo ento ir analisar o contedo do executvel em busca Atualmente faz parte de uma equipe de desenvolvimento de sistemas para
de qualquer classe do tipo Installer. Ao encontr-lo, o installutil as um rgo do Estado de So Paulo.
executa (no nosso exemplo, encontrar a ProjectInstaller, rodando
todo o cdigo de instalao do windows service, do log de eventos Permisses para uso do EventLog - Windows 2003
e do contador de desempenho). http://galorebr.blogspot.com.br/2008/03/permisses-para-uso-do-
eventlog-windows.html
Acessando arquivos com StreamReader e StreamWriter
http://codigoweb.wordpress.com/2010/02/22/acessando-arquivos-com-
streamreader-e-streamwriter/
Programando threads em C#
http://imasters.com.br/artigo/19541/c-sharp/programando-threads-em-c
System Center 2012
http://www.microsoft.com/en-us/server-cloud/system-center/default.aspx
How to Create an Alert Generating NT-Event-Log-Based Rule in System
Center Essentials
http://technet.microsoft.com/en-us/library/ff730470.aspx
Windows Server Performance Monitor - Data Collector Sets and Alerts
http://www.computerperformance.co.uk/HealthCheck/Alerts.htm
Figura 17. Instalando o windows service Injeo de SQL
http://pt.wikipedia.org/wiki/Inje%C3%A7%C3%A3o_de_SQL
Para remover essa instalao, basta executar novamente o co-
EventLog Class
mando installutil incluindo o parmetro /u. Aps o processo
http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog.aspx
de desinstalao do servio, chamado o evento ProjectInstal-
ler_AfterUninstall, responsvel por remover o log de eventos e o PerformanceCounterType Enumeration (tipos de contadores)
contador de desempenho. http://msdn.microsoft.com/en-us/library/system.diagnostics.
performancecountertype.aspx
Concluso EventLogInstaller Class
odo o nosso trabalho para criar logs de eventos e contadores
T http://msdn.microsoft.com/en-us/library/system.diagnostics.eventloginstaller.aspx
de desempenho personalizados de nada vai adiantar se ningum

26 Easy .Net Magazine Edio 27


Desenvolvendo um blog
com ASP.NET Parte 2
Aspectos da interface do usurio

Este artigo faz parte de um curso Resumo DevMan


Desenvolvendo um blog com ASP.NET Parte 2:
Todas as tecnologias relacionadas com o desenvolvimento e ma-
nuteno de aplicativos para a internet so complexas e ricas em

E
xistem muitas plataformas para desenvolver recursos. Hoje h uma grande variedade de plataformas, linguagens,
aplicaes Web. Desde tecnologias que ocultam design patterns, boas prticas e ferramentas que podem ajudar a
grande parte da complexidade do gerenciamen- atingir seus objetivos.
to do estado da aplicao at aquelas que deixam este ASP.NET em conjunto com Web Forms uma destas opes que
totalmente sob a responsabilidade do programador, veio sendo consolidado durante os anos. Iniciando as novidades para
possvel fazer praticamente qualquer coisa em um enriquecer a interface com o usurio vamos conhecer a biblioteca
browser. AJAX Control Toolkit que, quando utilizada com o ASP.NET, torna suas
A justificativa para usar uma aplicao Web sendo aplicaes mais interessantes adicionando pouco ou quase nenhum
executada em um browser em vez de uma aplicao trabalho no desenvolvimento.
desktop que esta principalmente dispensa a instalao Falando em melhorias na interface, para aqueles que leram a primeira
e configurao da parte do usurio e um maior controle parte do artigo devem ter achado que a aplicao ficou sem graa,
do programador j que todos os usurios tero o mesmo afinal, nenhuma formatao foi feita. Nesta edio vamos criar uma
cdigo e o mesmo ambiente. Quanto configurao, formatao usando as folhas de estilo CSS. Durante o desenrolar do
por estar localizada em um servidor, basta que esta no texto voc ir entender porque sempre melhor usar esta formatao
prprio servidor. em sua aplicao Web.
Dentro deste cenrio surgiu h alguns anos atrs a Evoluindo um pouco mais na utilizao do Entity Framework para o
plataforma Active Server Pages. Sua principal motivao trabalho com os dados, veremos o que pode ser feito para estender
foi dar ao desenvolvedor a possibilidade de manipular as classes originalmente mapeadas no banco de dados atravs do
com facilidade a formatao das pginas no servidor uso das partial classes.
da mesma forma que na poca ele podia fazer com as
aplicaes desktop, arrastando controles visuais para Em que situao o tema til:
um designer e fazendo a sua formatao. Aliado a isto Voc vai poder usar este artigo como referncia para os recursos
tnhamos tambm a possibilidade de escrever pequenas do ASP.NET e tambm para tirar dvidas sobre como usar alguns
partes de cdigo para responder a eventos como cliques componentes para melhorar os recursos da sua interface ou ainda,
em botes ou links e preenchimentos em campos. Uma como tirar proveito das folhas de estilo CSS para criar determinados
vez compilada e hospedada em um servidor, estas pgi- estilos de formatao e efeitos em sua aplicao.
nas eram acessadas pelos browsers normalmente como
as demais aplicaes, mas o servidor que recebia dados
sobre o browser que estava fazendo a solicitao gerava bsica para a pgina e cdigo em uma linguagem gerenciada do
o cdigo HTML necessrio para exibir esta pgina j .NET para manipular as regras de negcio.
adaptada a verso do browser para (tentar) otimizar Com o Visual Studio o desenvolvedor tem a opo de arrastar
este processo. e soltar os controles visuais para a interface e fazer a formata-
Esta tecnologia foi a base para o ASP.NET. Neste so o usando os editores de propriedades ou, se preferir, editar
usados controles de servidor para criar uma formatao manualmente as tags HTML referentes aos controles e fazer

Edio 27 Easy .Net Magazine 27


Desenvolvendo um blog com ASP.NET Parte 2

a formatao usando suas propriedades, ou ainda, fazendo Outro ponto de vista importante com relao formatao.
uso de classes em CSS. Esta forma de trabalhar com o ASP Esta precisa permitir sua fcil manuteno e modificao, algo
.NET ficou conhecida como ASP.NET Web Forms. Lembrando que difcil de fazer caso esteja vinculada diretamente com as
que um formulrio tudo o que est localizado dentro da tag propriedades do controle. Para simplificar, use folhas de estilo,
<form> que nativa do HTML. No possvel usar controles que veremos mais a frente.
ASP.NET fora desta TAG. Por fim, existem validaes e tarefas que podem ser feitas ainda
Um dos diferenciais do ASP.NET a possibilidade de manipular no browser do seu usurio com o JavaScript. Algumas destas fo-
a pgina usando linguagens de programao originalmente no ram apresentadas na primeira parte do artigo e com o ASP.NET
orientadas para a Web para obter os dados da pgina e enviar pode-se usar alguns server controls como os validators para gerar
para o servidor. Sem o ASP.NET necessrio conhecimento a validao do lado cliente automaticamente.
avanado de JavaScript, HTML e DOM (Nota do DevMan 1)
para fazer esta tarefa.
Um dos problemas ao usar ASP.NET que no tem muito
controle com o cdigo gerado no servidor para renderizar e
Nota do DevMan 1
enviar a pgina para o browser que fez a solicitao. Em muitos
DOM a sigla para Document Object Model e consiste em um conjunto de prticas e tcnicas
casos, se o desenvolvedor simplesmente arrastar componentes (patterns) usando HTML, XHTML (um subconjunto de HTML e XML) para fazer a manipulao dos
sem tomar cuidado e sem seguir padres de desenvolvimento, dados de documentos HTML e XML.
o carregamento e comportamento destas pginas podem ficar
comprometidos por tornar-se muito pesado devido ao excesso
de cdigo gerado. AJAX
importante considerar que o cdigo que vemos no Visual Os controles do ASP.NET so todos baseados no servidor. Entre-
Studio referente s marcaes HTML para os server side controls tanto, para atualizar e construir pginas baseadas nestes controles,
diferente daquele que enviado para o browser. Lembre-se de necessrio que haja um processo conhecido como server round
que browsers, mesmo os mais sofisticados, interpretam apenas trip, que o envio da requisio para o servidor que vai renderizar
HTML e JavaScript e o que d para fazer com estes dois no a pgina e enviar a mesma novamente para o browser.
pouca coisa. Infelizmente, muitas vezes, pela gerao do cdigo Este processo requer que toda a pgina do lado do servidor seja
ser automatizada e considerada um cenrio padro, muito cdigo reconstruda, o que quase sempre um processo lento dependen-
desnecessrio gerado. do do nmero de controles da pgina.
Por causa de programadores descuidados e de falta de critrio Para resolver este problema e tornar a experincia do usurio
na hora de usar o ASP.NET, hoje existe um nmero considervel em aplicaes Web mais atraente desenvolveu-se alguns anos
de desenvolvedores Web que abandonaram a sua utilizao e atrs um conjunto de tecnologias denominado AJAX, tecnologia
esto voltando-se para o HTML puro novamente, o que garante que em conjunto com o XMLHttpRequest dos browsers permite
maior controle da aplicao, embora, aumente consideravelmente a atualizao parcial do contedo de uma pgina Web.
o trabalho do desenvolvimento. Com esta tecnologia o servidor fornece dados que iro partici-
Paralelamente a isto tudo existem programadores com bom par da renderizao da pgina no browser do usurio. Os dados
senso que se aprofundam nas tecnologias que esto adotando fazem parte do contedo que pode corresponder a controles
para fazer destas a melhor aplicao. O ASP.NET bom e a prova como botes, caixas de listagem e texto que j foram carregados
disso o nmero de usurios existente e de empresas que criam previamente e que agora, so apenas preenchidos com os dados
componentes personalizados para esta plataforma. Alm disto, vindos do servidor.
desde a verso 3.5 do Framework .NET possvel associar o A biblioteca inicial para quem deseja iniciar o trabalho com o
desenvolvimento ASP.NET com design patterns como o MVC AJAX no Visual Studio e no ASP.NET o AJAX Control Toolkit.
que exige a separao bem definida entre as camadas de dados Isso porque existem outras. Esta indicada para o incio da com-
(Model), exibio destes (View) e da forma como estas duas se preenso e vai ser usada no projeto de exemplo.
comunicam (Controller).
Uma das boas prticas a ser seguida no desenvolvimento ASP
.NET usar server controls (TextBox, Label, ComboBox, etc.)
apenas quando no for possvel trabalhar com controles HTML Tutorial
puro. Assim, se voc precisa exibir dados de forma dinmica, que
dependem de informaes que esto localizadas em um banco
de dados, por exemplo, esperado e at conveniente que utilize AJAX Control Toolkit
os server controls. J em casos de dados estticos como textos Para comear a usar esta biblioteca necessrio fazer o seu
explicativos, ttulos, etc., o ideal usar os controles HTML para download no site do projeto (vide seo Links) e descompactar o
acelerar a carga da sua pgina. contedo do arquivo em uma pasta.

28 Easy .Net Magazine Edio 27


Em seguida, voc precisa criar uma aba na toolbox do Visual Finalizado este processo o Visual Studio passar a exibir os
Studio para armazenar os controles da biblioteca, faa isso cli- controles desta biblioteca, como mostrado na Figura 3, que podem
cando com o boto direito do mouse sobre a toolbox e escolha a ser arrastados para seus Web Forms. Durante a elaborao do
opo Add Tab (Figura 1) e digite o nome Ajax toolkit. projeto de exemplo ser demonstrada a utilizao de um destes
componentes.

Figura 1. Adicionando uma nova aba - Passo 1

Com a aba criada, devemos agora adicionar os componentes Figura 3. Toolbox AJAX Toolkit
clicando com o boto direito do mouse sobre a tab recm-criada
e escolhendo a opo Choose Items. O funcionamento deste toolkit e dos seus controles consiste basi-
O processo continua navegando pelo sistema de arquivos do camente na gerao do script necessrio para gerenciar requisies
seu computador para localizar a pasta onde foi descompactado o e respostas do servidor pelo lado do cliente. Para que isto seja feito
arquivo com os componentes. Isto feito clicando no boto Browse corretamente o primeiro elemento que deve estar presente na
da aba .NET Framework Components que vai exibir uma janela pgina o ToolKitScriptManager, responsvel pelo gerenciamento
para pesquisar pastas e arquivos do Windows. Nesta devemos destas requisies. Este componente no visual bem simples de
localizar o arquivo AjaxControlToolkit.dll, selecionar o mesmo trabalhar, precisando apenas ser arrastado. S a sua presena j
e clicar em OK. garante o correto funcionamento dos controles.
Com o arquivo da biblioteca selecionado o Visual Studio retorna Com relao performance do AJAX existem algumas restries.
para a janela j com os controles AJAX selecionados, como mos- Como foi considerado no tpico sobre o ASP.NET, o cdigo dos com-
trado na Figura 2. Clicando em OK o processo concludo. ponentes AJAX gerado no servidor. Se houverem muitos componen-
tes a tendncia que a carga inicial da pgina fique muito lenta.
Desta forma, preciso usar os controles com critrio. Este critrio
difcil porque cada projeto tem suas caractersticas particulares.
Uma boa dica usar componentes desta biblioteca apenas onde
o tempo de resposta for algo muito importante para o correto
funcionamento, como por exemplo, controles de calendrio ou
de formatao dinmica.

Query String
Na primeira parte do artigo fizemos a transferncia de dados
entre as pginas usando as variveis de sesso (Sessions) do ASP
.NET. Nesta parte veremos um pouco mais sobre como fazer esta
transferncia usando outro recurso chamado de QueryString.
Consiste em colocar o nome da varivel e o valor no campo de
endereo do browser, logo aps a URL da pgina, precedido pelo
ponto de interrogao da seguinte forma:

Figura 2. Controles AJAX selecionados http://minhaaplicacao.com/Customer.aspx?ID=COMMI

Edio 27 Easy .Net Magazine 29


Desenvolvendo um blog com ASP.NET Parte 2

Para ler corretamente estes valores, no seu cdigo em C# escreva Porm, existem situaes em que isso pode ser insuficiente para
um manipulador para o evento Load da pgina (ou onde achar modelar os dados e a regra de negcios da aplicao.
conveniente) como no exemplo da Listagem 1. Se voc procurar na solution vai encontrar o cdigo que define
as classes do Entity Framework. E cada entidade est definida
desta forma:
Listagem 1. Obtendo parmetros a partir da QueryString

01 protected void Page_Load(object sender, EventArgs e) [Serializable()]


02 { [DataContractAttribute(IsReference=true)]
03 btnSend.Enabled = false; publicpartialclassblogs:EntityObject
04 if (!Page.IsPostBack) .
05 {
06 if (Request.QueryString[ID] != null)
07 loadCustomer(Request.QueryString[ID].ToString());
Observe que as entidades so criadas como partial, o que sig-
08 } nifica que voc pode estender estas em outros arquivos do seu
09 } projeto e implementar novas propriedades e mtodos.
Durante a parte de apresentao do exemplo voltaremos a tratar
deste assunto com mais detalhes e um exemplo aplicando este
Nessa listagem verificamos inicialmente se a requisio um conceito.
PostBack da pgina, ou seja, algum controle da pgina (que j Se voc quiser visualizar o cdigo referente a isto deve procurar
estava renderizada) faz uma nova requisio para o servidor. na janela Solution Explorer pelo arquivo referente ao data model,
Neste caso, no vai ser necessrio verificar os parmetros passados expandir e visualizar o documento com o cdigo em C#. A Figura 4
na carga da pgina, fazendo com que o cdigo dentro do IF seja ilustra este arquivo no projeto de exemplo.
executado apenas na primeira requisio pgina.
A maneira que recuperando o valor passando como indexador
(j que QueryString uma coleo de dados) o nome da varivel
que desejamos recuperar. Neste exemplo foi usada uma varivel
chamada ID. preciso tomar cuidado ao recuperar estas va-
riveis, pois se elas no forem definidas na URL da requisio
retornaro valor null, por isso sempre interessante tratar esta
possibilidade, como mostrado na linha 76.
Em aplicaes mais simples bem provvel que exista apenas
uma varivel no QueryString, porm, a tendncia enviar mais
dessas variveis. Quando isto acontecer, cada uma deve estar
separada pelo smbolo ampersand (&):

http://minhaaplicacao.com/Customer.aspx?Delete=true&ID=COMMI

Em seguida pode-se acessar estas pelo nome ou, usando um


ndice numrico:

If(Request.QueryString[0] != null)
...
Figura 4. Visualizando o cdigo do Data Model
Voc pode tambm achar conveniente obter o nome de todas as
chaves que foram passadas, evitando erros de programao ao
acessar um item que no existe. Para obter todas as chaves que Folhas de Estilo CSS
foram passadas use a propriedade AllKeys desta forma: ASP.NET compatvel com folhas de estilo em cascata (CSS)
o que significa que voc pode (na verdade, deve) definir estilos
var obj = Request.QueryString.AllKeys;
previamente para que sejam usados em todo o projeto e garantam
Esta propriedade retorna um array de string com todos os nomes a uniformidade de formatao de suas pginas.
que foram passados. A principal vantagem ao utilizar este recurso que diminui a
complexidade do cdigo HTML usado para carregar a pgina. Em
Entity Framework e Partial Classes vez de definir os estilos e formatao em cada elemento e server
Continuando com os recursos que foram apresentados na pri- control da pgina, associam-se estes a um estilo css.
meira parte do artigo, ao usarmos Entity Framework para fazer o Dessa forma, alm da carga da pgina ser realizada mais rapi-
mapeamento dos dados, foi feito apenas o trabalho bsico de criar damente, uma vez que o contedo HTML fica mais limpo, para o
as classes correspondentes s tabelas no banco de dados. desenvolvedor fica mais fcil fazer qualquer manuteno, pois ao

30 Easy .Net Magazine Edio 27


mudar a regra de formatao de um estilo esta alterao refletida CssClass o InteliSense do Visual Studio mostra as classes que
em todos os controles que utilizam este estilo. esto referenciadas no arquivo ASP.NET, como mostrado na
Um dos pontos chave a destacar a possibilidade de alterar- Figura 7.
mos os estilos globais do HTML definindo estilos para tags
como <body> <p> e <a>. Para isso a classe ( assim como so
chamados os conjuntos de estilos) deve ter o nome da tag html
em questo, como podemos ver no exemplo na Listagem 2.
No exemplo da Listagem 2 modificada a tag <body>, desta
forma, toda pgina que fizer referncia ao arquivo que contm
esta classe de estilo ter automaticamente a formatao definida
na classe aplicada para todo o contedo da pgina, sem que
seja necessrio sequer referenciar a classe.
Por outro lado, para criar classes que podem ser aplicadas
para diversos elementos precisamos usar um ponto (.) como
primeiro caractere do nome desta, como podemos ver na Figura 5. Menu de contexto para abrir o assistente de CSS
Listagem 3.

Listagem 2. Css para um elemento HTML

01 body
02 {
03 font-family:Verdana,Arial,Helvetica,sans-serif;
04 font-size:12px;
05 margin-top:0;
06 margin-bottom:0;
07 margin-left:0;
08 margin-right:0;
09 width:100%;
10 }

Listagem 3. Css com uma classe especfica

01 .command
02 {
03 border:2pxoutset#000099;
04 padding:8px;
05 font-family:Arial,Helvetica,sans-serif;
06 font-size:small;
07 color:#FFFFFF;
08 background-color:#0039FF;
09 }
Figura 6. Janela do assistente para construo de estilo

O Visual Studio possui muitas ferramentas que facilitam o


trabalho com folhas de estilo, o primeiro um assistente que
pode ser chamado na janela de editor de cdigo que serve para
tornar o processo de criao de estilos geralmente demorado
e trabalhoso por no ter um resultado imediato um pouco
mais fcil. Para usar este assistente, basta editar o arquivo CSS,
clicar com o boto direito do mouse sobre uma classe e escolher
o comando Build Style como demonstrado na Figura 5.
Ao fazer isto ser aberta uma janela como a da Figura 6 permi- Figura 7. InteliSense para o CSS
tindo a definio dos principais elementos que compem uma
classe de estilo como, por exemplo, as regras de formatao de Lembrando que voc pode ter mais de uma folha de estilos
fonte, cor de fundo, bordas, dentre outras, possibilitando ainda referenciadas em uma pgina ASP.NET. Basta usar quantas fo-
uma pr-visualizao do estilo sem que seja necessrio rodar rem necessrias na tag <head> do arquivo, como mostrado na
a aplicao para ver como o mesmo ficaria. Listagem 4.
Se voc j trabalhou com o editor HTML deve ter percebido Veremos mais informaes sobre folhas de estilo durante a ex-
tambm que ao informar a classe CSS no atributo class ou plicao das melhorias feitas na aplicao de exemplo.

Edio 27 Easy .Net Magazine 31


Desenvolvendo um blog com ASP.NET Parte 2

Listagem 4. Css para um elemento HTML Listagem 5. Classe posts estendida

<headrunat=server> 01using System;


<title></title> 02using System.Data.Objects.DataClasses;
<linkhref=~/css/base.cssrel=stylesheettype=text/css/> 03
<linkhref=~/css/grid.cssrel=stylesheettype=text/css/> 04namespace BlogEngine
</head> 05{
06 public partial class posts : EntityObject
07 {
Aperfeioando a aplicao 08 public String PostUrl
09 {
Voltando a falar da primeira parte do artigo, nela foi feita a regra
10 get
de negcios do projeto e as pginas para: 11 {
1. Login 12 return String.Format(posts.aspx?id={0}, this.id);
13 }
2. Criao de novo blog 14 }
3. Gerenciamento de um blog 15 }
4. Insero de um novo post 16}

Estas tarefas usaram um layout bsico, sendo que nenhuma


formatao foi aplicada nas pginas. Os dois pontos mais importantes deste cdigo esto na declara-
o do namespace (linha 4) e da classe (linha 6).
Neste segundo artigo, o projeto vai ser aperfeioado e ser O namespace deve ser o mesmo que foi declarado no DataModel.
acrescentado as seguintes melhorias: Quando voc adiciona uma classe dentro de uma pasta no projeto,
1. Exibio da pgina inicial do blog para os usurios o Visual Studio assume que a pasta deve ser acrescentada ao na-
2. Exibio das publicaes mespace. Dessa forma, a classe que foi criada ficar com o nome
3. Melhorias na pgina de gerenciamento do blog com a possibi- de namespace definido como BlogEngine.Data. Se for executar o
lidade de visualizar as pginas do blog projeto ou qualquer outro onde os arquivos das classes fiquem
4. Definio da formatao das pginas. em uma pasta, fique atento a este detalhe.
J a declarao da classe deve seguir o mesmo padro usado no
Para a formatao vou usar folhas de estilo para demonstrar DataModel e a ateno redobrada sobre a palavra chave do C#
alguns dos seus recursos. Se voc acompanhar o trabalho vai partial precedendo o termo class. Isto vai indicar para o compi-
perceber que se trata de um estilo espartano, bem bsico apenas lador que trata-se de uma classe que estende ou complementa o
para demonstrar as capacidades do ASP.NET quando usado em contedo de outro arquivo do projeto.
conjunto com CSS. A propriedade PostUrl retorna uma string contendo o link
Tambm ser acrescentado um controle AJAX para deixar a formado para a carga do post. Esta propriedade assume que os
pgina de criao do post um pouco mais atraente. dados j esto carregados do banco.
Para executar este projeto ser utilizado as mesmas ferramentas
da primeira parte: A pgina inicial do blog
1. SQL Server Express 2012. Pode usar tambm o SQL Server 2008 A primeira melhoria a ser feita a criao da pgina inicial do blog
para o banco de dados. para ser exibida aos visitantes. Para que ela seja carregada, os dados
2. Visual Studio 2010. sero carregados dinamicamente partindo do id do blog que ser en-
viado em conjunto com o endereo da pgina usando QueryString.
Estendendo a classe posts O design desta pgina pode ser conferido na Figura 8.
Neste projeto, para acessar os posts do blog, o link para direcio- Os principais elementos so o ttulo do blog que vai ser preenchido
nar o usurio para estes ser criado dinamicamente. dinamicamente, a descrio que foi informada no momento do seu
A carga do post vai ser feita em uma pgina ASPX definida mais cadastro, o ltimo artigo publicado, com seu ttulo e corpo, sendo
adiante que vai ser chamada de posts.aspx. Durante a sua carga que o ttulo vai oferecer um atalho para visualizao do post.
dever ser verificado o ID do post que deseja carregar. Logo aps o ltimo post exibida uma lista com os cinco l-
Para facilitar a gerao da URL optamos por estender a classe timos posts com o ttulo dos mesmos contendo um atalho para
posts que foi definida no DataModel de modo a acrescentar uma acessar o post.
propriedade que gera este elemento. Nesta pgina tambm exibido um painel do lado direito com os
Colocamos esta classe em uma pasta chamada data no projeto detalhes do blog, como o nome do autor, o nmero de publicaes
por tratar-se de uma classe referente a dados. A Listagem 5 mostra e a data de criao do blog.
como esta classe ficou definida. Antes de acrescentar esta pgina ao projeto necessrio criar
Para adicionar uma nova classe basta clicar com o boto direito uma pasta para separar as pginas referentes ao contedo do blog
do mouse sobre a pasta e selecionar Add => Class. daquelas que so usadas para o gerenciamento.

32 Easy .Net Magazine Edio 27


Esta pasta foi chamada pages e armazena a pgina inicial do Note na Figura 9 que tambm foi separada uma pasta para
blog e a pgina que usada como template para o post. armazenar as folhas de estilo CSS. Isto no obrigatrio, mas
A Figura 9 mostra esta pasta criada na janela Solution Explorer. O ajuda na separao de elementos e na organizao do projeto. A
processo para criar uma pgina ASPX dentro de uma pasta o mesmo marcao HTML para a pgina, que foi chamada de blog.aspx,
para criar outros elementos na pasta raiz. Deve clicar com o boto pode ser conferida na Listagem 6.
direito do mouse sobre a pasta e escolher o menu Add > New Item.

Figura 9. Estrutura de pastas


Figura 8. Pgina inicial do blog

Listagem 6. Marcao HTML da pgina

01 <%@ Page Language=C# 40 CssClass=GridBase


02 AutoEventWireup=true 41 AutoGenerateColumns=false>
03 CodeBehind=blog.aspx.cs 42 <HeaderStyle CssClass=GridBase GridTitle />
04 Inherits=BlogEngine.pages.blog %> 43 <RowStyle CssClass=GridBase />
05 44 <AlternatingRowStyle CssClass=GridBase GridAlternate />
06 <!DOCTYPE html PUBLIC -//W3C//DTDXHTML1.0Transitional// EN 45 <Columns>
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd> 46 <asp:HyperLinkField
07 47 DataTextField=post_title
08 <html xmlns=http://www.w3.org/1999/xhtml> 48 DataNavigateUrlFields=PostUrl
09 <head runat=server> 49 HeaderText=Publicao />
10 <title>BlogEngineDefault</title> 50 <asp:BoundField
11 </head> 51 DataField=date_created
12 <body> 52 DataFormatString={0:dd/MM/yyyy}
13 <form id=form1 runat=server> 53 HeaderText=Data
14 <h1><asp:Label 54 HtmlEncode=false />
15 runat=server 55 </Columns>
16 Text=PginaInicial 56 </asp:GridView>
17 ID=lblTitle /></h1> 57 </td>
18 <table style=width:100% cellspacing=0 cellpadding=0> 58 <td>
19 <tr> 59 <h3>Detalhes do Blog</h3>
20 <td style=width:70%> 60 <asp:Label
21 <asp:Label 61 runat=server
22 runat=server 62 Text=Escritopor:
23 ID=lblDescription /> 63 ID=lblAuthor />
24 <br /> 64 <br />
25 <h3> 65 <asp:Label
26 <asp:HyperLink 66 runat=server
27 NavigateUrl= 67 Text=Nenhumapublicao
28 ID=hypLastPostTitle 68 ID=lblPosts />
29 Text=ltimopost 69 <br />
30 runat=server /></h3> 70 <asp:Label
31 <br /> 71 runat=server
32 <asp:label 72 Text=Criadoemdd/MM/yyyy
33 runat=server 73 ID=lblDate />
34 ID=lblPostText /> 74 </td>
35 <br /> 75 </tr>
36 <h3>PostsRecentes</h3> 76 </table>
37 <asp:GridView 77 </form>
38 runat=server 78 </body>
39 ID=grdPosts 79 </html>

Edio 27 Easy .Net Magazine 33


Desenvolvendo um blog com ASP.NET Parte 2

Esta pgina tem os componentes da Tabela 1 onde voc pode Listagem 7. Carga da pgina
conferir as configuraes das principais propriedades. Nas proprie-
01 using System;
dades j esto sendo colocadas as classes CSS que sero usadas. 02 using System.Configuration;
O bloco que inicia com a tag <asp:GridView> na linha 37, re- 03 using System.Linq;
ferente grid completa. Dentro deste esto aninhados os blocos 04 using System.Web.UI;
05
referentes ao estilo do cabealho na linha 42, referente ao estilo 06 namespace BlogEngine.pages
das linhas (linha 43) e referente s linhas alternadas (linha 44). 07 {
A partir da linha 45 inicia-se a definio das colunas que estaro 08 public partial class blog : System.Web.UI.Page
09 {
vinculadas com as propriedades da classe Blog. 10 protected void Page_Load(object sender, EventArgs e)
Um ponto importante na definio da coluna que vai mostrar a 11 {
12 if (Page.IsPostBack)
data o elemento HtmlEncode (na linha 54) definido como false
13 return;
para que a string de formatao (linha 52) possa ser aplicada ao 14
campo. Caso esta propriedade no seja definida, a string no 15 if (Request.QueryString.Count == 0)
16 {
tem efeito.
17 Response.Redirect(../default.aspx);
Esta pgina uma das mais dinmicas da aplicao. Todo 18 return;
o seu contedo construdo durante a execuo partindo do 19 }
20
contedo do banco de dados. Assim, o primeiro cdigo a ser 21 load();
escrito corresponde ao evento Page_load (executado sempre que 22 }
feita uma chamada para a pgina) e que pode ser conferido na
Listagem 7.
O mtodo verifica se a pgina est sendo recarregada em Neste caso fazemos o direcionamento para a pgina default, mas
resposta a uma solicitao; em seguida verifica se foi passado em uma situao de real vai ser necessrio usar outra pgina com
algum parmetro na string do endereo usando QueryString e uma mensagem mais significativa para o usurio de forma que
faz chamada ao mtodo load para fazer a carga. deixe claro que houve algum problema com a carga da pgina.
Na linha 15 o cdigo verifica o nmero de parmetros Query- Podemos ver o mtodo load que faz a carga dos dados na
String que foi enviado, caso por algum motivo nenhum parmetro Listagem 8.
tenha sido enviado, a pgina redirecionada para a pgina default O mtodo load chama outro mtodo na linha 03 responsvel pela
da aplicao e o mtodo encerra. carga dos dados enviando como parmetro deste o valor passado

Controle Propriedade Valor Comentrio


ID lblDescription
Este componente serve como ttulo do blog e preenchido dinamicamente a partir do banco
Label Runat Server
de dados.
CssClass TableHeader
NavigateUrl
ID hypLastPostTitle
Este componente vai ser usado para abrigar o link para visualizao do post em uma pgina em
HyperLink Text ltimo post
separado.
Runat Server
CssClass TableHeader
Runat Server
Label Recebe o contedo do post para apresentar na pgina inicial.
ID lblPostText
Runat Server
ID grdPosts Controle Grid para listar os posts recentes do blog. A forma mais fcil de configurar o controle
GridView
CssClass GridBase GridView usando a marcao HTML.
AutoGenerateColumns false
Runat server
Label Text Escrito por:
ID lblAuthor
Runat server
Label Text Nenhuma publicao
ID lblPosts
runat server
Label Text Criado em dd/MM/yyyy
ID lblDate

Tabela 1. Controles da pgina Blog.aspx

34 Easy .Net Magazine Edio 27


na QueryString referente varivel id. O mtodo para a carga Ao fazer isto todas as propriedades, inclusive os posts vinculados,
dos dados est descrito na Listagem 9. esto sendo passados para o objeto. Neste exemplo, este tipo de
Neste exemplo estou passando o contedo da QueryString abordagem mapeando todas as propriedades do objeto, no traz
considerando que foi passada a varivel com este nome. Em nenhum problema porque so poucos os dados que esto sen-
uma aplicao mais robusta, deve ser feito o tratamento como do carregados, porm, ao trabalhar com aplicaes reais, tome
foi apresentado no tpico sobre Query String durante a primeira cuidado em carregar somente os dados necessrios para evitar
parte do artigo. problemas de lentido com a carga de grandes quantidades de
A partir da linha 05, verificamos se o objeto que foi retornado informao no seu objeto.
durante a carga est nulo, neste caso, redireciona novamente para Finalizando o mtodo temos o bloco if da linha 10 que testa se
a pgina default da aplicao. existem dados para serem retornados.
Em caso de sucesso na carga dos dados o objeto enviado para O mtodo loadBlogData, da Listagem 10, responsvel por vin-
o mtodo que faz o vnculo dos dados com os controles e que est cular os dados do objeto do tipo blogs enviado como argumento,
sendo descrito na Listagem 9. com os controles da pgina.

Listagem 8. Mtodo load Listagem 10 Construo do contedo da pgina

01 private void load() 01 private void loadBlogData(BlogEngine.blogs blog)


02 { 02 {
03 var blog = selectBlog(Request.QueryString[id].ToString()); 03 lblAuthor.Text = String.Format(Publicado por: {0},
04 04 blog.admin_name);
05 if (blog == null) 05 lblDate.Text = String.Format(Criado em {0:dd/MM/yyyy},
06 { 06 blog.date_created);
07 Response.Redirect(../default.aspx); 07 lblDescription.Text = blog.description;
08 return; 08
09 } 09 if (blog.posts.Count > 0)
10 10 {
11 loadBlogData(blog); 11 hypLastPostTitle.Text = blog.posts.Last().post_title;
12 } 12 hypLastPostTitle.NavigateUrl = blog.posts.Last().PostUrl;
13 lblPostText.Text = blog.posts.Last().content;
Listagem 9. Carga dos dados com LINQ 14 lblPosts.Text =
15 String.Format(blog.posts.Count == 1 ?
01 private BlogEngine.blogs selectBlog(string blogId) 16 {0} publicao :
02 { 17 {0} publicaes, blog.posts.Count);
03 var model = new BlogEngineEntities(ConfigurationManager 18 }
04 .ConnectionStrings[BlogEngineEntities].ToString()); 19
05 var blogIdInt = Convert.ToInt32(blogId); 20 grdPosts.DataSource = blog.posts.OrderByDescending(p => p.id).Take(5);
06 var obj = from b in model.blogs 21 grdPosts.DataBind();
07 where b.id == blogIdInt 22 Page.Title = blog.name;
08 select b; 23 lblTitle.Text = blog.name;
09 24 }
10 if (obj != null && obj.ToList().Count > 0)
11 return obj.ToList()[0];
12 else
13 return null; O cdigo inteiro no tem muitas novidades, onde cada linha
14 }
basicamente envia para os controles os dados do objeto.
Na linha 11, que est dentro de um bloco if executado caso exis-
O mtodo selectBlog recebe o id do blog e usando LINQ busca no tam posts vinculados, passado o ttulo do ltimo post que foi
banco de dados uma instncia do objeto correspondente ao id que carregado do banco. Para obter este registro basta usar o mtodo
foi passado. Importante observar que nesta instncia encontram- Last().
se tambm as publicaes vinculadas com o blog. Continuando com a carga do post, a URL usada para o mesmo
Inicialmente o cdigo da linha 03 cria uma instncia do Data- carregada a partir da propriedade PostUrl , que foi definida na
Model, necessrio para fazer a consulta com LINQ. Ao criar a partial class que usamos para estender a classe posts.
instncia, est sendo enviada a string de conexo, previamente As demais linhas at o fim do bloco na linha 18 continuam
armazenada no arquivo Web.Config. carregando os dados do post.
Na linha 05 estou convertendo o id que foi passado como Na linha 20 o cdigo est vinculando a grid com as ltimas cinco
argumento do mtodo para o tipo inteiro para que possa ser postagens carregadas. Para isso, primeiramente a lista ordenada
comparado com o id que est no banco de dados na formao da de forma descendente com o extension method OrderByDescen-
instruo LINQ. ding e so obtidos os ltimos cinco registros usando Take() onde o
Esta instruo est disposta das linhas 06 08. O destaque argumento que deve ser usado corresponde ao nmero de linhas
est na linha 08 onde selecionado o objeto blog completo. desejado. Take(<n>) sempre retorna as <n> primeiras linhas da

Edio 27 Easy .Net Magazine 35


Desenvolvendo um blog com ASP.NET Parte 2

lista, como neste caso colocamos a lista em ordem descendente, Na Tabela 2 segue a configurao das propriedades dos controles
vo ser retornadas as ltimas <n>. que esto nesta pgina. Note que na tabela j esto includas as
classes CSS que sero usadas.
Pgina para exibio das publicaes A parte principal desta pgina est na sua carga. Novamente
Para exibir o contedo de um post foi adicionada uma pgina obtido o id do post que deve carregar atravs da QueryString.
nomeada como posts.aspx. O design bsico da pgina, ainda sem O evento responsvel pelo preenchimento dos dados o Page_
o estilo aplicado, pode ser conferido na Figura 10. Load cujo mtodo pode ser conferido na Listagem 12.
Esta pgina tem a marcao HTML como da Listagem 11.

Listagem 11. Marcao HTML inicial

01 <%@ Page Language=C#


02 AutoEventWireup=true
03 CodeBehind=posts.aspx.cs
04 Inherits=BlogEngine.pages.posts %>
05
06 <!DOCTYPE html PUBLIC -07
//W3C//DTDXHTML1.0Transitional//EN http://www.w3.org/TR/ Figura 10. Visualizao de post
xhtml1/DTD/xhtml1-08 transitional.dtd>
09
10 <html xmlns=http://www.w3.org/1999/xhtml> Listagem 12. Carga inicial da pgina
11 <head runat=server>
12 <title></title> 01 using System;
13 </head> 02 using System.Configuration;
14 <body> 03 using System.Linq;
15 <form id=form1 runat=server> 04 using System.Web.UI;
16 <asp:Label 05
17 runat=server 06 namespace BlogEngine.pages
18 ID=lblBlogTitle 07 {
19 Text=Nome do blog - /> 08 public partial class posts : System.Web.UI.Page
20 <asp:HyperLink 09 {
21 runat=server 10 protected void Page_Load(object sender, EventArgs e)
22 Text=Home 11 {
23 ID=hypHome /><br /> 12 if (Page.IsPostBack)
24 <h1><asp:Label 13 return;
25 runat=server 14
26 Text=TtulodoPost 15 if (Request.QueryString.Count == 0
27 ID=lblTitle /></h1> 16 || String.IsNullOrEmpty(Request.QueryString[id]))
28 <asp:Label 17 {
29 runat=server 18 Response.Redirect(../default.aspx);
30 ID=lblContent 19 return;
31 Text=Content /> 20 }
32 </form> 21
33 </body> 22 load();
34 </html> 23 }

Controle Propriedade Valor Comentrio


ID lblBlogTitle
Label runat server Este label vai ser usado para exibir o ttulo do blog.
Text Nome do blog
ID hypHome
runat server Controle responsvel por fornecer um link para retornar pgina inicial do blog. Este link tambm vai
HyperLink
Text Pgina inicial ser construdo dinamicamente.
CssClass aplus
ID lblTitle
Label para exibir o ttulo do post.
runat server
Label Note na propriedade CssClass que foram definidas duas classes. Mais frente vou explicar o porqu
Text Ttulo do Post
disto.
CssClass form TableHeader
ID lblContent
Label Text content Controle para exibio do texto do post.
runat server

Tabela 2. Propriedades dos controles da pgina posts.aspx

36 Easy .Net Magazine Edio 27


Observe que novamente o mtodo inicia-se verificando se no utilizar as folhas de estilo dever ser passado tambm o nome da
se trata de um post back. No bloco da linha 15 em diante verifi- pasta. Na janela do Visual Studio para adicionar folhas de estilo
cado se o nome da propriedade que armazena o id da pgina foi ao projeto ao clicar com o boto direito na janela Solution Explorer
passado corretamente. Se por algum motivo este no foi, o mtodo sobre a pasta css e escolher o comando Add > New item...
redireciona o usurio para a pgina principal do projeto. Mas voc pode melhorar suas habilidades em trabalhar com
Finalizando o event handler a linha 22 faz uma chamada ao m- cores nos seus projetos Web quer seja estudando design ou
todo Load(), descrito na Listagem 13. Este mtodo responsvel usando uma ferramenta on line para ajudar, como a da Figura 11
por carregar os dados e preencher os controles da pgina. que mostra o color wizard (assistente para cores) do site Colors
on the Web. Esta ferramenta permite que voc escolha uma cor
principal e a partir desta demonstra as principais combinaes
Listagem 13. Mtodo load
que podem ser feitas. um bom ponto de partida para comear a
01 private void load() criar combinaes de cores mais sbrias e com o tempo at mesmo
02 {
03 var postObj = loadPost(Request.QueryString[id]);
arriscar um pouco mais.
04
05 if (postObj == null)
06 { Listagem 14. Carga dos dados
07 Response.Redirect(../default.aspx);
08 return; 01 private BlogEngine.posts loadPost(String postId)
09 } 02 {
10 03 var model = new BlogEngineEntities(ConfigurationManager
11 lblBlogTitle.Text = postObj.blogs.name; 04 .ConnectionStrings[BlogEngineEntities].ToString());
12 hypHome.NavigateUrl = String.Format(blog.aspx?id={0}, postObj.blogs.id); 05 var id = Convert.ToInt32(postId);
13 lblTitle.Text = postObj.post_title; 06 var postObj = from p in model.posts
14 lblContent.Text = postObj.content; 07 where p.id == id
15 Page.Title = String.Format({0} - {1}, 08 select p;
16 postObj.blogs.name, postObj.post_title); 09
17 } 10 if (postObj != null &&
11 postObj.ToList().Count > 0)
12 return postObj.ToList()[0];
13 else
Na linha 03 temos a chamada ao mtodo loadPost() para a carga
14 return null;
dos dados, como podemos ver na Listagem 14. 15 }
Na linha 05 feito o teste verificando se foi retornado um objeto
referente ao post vlido, novamente, se algo deu errado e objeto
retornou nulo, o usurio direcionado para a pgina padro do
projeto.
Na linha 11 definido o nome do blog que obtido do objeto
que foi consultado no banco. Se voc lembrar da primeira parte
do artigo a classe posts e a blogs esto relacionadas. Assim, existe
uma instncia do blog na classe posts e uma lista de posts na classe
blog representando o relacionamento entre as duas.
Na linha 13 formatado o endereo do blog no controle hyper-
link, enquanto que da linha 14 em diante os controles so preen-
chidos conforme os dados que foram carregados.
Para carregar os dados temos os mesmos passos da carga da
pgina blogs.aspx. Assim, o mtodo inicia-se criando uma ins-
tncia do DataModel passando a string de conexo. Em seguida
usamos linq (linha 06), usando como filtro o id que foi enviado
Figura 11. Ferramenta de cores
como argumento para o mtodo.
Na linha 10 feito o teste se a lista retornada no nula e se
possui pelo menos um registro, caso positivo o objeto retornado, Para este projeto defini trs arquivos ou trs folhas de estilo
caso contrrio o mtodo retorna um valor nulo. separadas, cada uma com um objetivo distinto:
base folha de estilos para ser usada com todas as pginas do
Definindo a pgina de estilos projeto, incluindo logins e incluso de dados.
Chegamos finalmente ao ponto principal do artigo que a editor rene as classe para usar com controles de edio de
definio dos estilos. Para adicionar os arquivos com os estilos posts.
CSS criamos uma pasta chamada css com o objetivo de manter grid estilos para formatar as listas de dados nos controles
o projeto organizado. importante lembrar que no momento de GridView.

Edio 27 Easy .Net Magazine 37


Desenvolvendo um blog com ASP.NET Parte 2

Voc at pode optar por criar uma folha apenas para o projeto, no comeo, mas faa o bsico no incio e v aos poucos sofisticando.
mas, isto provavelmente vai dificultar a manuteno e em alguns A Listagem 15 mostra o contedo do arquivo base.css. A Tabela 3
casos, impossvel porque existiro situaes em que um estilo no contm os comentrios para cada elemento.
vai conseguir sobrepor a outro. Na Listagem 16 esto as classes da folha de estilo para a edio
O ponto importante as folhas de estilo que voc possa ter em do post. Novamente, para verificar o que cada classe faz, consulte
mente antes um padro para ser seguido em todo o projeto. difcil a Tabela 4.

Listagem 15. Folha de estilos base

01 body 62 background-color:#D2E9FF;
02 { 63 }
03 font-family:Verdana,Arial,Helvetica,sans-serif; 64 .command
04 font-size:12px; 65 {
05 margin-top:0; 66 border:2pxoutset#000099;
06 margin-bottom:0; 67 padding:8px;
07 margin-left:0; 68 font-family:Arial,Helvetica,sans-serif;
08 margin-right:0; 69 font-size:small;
09 width:100%; 70 color:#FFFFFF;
10 } 71 background-color:#0039FF;
11 h1 72 }
12 { 73 .command:hover
13 font-family:Verdana,Arial,Sans-Serif; 74 {
14 background-color:#003399; 75 border-color:#003300;
15 color:#FFFFFF; 76 background-color:#329900;
16 font-size:24pt; 77 }
17 width:100%; 78 .error
18 height:40px; 79 {
19 vertical-align:middle; 80 color:red;
20 margin-top:0; 81 }
21 margin-bottom:0; 82 a
22 margin-left:0; 83 {
23 margin-right:0; 84 color:#0039FF;
24 font-weight:normal; 85 text-decoration:none;
25 } 86 }
26 .title 87 a:hover
27 { 88 {
28 background-color:#003399; 89 background-color:#D2E9FF;
29 color:#FFFFFF; 90 }
30 margin-top:0; 91 .aplus
31 margin-bottom:0; 92 {
32 margin-left:0; 93 color:White;
33 margin-right:0; 94 background-color:transparent;
34 width:100%; 95 text-decoration:underline;
35 vertical-align:middle; 96 }
36 } 97 .aplus:hover
37 .form 98 {
38 { 99 text-decoration:underline;
39 margin-top:15px; 100 background-color:Blue;
40 margin-bottom:0; 101 }
41 margin-left:15px; 102 .TextArea
42 margin-right:0; 103 {
43 width:90%; 104 border-width:1px;
44 } 105 border-color:#4C4C4C;
45 .field 106 font-family:LucidaConsole,Monospace;
46 { 107 font-size:10pt;
47 border-style:nonenonesolidnone; 108 font-weight:bold;
48 border-width:1px; 109 margin:0000;
49 border-color:#4C4C4C; 110 overflow:auto;
50 font-family:LucidaConsole,Monospace; 111 }
51 font-size:10pt; 112 .TextArea:focus
52 height:20px; 113 {
53 font-weight:bold; 114 background-color:#D2E9FF;
54 margin:0000; 115 }
55 } 116 .content
56 .field:hover 117 {
57 { 118 font-family:SegoeUI,Arial,Sans-Serif;
58 background-color:#D2E9FF; 119 font-size:10pt;
59 } 120 margin-right:20px;
60 .field:focus 121 margin-left:20px;
61 { 122 }

38 Easy .Net Magazine Edio 27


Classe Definio
Corresponde a TAG <body> do HTML.
Numa folha de estilos quando voc define uma classe com o mesmo nome de um elemento HTML, as formataes ali definidas vo ser
Body
sobrescritas sem que seja necessrio fazer referncia.
Este estilo define a fonte e as margens do corpo da pgina. Note que todas as margens esto definidas com zero.
h1 Redefine a fonte, cor de fundo e tamanho da TAG <h1>.
Esta classe inicia o grupo de classes no relacionadas com elementos HTML.
Title
Define a formatao que vai ser usada para os ttulos das pginas.
Define padres para serem usados com a TAG <form>.
Form
Deste modo possvel configurar uma aparncia diferenciada para a seo da pgina que armazena os controles de servidor ASP.NET.
usado para configurar a aparncia dos controles de edio de dados como TextBox. Eu optei por deixar apenas a borda inferior para dar
Field
um efeito diferenciado que poder ser conferido frente.
Trata-se de uma forma de estender a classe field. Com a palavra hover precedida do sinal de dois pontos (:) toda vez que o mouse
field:hover passar sobre os controles usando este estilo, ser aplicada a formatao definida nesta classe.
Neste caso, apenas defini uma cor de fundo diferenciada.
Novamente estou estendendo a classe field. Atravs da palavra focus estou definindo um estilo para quando o controle com este estilo
field:focus
estiver com foco.
command uma classe para formatar os botes da aplicao.
command:hover Assim como a classe field, a classe command recebe uma formatao diferente para quando o mouse passar sobre o controle.
error Classe para formatar os controles de validao.
Redefine a tag <a> usada para os hiperlinks.
a, a:hover
O destaque que remove o sublinhado padro do hiperlink que s reativado ao passar o mouse sobre o mesmo (hover).
aplus, aplus:hover Cria uma outra categoria para ser usada com o controle ASP.NET hyperlink.
Formatao para controle de texto multinha.
TextArea, TextArea:focus
A propriedade overflow esconde a barra de rolagem at que o nmero de linhas seja igual ou maior ao definido nas propriedades do controle.
content Formatao do contedo dos posts.

Tabela 3. Definio das classes da folha de estilo base.css

Listagem 16. Folha de estilos para edio de texto


Classe Definio
Classe base para ser usada com os editores de texto. 01 .TextBoxBase
Esta classe vai ser usada em conjunto com outras para 02 {
TextBoxBase 03 border:none;
definir a aparncia dos controles TextBox na pgina de
04 overflow:auto;
posts. 05 font-family:Verdana,Arial,Sans-Serif;
Define o estilo para ser usado na mscara para o ttulo 06 width:100%;
TextBoxMaskTitle
do post. 07 }
Tambm define estilo para a mscara, desta vez, de 08 .TextBoxMaskTitle
TextBoxMaskSubtitle 09 {
subttulo.
10 color:#CCCCCC;
TextBoxMaskContent Novamente define estilo para a mscara do contedo. 11 font-size:18pt;
12 }
TextBoxTitle Estilo para o TextBox do ttulo.
13 .TextBoxMaskSubtitle
TextBoxSubtitle Estilo para o TextBox do subttulo. 14 {
15 color:#CCCCCC;
TextBoxContent Estilo para o TextBox de edio do texto do post. 16 font-size:12pt;
17 }
Tabela 4. Classes para edio do post 18 .TextBoxMaskContent
19 {
20 color:#CCCCCC;
Finalmente, na Listagem 17 esto definidas as formataes para 21 font-size:10pt;
o controle GridView que faz a listagem de dados. Alm dos estilos 22 }
23 .TextBoxTitle
da grid so definidos outros para tabelas, a Tabela 5 descreve
24 {
cada classe. 25 font-size:18pt;
26 }
Aplicando a formatao 27
28
.TextBoxSubtitle
{
Aplicar a formatao no trata apenas de vincular as folhas de 29 font-size:12pt;
estilo com os controles. Para termos um bom resultado alguns 30 }
31 .TextBoxContent
elementos precisaram ser modificados no cdigo HTML con- 32 {
forme ser explicado adiante. Nestas listagens onde estaremos 33 font-size:10pt;
34 }

Edio 27 Easy .Net Magazine 39


Desenvolvendo um blog com ASP.NET Parte 2

demonstrando a aplicao dos estilos, vamos suprimir o cdigo Classe Definio


da pgina que no alterado, substituindo o mesmo por ... Formatao bsica da grid.
GridBase
(reticncias), mantendo apenas os elementos necessrios para Vai ser usada em conjunto com outras classes.

o entendimento do cdigo, enquanto que os itens adicionados GridAlternate Formatao para linhas alternadas das linhas da grid.
ficaro destacados, de forma que a leitura no fique poluda. GridTitle Formatao para o ttulo da grid.
A primeira pgina que vai ser modificada a pgina de login. Sobrepe a TAG <table> definindo a formatao
Table
Sua aparncia final ser como exibido na Figura 12. Note que bsica deste elemento.
o campo da senha est recebendo o foco e com isso j teve sua Vai definir a formatao para coluna esquerda de uma
TableLeft
aparncia alterada. tabela.
TableRight Define formatao de coluna direita de uma tabela.

Listagem 17. Folha de estilos para grid TableHeader Formatao do cabealho de tabela.
TableBlogLeft e Formatao de coluna para a pgina dos posts do
01 .GridBase TableBlogRight blog.
02 {
03 font-family:SegoeUI,Arial,Sans-serif; Tabela 5. Folha de estilos de listagens
04 border:1pxsolid#CCCCCC;
05 }
06 .GridAlternate
07 { As principais mudanas do cdigo HTML esto em destaque
08 background-color:#DBE1F9; na Listagem 18 que mostra tambm as classes CSS que foram
09 }
10 .GridTitle
vinculadas com os controles e as mudanas no HTML.
11 { Na Listagem 18 gostaria de destacar na linha 3 o cdigo que
12 color:White; faz a ligao da folha de estilo CSS com a pgina. Ainda na
13 background-color:#003399;
14 } Listagem 18, na linha 6, podemos ver que inclumos uma tag
15 table{width:100%;} <div>, usada para criar a parte do cabealho da pgina, melho-
16 .TableLeft rando a aparncia da pgina.
17 {
18 width:50%;
19 vertical-align:text-top;
20 } Listagem 18. Marcao HTML para a pgina inicial
21 .TableRight
22 { 01 <headrunat=server>
23 vertical-align:text-top; 02
24 } 03 <linkhref=~/css/base.cssrel=stylesheettype=text/css/>
25 .TableHeader 04 </head>
26 { 05 <body>
27 font-size:18pt; 06 <divclass=title>
28 } 07 <h1>BlogEngine-GerenciadordeBlogs</h1>
29 .TableBlogLeft 08 <br/>
30 { 09 </div>
31 width:70%; 10 <formid=form1
32 vertical-align:text-top; 11
33 } 12 class=form>
34 .TableBlogRight 13 <asp:TextBox
35 { 14
36 vertical-align:text-top; 15 ID=txtEmail
37 } 16 CssClass=field
17 /><br/>
18 <asp:RequiredFieldValidator
19 20 ID=LoginRequiredFieldValidator
21 CssClass=error/><br/>
22 <asp:TextBox
23
24 ID=txtPass
25 CssClass=field/><br/>
26 <asp:RequiredFieldValidator
27 ID=PassRequiredFieldValidator
28
29 CssClass=error/><br/>
30 <asp:Button
31 ID=btnSend
32
33 CssClass=command />
34 </form>
35 </body>
Figura 12. Pgina inicial Layout Final

40 Easy .Net Magazine Edio 27


Como foi mencionado anteriormente, necessrio incluir o
nome da pasta onde o arquivo correspondente folha de estilos
est localizado no projeto.
A pgina seguinte a pgina para a criao de um blog novo.
Sua aparncia final pode ser conferida na Figura 13.
Note os estilos em ao principalmente aqueles vinculados com
os campos TextBox e para os validadores que agora aparecem na
cor vermelha para um destaque maior. A Listagem 19 demonstra
o cdigo HTML com a aplicao dos estilos para esta pgina.
Na Listagem 19 podemos destacar dois elementos, na linha 8
temos um HyperLink com a aplicao da classe aplus, onde
criamos um efeito para o link removendo o sublinhado at que
o usurio aponte o mouse para o mesmo e na linha 31 temos um
TextBox com uma classe diferenciada, por necessitar de vrias
linhas para seu contedo.
A prxima pgina que vamos ajustar a formatao referente
ao gerenciamento do blog, BlogStartPage.aspx e o resultado final
pode ser conferido na Figura 14.
Figura 13. Pgina de criao do blog

Listagem 19. Marcao HTML para a pgina

01 <head runat=server> 45 CssClass=error/>


02 46 <br />Endereodee-mail<br />
03 <link href=~/css/base.css rel=stylesheet type=text/css /> 47 <asp:TextBox
04 </head> 48
05 <body> 49 ID=txtMail
06 <div class=title> 50 CssClass=field /><br />
07 <h1>BlogEngine- Criarnovoblog</h1> 51 <asp:RequiredFieldValidator
08 <asp:HyperLink 52
09 53 ID=EmailRequiredFieldValidator
10 CssClass=aplus /> - Criarconta<br /><br /> 54 CssClass=error />
11 </div> 55 <asp:RegularExpressionValidator
12 <form 56
13 57 ID=EmailRegularExpressionValidator
14 id=form1 58 CssClass=error/>
15 class=form> 59 <asp:CustomValidator
16 <asp:TextBox 60
17 61 ID=CustomValidatorEmail
18 ID=txtName 62 CssClass=error />
19 CssClass=field /><br /> 63 <br />Senha<br />
20 <asp:RequiredFieldValidator 64 <asp:TextBox
21 65
22 ID=NameRequiredFieldValidator 66 ID=txtPass
23 CssClass=error/> 67 CssClass=field /><br />
24 <asp:CustomValidator 68 <asp:RequiredFieldValidator
25 69
26 ID=CustomValidatorName 70 ID=PassRequiredFieldValidator
27 CssClass=error/> 71 CssClass=error />
28 <br />Descriodocontedodoblog<br /> 72 <br />Confirmao da senha<br />
29 <asp:TextBox 73 <asp:TextBox
30 74
31 ID=txtDescription 75 ID=txtConfirm
32 CssClass=TextArea /><br /> 76 CssClass=field /><br />
33 <asp:RequiredFieldValidator 77 <asp:CompareValidator
34 78
35 ID=DescriptionRequiredFieldValidator 79 ID=PassCompareValidator
36 CssClass=error/> 80 CssClass=error />
37 <br />Nome do autor<br /> 81 <asp:Button
38 <asp:TextBox 82
39 83 ID=btnSend
40 ID=txtAuthor 84 CssClass=command />
41 CssClass=field/><br /> 85 </form>
42 <asp:RequiredFieldValidator 86 </body>
43 87 </html>
44 ID=AutorRequiredFieldValidator

Edio 27 Easy .Net Magazine 41


Desenvolvendo um blog com ASP.NET Parte 2

Na Listagem 20 est a marcao HTML completa para esta


pgina.
Nas linhas 3 e 4 podemos observar que esta pgina vai usar
duas folhas de estilo.
Nas linhas 21, 22, 25 e 79 temos elementos <td> com a aplica-
o de mais de uma classe CSS, separadas por um espao, isto
faz com que o browser aplique o estilo definido na primeira
classe e em seguida o da segunda. Neste caso no h proble-
mas porque os dois estilos so complementares, ou seja, so
definidas formataes diferentes. Caso haja formataes para
os mesmos elementos, prevalece a do ltimo estilo.
Na linha 89 temos a definio do estilo para as linhas da
grid, enquanto que na linha 90 temos a definio do estilo
para as linhas alternadas, fazendo com que a grid tenha uma
Figura 14. Pgina de gerenciamento do blog

Listagem 20. Marcao HTML da pgina de gerenciamento do blog

01 <head runat=server> 51 ID=txtAuthor


02 52 CssClass=field/><br />
03 <link href=~/css/base.css rel=stylesheet type=text/css /> 53 <asp:RequiredFieldValidator
04 <link href=~/css/grid.css rel=stylesheet type=text/css /> 54
05 </head> 55 ID=AutorRequiredFieldValidator
06 <body> 56 CssClass=error/>
07 <div class=title> 57 <br />Endereodee-mail<br />
08 ... 58 <asp:TextBox
09 <asp:HyperLink 59
10 60 ID=txtMail
11 ID=hypLogoff 61 CssClass=field/><br />
12 CssClass=aplus /> - Gerenciar<br /><br /> 62 <asp:RequiredFieldValidator
13 </div> 63
14 <form 64 ID=EmailRequiredFieldValidator
15 65 CssClass=error/><br />
16 id=form1 66 <asp:RegularExpressionValidator
17 class=form> 67
18 68 ID=EmailRegularExpressionValidator
19 <table> 69 CssClass=error />
20 <tr> 70 <asp:CustomValidator
21 <td class=TableLeftTableHeader>Dados do blog</td> 71 ...
22 <td class=TableRightTableHeader>Posts</td> 72 ID=CustomValidatorEmail
23 </tr> 73 CssClass=error />
24 <tr> 74 <asp:Button
25 <td class=TableBlogLeft> 75 ...
26 <br />Nome do Blog<br /> 76 ID=btnSend
27 <asp:TextBox 77 CssClass=command />
28 78 </td>
29 ID=txtName 79 <td class=TableBlogRight>
30 CssClass=field/><br /> 80 <asp:Button
31 <asp:RequiredFieldValidator 81
32 82 ID=btnNewPost
33 ID=NameRequiredFieldValidator 83 CssClass=command />
34 CssClass=error/> 84 <asp:GridView
35 <asp:CustomValidator 85
36 ID=CustomValidatorName 86 ID=grdPosts
37 ... 87 CssClass=GridBase
38 CssClass=error/> 88 >
39 <br />Descriodocontedodoblog<br /> 89 <RowStyle CssClass=GridBase />
40 <asp:TextBox 90 <AlternatingRowStyle CssClass=GridBaseGridAlternate />
41 91 <HeaderStyle CssClass=GridBaseGridTitle />
42 ID=txtDescription 92
43 CssClass=TextArea/><br /> 93 </asp:GridView>
44 <asp:RequiredFieldValidator 94 </td>
45 95 </tr>
46 ID=DescriptionRequiredFieldValidator 96 </table>
47 CssClass=error/> 97 </form>
48 <br />Nome do autor<br /> 98 </body>
49 <asp:TextBox 99 </html>
50

42 Easy .Net Magazine Edio 27


formatao zebrada, o que melhora a visualizao por parte Para comear a usar o AJAX Control Toolkit no projeto deve-se
usurio. adicionar a referncia para a DLL que foi baixada e descompactada.
A Figura 15 mostra a pgina para criao de um novo post. Nesta Para adicionar referncia ao projeto voc pode usar o menu Project
pgina, alm de aplicar as folhas de estilo, realizamos algumas > Add Reference e na aba Browse localizar a biblioteca desejada.
mudanas adicionais, para poder obter o estilo finalForam adicio- A Listagem 21 contm a marcao HTML completa da pgina
nados controles da biblioteca AJAX Control Toolkit para criar o e na sequncia uma explicao do que foi feito.
efeito de mscara para os campos TextBox. Dessa forma, enquanto O primeiro elemento que deve ser colocado na pgina ASP.NET
o controle estiver vazio ser exibido um texto que serve como label o gerenciador de scripts. Como os controles AJAX vo depender
para o mesmo e como dica de preenchimento. da gerao de scripts este o responsvel por fazer esta tarefa.

Listagem 21. Marcao HTML para pgina de incluso de post

01 <head runat=server> 59 Display=Dynamic


02 <title>BlogEngine- Novapublicao</title> 60 ControlToValidate=txtTitle /><br /><br />
03 <script type=text/javascript src=scripts.js></script> 61 <asp:TextBoxWatermarkExtender
04 <link href=~/css/base.css rel=stylesheet type=text/css /> 62 ID=TextBoxWatermarkExtender2
05 <link href=~/css/editor.css rel=stylesheet type=text/css /> 63 runat=server
06 </head> 64 WatermarkText=Informeosubttulo
07 <body> 65 WatermarkCssClass=TextBoxBaseTextBoxMaskSubtitle
08 <div class=title> 66 TargetControlID=txtSubtitle />
09 <h1>BlogEngine- Criarnovapublicao</h1> 67 <asp:TextBox
10 <table style=width:100%; border: 0 0 0 0; 68 runat=server
11 cellpadding=0 69 ID=txtSubtitle
12 cellspacing=0 70 CssClass=TextBoxBaseTextBoxSubtitle
13 class=title> 71 MaxLength=100 /><br /><br />
14 <tr> 72 <asp:TextBoxWatermarkExtender
15 <td> 73 ID=TextBoxWatermarkExtender3
16 <asp:HyperLink 74 runat=server
17 ID=hypManage 75 WatermarkCssClass=TextBoxBaseTextBoxMaskContent
18 runat=server 76 WatermarkText=Informeaspalavras-
19 Text=GerenciaroBlog chaveseparadasporespao
20 NavigateUrl=~/BlogStartPage.aspx 77 TargetControlID=txtKeywords />
21 CssClass=aplus /> - 78 <asp:TextBox
22 Criar nova publicao 79 runat=server
23 </td> 80 ID=txtKeywords
24 <td align=right> 81 Rows=3
25 <asp:HyperLink 82 CssClass=TextBoxBaseTextBoxContent
26 ID=hypSair 83 TextMode=MultiLine
27 runat=server 84 MaxLength=1000 /><br /><br />
28 Text=Sair 85 <asp:TextBoxWatermarkExtender
29 NavigateUrl=~/default.aspx 86 ID=TextBoxWatermarkExtender4
30 CssClass=aplus /> 87 runat=server
31 </td> 88 WatermarkCssClass=TextBoxBaseTextBoxMaskContent
32 </tr> 89 WatermarkText=Contedodapublicao
33 </table> 90 TargetControlID=txtContent />
34 <br /> 100 <asp:TextBox
35 </div> 101 runat=server
36 <form id=form1 102 ID=txtContent
37 class=form 103 TextMode=MultiLine
38 runat=server> 104 Rows=15
39 Useestapginaparaenviarumanovapublicao.<br /><br /> 105 CssClass=TextBoxBaseTextBoxContent
40 <asp:ToolkitScriptManager 106 MaxLength=5000 /><br /><br />
41 runat=server 107 <asp:RequiredFieldValidator
42 ID=scriptManager1 /> 108 runat=server
43 <asp:TextBoxWatermarkExtender 109 ID=ContentRequiredFieldValidator
44 ID=TextBoxWatermarkExtender1 110 ErrorMessage=
45 runat=server necessrioinformarumcontedoparaopost.
46 WatermarkCssClass=TextBoxBaseTextBoxMaskTitle 111 Display=Dynamic
47 WatermarkText=Entrecomumttuloaqui 112 CssClass=error
48 TargetControlID=txtTitle /> 113 ControlToValidate=txtContent /><br />
49 <asp:TextBox 114 <asp:Button
50 runat=server 115 runat=server
51 ID=txtTitle 116 ID=btnSend
52 CssClass=TextBoxBaseTextBoxTitle 117 OnClientClick=confirmacao
53 MaxLength=100 /><br /> (Confirmaoenviodestepost?);
54 <asp:RequiredFieldValidator 118 Text=Enviar
55 runat=server 119 CssClass=command
56 ID=TitleRequiredFieldValidator 120 onclick=btnSend_Click />
57 ErrorMessage=necessrioinformarumttuloparaopost. 121 </form>
58 CssClass=error 122 </body>

Edio 27 Easy .Net Magazine 43


Desenvolvendo um blog com ASP.NET Parte 2

Na pgina para edio do post foi colocado um ToolkitScript- seja, se estiver usando o designer do Visual Studio em vez da
Manager (linha 40) logo aps a marcao Form. marcao HTML para editar a pgina este elemento vai ficar com
Este elemento no precisa ter nenhuma propriedade ajustada, a aparncia da Figura 16. O controle para a mscara dos campos
sendo assim, basta arrast-lo para a pgina ou definir sua mar- TextBox tambm no possui visualizao em tempo de design.
cao HTML. Lembrando que este um controle no visual, ou O controle que vai gerar a mscara para o controle TextBox o Text-
BoxWatermarkExtender. Inserimos ele nas linhas 43, 61, 72 e 85.
Alm do ID, as propriedades mais importantes deste con-
trole so:
WatermarkCssClass vincula o controle com uma classe CSS.
Pode ou no estar presente.
WatermarkText propriedade para configurar o texto que vai
ser usado como mscara para o controle.
TargetControlID ID do controle que est vinculado com o
componente.

Como voc informa o controle vinculado com o componente


(TargetControlID), possvel agrupar estes controles em uma de-
terminada seo da pgina, mas optei por coloc-los sempre acima
do controle TextBox correspondente para facilitar a compreenso.
A seguir a Tabela 6 detalha as classes CSS que foram usadas.
Figura 15. Pgina para incluir novo post preenchida Continuando com a formatao na Figura 17 temos a pgina
principal exibida para os usurios do blog.
Mais uma vez, a marcao HTML usada est na Listagem 22.
Na linha 9 inclumos uma div com a class title para formar o
cabealho da pgina, na linha 15 temos um table com a classe
form, que a table para organizar o layout da pgina dividido em
duas colunas. Na primeira coluna (linha 19), temos uma coluna
da table usando a classe TableBlogLeft, j na linha 35 temos uma
div para agrupar os posts recentes, com a classe TableHeader
e na linha 49 temos a coluna da direita da pgina com a classe
Figura 16. Visualizando o ToolkitScriptManager TableBlogRight;

Elemento Classe Comentrios


Tabela usada para formatar o cabealho da pgina.
Table Title
Permite aninhar os links para navegao direita.

HyperLink (ID=hypManage) Aplus

HyperLink (ID=hypSair) Aplus


<form> Form
TextBoxWatermarkExtender (ID=TextBoxWatermarkExtender1) TextBoxBase e TextBoxMaskTitle Mscara vinculada com o ttulo do post.
TextBox ID=txtTitle TextBoxBase e TextBoxTitle
RequiredFieldValidator (ID=TitleRequiredFieldValidator) Error
TextBoxWatermarkExtender (ID=TextBoxWatermarkExtender2) TextBoxBase e TextBoxMaskSubtitle Mscara vinculada com o subttulo do post.
TextBox (ID=txtSubtitle) TextBoxBase TextBoxSubtitle
TextBoxWatermarkExtender (ID=TextBoxWatermarkExtender3) TextBoxBase e TextBoxMaskContent Mscara vinculada com as palavras chave do post.
TextBox (ID=txtKeywords) TextBoxBase e TextBoxContent
TextBoxWatermarkExtender (ID=TextBoxWatermarkExtender4) TextBoxBase e TextBoxMaskContent Mscara vinculada com o contedo (texto) do post.
TextBox (ID=txtContent) TextBoxBase e TextBoxContent
RequiredFieldValidator
error
(ID=ContentRequiredFieldValidator)
Button (ID=btnSend) command

Tabela 6. Detalhamento dos elementos da pgina NewPost.aspx

44 Easy .Net Magazine Edio 27


Listagem 22. Marcao HTML da pgina inicial com estilos

01 <headrunat=server> 30 <br/>
02 ... 31 <asp:label
03 <linkhref=~/css/grid.cssrel=stylesheettype=text/css/> 32 runat=server
04 <linkhref=~/css/base.cssrel=stylesheettype=text/css/> 33 ID=lblPostText/>
05 </head> 34 <br/><br/>
06 <body> 35 <divclass=TableHeader>PostsRecentes</div>
07 <formid=form1 36 <asp:GridView
08 runat=server> 37 runat=server
09 <divclass=title> 38 ID=grdPosts
10 <h1><asp:Label 39 CssClass=GridBase
11 ... 40 AutoGenerateColumns=false>
12 ID=lblTitle/></h1> 41 <HeaderStyleCssClass=GridBaseGridTitle/>
13 <br/> 42 <RowStyleCssClass=GridBase/>
14 </div> 43 <AlternatingRowStyleCssClass=GridBaseGridAlternate/>
15 <tablestyle=width:100% 44 <Columns>
16 45
17 class=form> 46 </Columns>
18 <tr> 47 </asp:GridView>
19 <tdclass=TableBlogLeft> 48 </td>
20 <asp:Label 49 <tdclass=TableBlogRight>
21 50 <divclass=TableHeader>DetalhesdoBlog</div>
22 CssClass=TableHeader 51
23 ID=lblDescription/> 52 </td>
24 <br/> 53 </tr>
25 <h3> 54 </table>
26 <asp:HyperLink 55 </form>
27 56 </body>
28 ID=hypLastPostTitle 57 </html>
29 CssClass=TableHeader/></h3>

Finalizando o projeto, temos na Figura 18 o design final da Listagem 23. Marcao HTML da visualizao de post
pgina que exibe o post.
Na Listagem 23 voc pode conferir como ficou a marcao <headrunat=server>
<linkhref=~/css/base.cssrel=stylesheettype=text/css/>
HTML para a pgina com destaque para os elementos CSS. <linkhref=~/css/grid.cssrel=stylesheettype=text/css/>
</head>
<body>
<formid=form1
runat=server>
<divclass=title>
<h1>
<asp:Label
runat=server
ID=lblBlogTitle
Text=Nomedoblog/></h1>
<br/>
<asp:HyperLink
runat=server
Text=Pginainicial
CssClass=aplus
ID=hypHome/><br/><br/>
</div>
<br/>
<asp:Label
Figura 17. Viso da pgina inicial do blo runat=server
Text=TtulodoPost
CssClass=formTableHeader
ID=lblTitle/><br/><br/>
<divclass=form>
<asp:Label
runat=server
ID=lblContent
Text=content/></div>
</form>
</body>
</html>
Figura 18. Visualizao de post

Edio 27 Easy .Net Magazine 45


Desenvolvendo um blog com ASP.NET Parte 2

Concluso Tutorial de CSS do W3Schools


Este artigo mostrou algumas tarefas para melhorar a aparncia http://www.w3schools.com/css/default.asp
do blog. Atravs do uso das folhas de estilo CSS, controles da
biblioteca AJAX Control Toolkit e um pouco de pacincia (muita,
Simple talk: back to basics
na verdade...) se tem um resultado satisfatrio e que torna a uti-
http://www.simple-talk.com/dotnet/asp.net/back-to-basics-structuring-a-web-
lizao da pgina mais atraente.
page-with-css-and-asp.net/
Algo que pode ser feito ainda na linha de melhorias de aparncia TextBoxWatermark Control
do blog explorar mais as capacidades das folhas de estilo CSS. http://www.asp.net/ajaxlibrary/AjaxControlToolkitSampleSite/
possvel refinar a ponto de criar CSS dinmico tambm, ou seja, TextBoxWatermark/TextBoxWatermark.aspx
aplicar o estilo dependendo do contedo que o controle vai rece-
Ajax Control Toolkit
ber, alm de utilizar os estilos em conjunto de maneira a reduzir
http://ajaxcontroltoolkit.codeplex.com/
o nmero de classes que voc vai ter de definir.
Em relao ao desempenho e ao Entity Framework destaco aqui Ajax Control Toolkit documentation
a necessidade de trazer apenas os dados necessrios. No exemplo http://www.asp.net/ajaxlibrary/act.ashx
estou filtrando para carregar os cinco ltimos posts depois de ter
Adding AJAX and Client Capabilities
feito a consulta no banco. Isto funciona muito bem num exemplo
http://msdn.microsoft.com/library/bb398822.aspx
como este onde existem poucos registros. Entretanto, em uma
aplicao real dever ser evitado este tipo de procedimento para Microsoft Ajax Overview
no haver sobrecarga no servidor. bom lembrar que uma apli- http://msdn.microsoft.com/pt-br/library/bb398874.aspx
cao ASP.NET normalmente possui vrios usurios a utilizando Generating Keys for Encryption and Decryption
ao mesmo tempo. http://msdn.microsoft.com/en-us/library/5e9ft273(v=vs.100).aspx

Vladimir Rech How to generate key pairs, encrypt and decrypt data with .NET (C#)
vladimirrech@yahoo.com.br http://vladimirrech.blogspot.com - http://blogs.msdn.com/b/alejacma/archive/2008/10/23/how-to-generate-key-
@vladimirrech pairs-encrypt-and-decrypt-data-with-net-c.aspx
Tecnlogo em Desenvolvimento de Sistemas pelo CEFET/UTF-PR,
Encrypt and Decrypt Data with C#
trabalha com desenvolvimento de sistemas em .NET destacando-se apli-
caes Windows, ASP.NET e Webservices. Mantm um blog onde escreve http://www.codeproject.com/Articles/14150/Encrypt-and-Decrypt-Data-with-C
sobre diversos assuntos relacionados a programao e ao Framework .NET. Encrypt/Decrypt String using DES in C#
http://www.codeproject.com/Articles/19538/Encrypt-Decrypt-String-using-DES-in-C
Color Wizard
http://www.colorsontheweb.com/colorwizard.asp
ASP.NET Params Collection vs. QueryString, Forms vs. Request[index]
and Double Decoding
http://www.hanselman.com/blog/
ASPNETParamsCollectionVsQueryStringFormsVsRequestindexAndDoubleDecoding.aspx
Utilizando CSS no Asp.Net
http://www.devmedia.com.br/utilizando-css-no-asp-net/5113
JavaScript e CSS
http://www.devmedia.com.br/artigo-net-magazine-66-javascript-e-css/14417
Utilizando CSS no Asp.Net
http://www.devmedia.com.br/utilizando-css-no-asp-net/5113
Envie dados via QueryString com mais segurana
http://www.devmedia.com.br/envie-dados-via-querystring-com-mais-
seguranca/4559

46 Easy .Net Magazine Edio 27


Edio 27 Easy .Net Magazine 47