You are on page 1of 68

Sumrio

A .NET Magazine tem que ser feita ao seu gosto.


Para isso, precisamos saber o que voc, leitor, acha
da revista!
D seu voto sobre esta edio, artigo por artigo,
atravs do link:
www.devmedia.com.br/netmagazine/feedback
D


s
e
u

F
e
edb
a
c
k
s
o
b
r
e

e
s
t
a

e
d
i o
D seu feedback sobre esta edio!
Artigo no estilo Soluo Completa
58 Criando uma aplicao para conexes remotas
[ Mauro Pichiliani ]
Contedo sobre Boas Prticas
24 Data Binding em WPF: Interagindo com o BD
[ Henrique Machado Gasparotto ]
Contedo sobre Novidades
04 Notificaes Push no Windows Phone 8
[ Felipe Farias Ferrari ]
Artigo no estilo Curso
36 Integration Services2012: implementando solues de ETL - Parte 1
[ Renato Jos Groffe ]
muito importante para a equipe saber o que voc est
achando da revista: que tipo de artigo voc gostaria de
ler, que artigo voc mais gostou e qual artigo voc menos
gostou. Fique a vontade para entrar em contato com os
editores e dar a sua sugesto!
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:
Joel Rodrigues - Editor da Revista
joelrlneto@gmail.com
Fale com o Editor!

Ano 10 - 110 Edio 2013 - ISSN 1980-3931 - Impresso no Brasil
Corpo Editorial
Atendimento ao Leitor
A DevMedia conta com um departamento exclusivo para
o atendimento ao leitor. Se voc tiver algum problema
no recebimento do seu exemplar ou precisar de algum
esclarecimento sobre assinaturas, exemplares anteriores,
endereo de bancas de jornal, entre outros, entre em
contato com:
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
especficas de marketing com a DevMedia, entre em
contato com:
Cristiany Queiroz
publicidade@devmedia.com.br
Assine agora e tenha acesso a
todo o contedo da DevMedia:
www.devmedia.com.br/mvp
Editor Geral
Joel Rodrigues (joelrlneto@gmail.com)
Jornalista Responsvel
Kaline Dolabella - JP24185
Capa e Diagramao
Romulo Araujo
Na Web
ww.devmedia.com.br/dotnet
Distribuio
FC Comercial e Distribuidora S.A
Rua Teodoro da Silva, 907 | Graja - RJ - 206563-900
Joel Rodrigues
Editor Chefe da .net
Magazine e Easy .net
Magazine
Notificaes Push no Windows Phone 8
4 .Net Magazine Edio 110
Porque esse artigo til::
Este artigo ser til para os desenvolvedores que desejam utilizar
novas formas de comunicao e interao com suas Apps por parte
dos usurios, por exemplo, notificar sobre novas notcias, exibir
novas imagens nos Tiles, a partir de um mecanismo que funciona
mesmo com a App fechada, e que consome pouco recurso do tele-
fone, como bateria.
Resumo DevMan
Notificaes Push no
Windows Phone 8
Enviando e recebendo notificaes a partir de um
servio externo
N
o Windows Phone, com o nmero crescente
de Apps, temos que sempre estar dispostos
a nos diferenciar dos concorrentes, com isso,
um dos diferenciais pode ser notificar o usurio sobre
algum evento importante em tempo real, ou mesmo de
tempos em tempos dependendo do propsito da App.
Alm disso, podemos utilizar as notificaes Push no
apenas como diferencial, mas tambm como core da
App, por exemplo, em jogos por turno.
Desse modo, esse artigo se prope a abordar como
podemos trabalhar com notificaes Push no Windows
Phone 8.
Push Notifications
Podemos descrever as notificaes Push como men-
sagens que contm informaes e podem ser recebidas
pelas Apps, mesmo quando esta no se encontra em
execuo, dependendo do tipo de notificao enviada.
O servio Microsft Push Notification para o Windows
Phone oferece aos desenvolvedores um canal para envio
de dados a uma App do Windows Phone, de forma as-
sncrona, a partir de um servio web ou na nuvem que
resulte em baixo consumo de energia pelo telefone.
Conforme a Figura 1, podemos entender como funcio-
na o servio.
1. A App solicita ao cliente Push do telefone uma URI
para notificao.
2. O cliente Push negocia com o Microsoft Push Notifica-
tion Service (MPNS), e o MPNS retorna uma URI nica
de notificao ao cliente Push do telefone.
3. O cliente Push retorna a URI de notificao para a
App.
4. A App pode enviar a URI recebida a um servio web
ou na nuvem para que esse servio web possa enviar
mensagens App quando necessrio.
5. Quando o servio web tem alguma mensagem para
ser enviada App, este ir enviar uma requisio
utilizando a URI de notificao recebida anteriormente para
o MPNS.
6. O MPNS encaminha a notificao Push para o telefone.
Nesse processo de envio, o MPNS responder com um cdigo
de resposta ao solicitante do Push, indicando se o mesmo foi
encaminhado ou ser encaminhado na prxima possibilidade
ao telefone. Tambm, o MPNS pode retornar indicando que o
Push no ser entregue e com isso, dependendo da situao,
o Push pode ser reenviado ou no. Apesar disso, o MPNS no
oferece uma confirmao de ponta a ponta de que o Push foi
realmente entregue.
Figura 1. Diagrama sobre como funciona o envio das notificaes. Fonte: MSDN
Notificaes Push no Windows Phone 8
Edio 110 .Net Magazine 5
Para o uso desse servio a Microsoft exige e/ou recomenda que
algumas aes sejam tratadas, ou implementadas para garantir
melhor o funcionamento do sistema, tais como:
Para o uso do Push o desenvolvedor deve incluir no seu arquivo
WMAppManifest.xml a indicao do uso do Push atravs da ca-
pability ID_CAP_PUSH_NOTIFICATION, conforme Figura 2.
Figura 2. Demonstrao da funcionalidade que deve ser adicionada no arquivo de Manifesto
Como parte da poltica de certificao da App, a mesma deve
descrever ao usurio qual ser a finalidade para a qual o Push
ser usado, e que o mesmo deve confirmar o uso. Tambm, a
App deve oferecer um meio para que o usurio possa cancelar o
recebimento das notificaes push;
A App sempre deve verificar se um canal de push j existe antes
de tentar abri-lo, para evitar que o mesmo gere uma exceo du-
rante a execuo. O canal, por sua vez, persiste mesmo que a App
seja atualizada, contudo, isso exige que o mesmo esteja atrelado
a uma notificao do tipo Tile ou Toast;
A App deve registrar-se no evento ChannelUriUpdated no caso
de uma mudana da Uri de notificao, mesmo que o canal j
esteja aberto. A URI expira de tempos em tempos, necessitando
que a App solicite uma nova URI;
A App deve registrar-se no evento ErrorOccurred para tratar
qualquer erro. Alguns dos possveis erros esto na Tabela 1;
Sempre que a App for aberta, ela deve enviar a URI ao servidor
web para que este tenha a URI sempre atualizada. Tambm re-
comendado que a App envie um identificador nico do telefone
para que seja possvel rastrear uma mudana de URI por parte
do servidor web. Como exemplo para obter um identificador de
cada telefone, na Listagem 1 temos o exemplo de uma soluo para
Windows Phone 7.1, j na Listagem 2, para uma soluo Windows
Phone 8. Em uma soluo Windows Phone 8, o identificador ser
nico por telefone e publicador, sendo assim, caso em outra App
de outro publicador tenha esse mesmo trecho de cdigo para re-
cuperar o identificador do telefone, o identificador retornado ser
diferente entre uma App e outra. Contudo, para que seja possvel
obter esse identificador necessrio adicionar ao arquivo de Ma-
nifesto a identificao ID_CAP_IDENTITY_DEVICE;
A quantidade de aplicativos com notificaes Push por aparelho
limitada em 15 no Windows Phone 7 pr Mango (7.5), 30 para Win-
dows Phone 7.5 e ilimitada para Windows Phone 8. Caso o limite
seja atingido, ao abrir o canal com cliente MPNS ser lanada uma
exceo e no ser possvel habilitar a notificao para o aparelho
at que o usurio remova as notificaes de outra App.
Erro Descrio
PushErrorTypeChannelOpenFailed O canal no existe, portanto no pode ser aberto. A App deve tentar abrir novamente.
PushErrorTypeMessageBadContent
Para uma mensagem do tipo Tile, a mesma no se enquadrou nas condies:
1) A URL no http://,
2) O nome do servidor excedeu 256 caracteres,
3) A URL excedeu 2055 caracteres,
4) O domnio no foi especificado dentro dos domnios permitidos.
Para uma mensagem do tipo Toast, o valor da tag Param excedeu o limite de 256 caracteres.
PushErrorTypeNotificationRateTooHigh A taxa de notificaes recebidas est muito alta. Diminuir a taxa de notificaes recebidas para evitar mensagens descartadas.
PushErrorTypePayloadFormatInvalid
O XML da mensagem est mal formatado ou com erros, ou o tipo de notificao no foi definido no cabealho da requisi-
o, ou no se enquadra no tipo da requisio efetuada, com isso, o canal ser fechado. Portanto, devemos verificar o XML
da requisio e reabrir o canal para obter uma nova URI de notificao.
PushErrorTypeUnknown Ocorreu um erro interno. O telefone talvez necessite ser reiniciado.
Tabela 1. Possveis erros que podem ser retornados no evento ErrorOccurred
Listagem 1. Propriedade para recuperar o identificador nico em uma soluo
Windows Phone 7.1
01 private string m_DeviceUniqueId;
02 public string DeviceId
03 {
04 get
05 {
06 if (m_DeviceUniqueId == null)
07 {
08 object val;
09 if (Microsoft.Phone.Info.DeviceExtendedProperties.TryGetValue
(DeviceUniqueId, out val))
10 m_DeviceUniqueId = Convert.ToBase64String((val as byte[]));
11 }
12 return m_DeviceUniqueId;
13 }
14 }
Listagem 2. Propriedade para recuperar o identificador nico em uma soluo
Windows Phone 8
01 private string m_DeviceUniqueId;
02 public string DeviceId
03 {
04 get
05 {
06 if (m_DeviceUniqueId == null)
07 {
08 m_DeviceUniqueId =
Windows.Phone.System.Analytics.HostInformation.PublisherHostId;
09 }
10 return m_DeviceUniqueId;
11 }
12 }
Notificaes Push no Windows Phone 8 Notificaes Push no Windows Phone 8
6 .Net Magazine Edio 110
A App deve se autenticar ao servio web;
A App deve criptografar a sua URI de notificao antes de
enviar ao servio web;
Se o usurio desligar o recebimento das notificaes dentro da
App, esta deve fechar o canal atravs do mtodo Close;
O envio das notificaes Push pode ser feito de modo autentica Push pode ser feito de modo autentica-
do ou no. No modo no autenticado, o nmero e frequncia das
notificaes enviadas ao MPNS so controlados, no caso, o limite
atual de 500 por canal (telefone), por dia. Para utilizar o modo
autenticado, o qual no apresenta restries, o desenvolvedor
primeiro precisa registrar um certificado com o servio de no-
tificaes Push atravs da loja do Windows Phone. O certificado
precisa ser expedido por uma unidade certificadora confivel
por parte da Microsoft, e ento esse certificado usado para
estabelecer uma conexo segura atravs de SSL entre o servio
web e o servio de notificaes push.
Aps a explicao sobre o que e como funciona o envio de
notificaes push, iremos falar dos trs tipos de notificaes, que
so Tile, Toast e Raw.
Tile Notification
Como o prprio nome diz, a notificao para Tile deve ser uti-
lizada para atualizar o contedo de um Tile, seja ele o principal
ou no. Caso seja o principal, no existe a possibilidade de trocar
seu template para o outro sem submeter outra verso da App, j
para o secundrio possvel cri-lo e alter-lo em tempo de exe-
cuo. Esse tipo de notificao funciona mesmo quando a App
no est aberta.
O Windows Phone 7.8 (atravs de reflection, documentao dis-
ponibilizada na seo Links) e Windows Phone 8 suportam trs
tipos de templates para Tiles: Flip, Iconic e Cycle. A escolha do
template ir depender da finalidade da App, j que cada um tem
uma caracterstica prpria. Os Tiles tm os tamanhos descritos
na Tabela 2. No caso de telas WVGA, para os tamanhos 720p e
1080p (a partir do Update 3 do Windows Phone 8) as imagens so
automaticamente ajustadas.
O padro Cycle exibe uma serie de at nove imagens em sequ-
ncia, conforme Figura 5. O uso desse template recomendado
para exibio de imagens.
Toast Notification
A notificao por Toast exibe uma mensagem por cerca de dez
segundos. Se o usurio clicar sobre o Toast, a App ser aberta na
pgina inicial ou, caso seja definido no parmetro Param do
Toast, a pgina especificada.
Em telefones com Windows Phone 8 sem o Update 3, as notifi-
caes Toast no so exibidas se a App estiver em execuo em
primeiro plano, j nos aparelhos com essa atualizao os Toasts
so exibidos, mas ficam obscuros por outra atividade como uma
chamada telefnica ou a tela de bloqueio. Outra funcionalidade
que tambm ser possvel com a atualizao customizar o som
da notificao quando o Toast for exibido.
Em um Toast, exibida uma verso miniatuarizada do cone da
App, um ttulo e uma mensagem, conforme Figura 6. No caso do
ttulo e da mensagem, ambos so truncados, caso o tamanho do
texto seja maior que o espao disponvel para exibio.
Raw Notification
Esse tipo de notificao no oferece nenhuma interao direta
com o usurio, ele utilizado principalmente para recebimento
Flip e Cycle Iconic
Pequeno 159 159 pixels 110 110 pixels
Mdio 336 336 pixels 202 202 pixels
Largo 691 336 pixels N/A
Tabela 2. Tamanho dos Tiles para telas no tamanho WXGA
Figura 4. Imagem demonstrando o funcionamento para um Tile no padro Iconic - Fonte: MSDN
Figura 3. Imagem demonstrando o funcionamento para um Tile no padro Flip para
Windows Phone 7.8 e 8 - Fonte: MSDN
O Flip template nico tipo de notificao para Tiles anterior
ao Windows Phone 7.8, que prov duas superfcies no tamanho
mdio e largo, na qual possvel inserir uma quantidade de texto
considervel, conforme Figura 3.
O padro Iconic exibe uma imagem no centro do Tile, juntamente
com um nmero, que opcional, conforme Figura 4. Esse tipo de
padro recomendado se deseja exibir um contador.
Notificaes Push no Windows Phone 8 Notificaes Push no Windows Phone 8
Edio 110 .Net Magazine 7
Figura 5. Imagem demonstrando o funcionamento para um Tile no padro Cycle - Fonte: MSDN
Figura 6. Imagem demonstrando como a notificao Toast exibida - Fonte: MSDN
de dados quando a App est aberta, j que quando encerrada, o
canal de comunicao com cliente Push finalizado. A utilizao
de uma notificao Push, ao invs fazer a App consumir servios
ou APIs, faz com que o uso de recursos do telefone, principalmente
a bateria, seja minimizado. Adiante no artigo veremos na prtica
como o esse tipo de notificao bastante til.
O projeto
A fim de exemplificar como funcionam os tipos de notificao
j explicados, criaremos um projeto Web que far as requisies
ao MPNS enviando um XML de acordo com o template de cada
tipo de notificao especificado pela Microsoft. Nesse caso, o
projeto tem o objetivo de mostrar como funciona a comunicao
entre o servidor Web e o MPNS, e entre o Windows Phone e o
cliente Push. Portanto, em um ambiente real teramos outra co-
municao, entre o servidor Web e Windows Phone, para que os
telefones pudessem enviar os canais de Push ao servidor atravs
de um servio ou API.
Windows Phone 8
Para os projetos, estaremos utilizando o Visual Studio 2012.
Dessa forma, abriremos esse IDE em modo administrador e cria-
remos o primeiro projeto, Windows Phone 8.
Aproveitando a prpria pgina MainPage.xaml que criada
por padro na soluo, alteraremos o grid LayoutRoot conforme
a Listagem 3. No caso, criaremos um elemento do tipo LongList-
Selector, que ir listar os lances do jogo de futebol e um TextBlock
que dever informar quais so os times que esto se enfrentando.
Tambm ser necessrio adicionar algumas imagens que sero
utilizadas no Tile do tipo Cycle, o qual no permite o uso de
imagens externas ao telefone, conforme a Figura 7.
Aps definido o layout da tela e seus elementos, implemen-
taremos a lgica para abertura do canal de comunicao das
notificaes push e o mecanismo de exibio das informaes
recebidas nas notificaes para a tela do usurio, como tambm
as configuraes dos Tiles. Para isso, criaremos uma varivel na
Listagem 3. Contedo do grid que mostrar as informaes ao usurio
01 <!--LayoutRoot is the root grid where all page content is placed-->
02 <Grid x:Name=LayoutRoot Background=Transparent>
03 <Grid.RowDefinitions>
04 <RowDefinition Height=Auto/>
05 <RowDefinition Height=*/>
06 </Grid.RowDefinitions>
07
08 <!--TitlePanel contains the name of the application and page title-->
09 <StackPanel x:Name=TitlePanel Grid.Row=0 Margin=12,17,0,28>
10 <TextBlock Text=EXEMPLO PUSH
11 Style={StaticResource PhoneTextNormalStyle} Margin=12,0/>
12 <TextBlock Text={Binding TituloJogo} Margin=9,-7,0,0
13 Style={StaticResource PhoneTextTitle1Style}/>
14 </StackPanel>
15
16 <!--ContentPanel - place additional content here-->
17 <Grid x:Name=ContentPanel Grid.Row=1 Margin=12,0,12,0>
18 <ScrollViewer>
19 <StackPanel Orientation=Vertical>
20 <TextBlock Text=Informaes do jogo Margin=0,0,0,10
21 Style={StaticResource PhoneTextSubtleStyle}/>
22 <phone:LongListSelector Grid.Row=1
23 ItemsSource={Binding InformacoesJogo} LayoutMode=List/>
24 </StackPanel>
25 </ScrollViewer>
26 </Grid>
27 </Grid>
Notificaes Push no Windows Phone 8 Notificaes Push no Windows Phone 8
8 .Net Magazine Edio 110
classe que conter no nome do canal a ser utilizado pela App,
a do endereo da URI do nosso projeto Web que criaremos em
seguida e um objeto do tipo HttpNotificationChannel, que con-
centrar todas as informaes das notificaes do App, conforme
a Listagem 4.
Depois disso, adicionamos os bindings das propriedades Infor-
macoesJogo e TituloJogo, que atualizaro os elementos da pgina
da App, conforme a Listagem 5.
Pelo fato da App ser um exemplo para todos os tipos de notifica-
o hoje existentes, ao abrir a App pela primeira vez esta ir criar
trs Tiles secundrios, um de cada tipo, que sero atualizados
pelas notificaes. Para isso, adicionamos no evento de abertura
da pgina, OnNavigatedTo, a criao de todos eles. Tambm nesse
evento onde atualizamos os times que esto se enfrentando.
Quando esses times forem enviados por um parmetro na URL,
esse parmetro ser utilizado nas notificaes Tile e Toast, assim,
quando o usurio clicar sobre Tile ou Toast, ele ser redirecionado
para essa pgina com os seus devidos parmetros, conforme a
Listagem 6.
Figura 7. Adicione imagens configurando para serem copiadas quando compilar o projeto
Listagem 4. Vriaveis globais da classe
01 // Nome do canal push do App
02 private readonly string channelName = WP8PushChannel;
03
04 //Uri do Projeto WebServer
05 private readonly string uriBaseImagesTile = http://169.254.80.80:2704;
06
07 // Objeto que contem as informaes do canal Push.
08 HttpNotificationChannel pushChannel;
Listagem 5. Propriedades, mtodo e evento utilizado no binding
01 private string _tituloJogo;
02 public string TituloJogo
03 {
04 get
05 {
06 return _tituloJogo;
07 }
08 set
09 {
10 if (value != _tituloJogo)
11 {
12 _tituloJogo = value;
13 NotifyPropertyChanged(TituloJogo);
14 }
15 }
16 }
17
18 private ObservableCollection<string> _informacoesJogo;
19 public ObservableCollection<string> InformacoesJogo
20 {
21 get
22 {
23 if (_informacoesJogo == null)
24 _informacoesJogo = new ObservableCollection<string>();
25
26 return _informacoesJogo;
27 }
28 set
29 {
30 if (value != _informacoesJogo)
31 {
32 _informacoesJogo = value;
33 NotifyPropertyChanged(InformacoesJogo);
34 }
35 }
36 }
37 // Evento para notificao de atualizao dos elementos da
38 // pagina que esto atrelados s propriedades
39 public event PropertyChangedEventHandler PropertyChanged;
40 private void NotifyPropertyChanged(String propertyName)
41 {
42 PropertyChangedEventHandler handler = PropertyChanged;
43 if (null != handler)
44 {
45 handler(this, new PropertyChangedEventArgs(propertyName));
46 }
47 }
Notificaes Push no Windows Phone 8 Notificaes Push no Windows Phone 8
Edio 110 .Net Magazine 9
Alm das criaes dos Tiles, se execu-
tarem o projeto em modo Debug, na aba
output do Visual Studio deve ser exibida a
URI do canal criado com o servio de Push,
o que ilustrado na Figura 8. Essa URI ser
utilizada na requisio das notificaes.
Por fim, criaremos os mtodos que iro
se registrar junto ao cliente Push do te-
lefone todas as notificaes para a App.
Alguns passos so comuns para todos os
tipos de notificao, como a verificao
da existncia do canal antes de abri-lo, o
registro no evento ChannelUriUpdated,
que ir informar quando houver alterao
no endereo do canal. Nesse momento, em
um cenrio real, precisaramos enviar essa
nova URI ao servio Web. Outro evento
comum o ErrorOccurred, que deve in-
formar a ocorrncia de algum dos erros
da Tabela 1.
Iniciando pela notificao do tipo Tile,
podemos dizer que essa notificao fun-
ciona mesmo quando a App no est em
execuo, e pode ser usado para baixar
recursos, como imagens externas ao
telefone. Para isso, precisamos informar
todas as URIs absolutas confiveis no
Figura 8. URI a ser utilizada nas requisies das notificaes
01 protected override void OnNavigatedTo(NavigationEventArgs e)
02 {
03 if (NavigationContext.QueryString.Keys.Contains(TituloJogo))
04 {
05 this.TituloJogo = NavigationContext.QueryString[TituloJogo];
06
07 if (NavigationService.CanGoBack)
08 NavigationService.RemoveBackEntry();
09 }
10
11 //Cria todos os Tiles secundarios que sero usados: Flip, Iconic e Cycle
12 CriarTilesSecundarios();
13
14 base.OnNavigatedTo(e);
15 }
16 private void CriarTilesSecundarios()
17 {
18 var tile = ShellTile.ActiveTiles.Where
(t => t.NavigationUri.OriginalString.Contains
(Tile=iconic)).FirstOrDefault();
19
20 if (tile == null)
21 {
22 IconicTileData iconicTile = new IconicTileData();
23 iconicTile.Title = Iconic;
24 ShellTile.Create(new Uri(/MainPage.xaml?TituloJogo=BRA x ESP&Tile=iconic,
25 UriKind.Relative), iconicTile, true);
26
27 return;
28 }
29
30 tile = ShellTile.ActiveTiles.Where
31 (t => t.NavigationUri.OriginalString.Contains(Tile=flip)).FirstOrDefault();
32
33 if (tile == null)
34 {
35 FlipTileData flipTile = new FlipTileData();
36 flipTile.Title = Flip;
37 ShellTile.Create(new Uri(/MainPage.xaml?TituloJogo=BRA x ESP&Tile=flip,
38 UriKind.Relative), flipTile, true);
39
40 return;
41 }
42
43 tile = ShellTile.ActiveTiles.Where
44 (t => t.NavigationUri.OriginalString.Contains(Tile=cycle))
45 .FirstOrDefault();
46
47 if (tile == null)
48 {
49 CycleTileData cycleTile = new CycleTileData();
50 cycleTile.Title = Cycle;
51 ShellTile.Create(new Uri(/MainPage.xaml?TituloJogo=BRA x ESP&Tile=cycle,
52 UriKind.Relative), cycleTile, true);
53
54 return;
55 }
56 }
Listagem 6. Rotina executada na abertura da pgina
momento do binding do canal, BindTo-
ShellTile, atravs do parmetro do tipo
Collection<Uri>, caso contrrio, se for
utilizada a sobrescrita do tipo void, a
notificao acessar somente recursos lo-
cais da App, de acordo com a Listagem 7.
Apesar disso, existe uma exceo para
a notificao de Tiles do tipo Cycle que
no permite o uso de recursos externos,
nesse caso, para utilizar recursos exter-
nos preciso utilizar um Background
Agent para baixar qualquer recurso de
um servidor, e assim salvar localmente
para depois ser utilizado no momento
do Push.
A notificao do tipo Toast tambm fun-
ciona com a App fechada, a diferena que
ao receber a notificao, pode existir uma
interao direta com o usurio temporaria-
mente. Caso o mesmo clique sobre a rea
do Toast, a App ir se abrir em uma URI
determinada no XML da notificao, caso
contrrio, a notificao desaparece aps
alguns segundos. Essa situao ocorrer
quando a App no estiver em execuo
em primeiro plano, seno, ser preciso
registrar-se no evento ShellToastNoti-
ficationReceived para que a App possa
identificar que uma notificao Toast foi
recebida. Nesse caso, a deciso sobre o que
Notificaes Push no Windows Phone 8 Notificaes Push no Windows Phone 8
10 .Net Magazine Edio 110
fazer fica a cargo do desenvolvedor. No exemplo da Listagem 8
apenas ser exibida uma mensagem com os parmetros recebidos
na notificao.
Alem disso, para registrar no canal a utilizao do Toast, ne-
cessrio efetuar o bind atravs do mtodo BindToShellToast.
Alm do tipo de notificao Tile e Toast, tambm possvel utili-
zar no Windows Phone a notificao do tipo Raw, que se diferencia
das demais pelo fato do canal de comunicao para o recebimento
das notificaes permanecerem operacional apenas enquanto a
App est em primeiro plano. Alm disso, para o recebimento das
notificaes preciso registrar-se no evento HttpNotificationRe-
ceived, conforme a Listagem 9. Os XMLs enviados atravs das
requisies no requerem um modelo especificado pela Microsoft
e podem ser utilizados pelos desenvolvedores livremente, nesse
caso, o XML trafegado contm apenas dois elementos que sero
utilizados, mostrados no projeto Web.
Projeto Web
O projeto Web consiste em demonstrar parte da funcionalidade
que um servio web faria em um ambiente real para enviar as
notificaes ao MPNS. Desse modo, montaremos uma pgina
que servir para parametrizar o XML a ser enviado na requisio
ao MPNS. Neste exemplo, esse projeto est configurado para ser
executado no IIS Express, na porta 2704, conforme Figura 9.
01 // Construtor
02 public MainPage()
03 {
04 InitializeComponent();
05
06 DataContext = this;
07
08 Loaded += MainPage_Loaded;
09 }
10 void MainPage_Loaded(object sender, RoutedEventArgs e)
11 {
12 InicializarRaw();
13
14 InicializarTile();
15
16 InicializarToast();
17 }
18 private void InicializarTile()
19 {
20 // Tenta encontrar o canal
21 pushChannel = HttpNotificationChannel.Find(channelName);
22
23 // Se no encontrado tenta criar uma nova conexo com o cliente Push.
24 if (pushChannel == null)
25 {
26 pushChannel = new HttpNotificationChannel(channelName);
27
28 // Registra em todos o eventos antes de abrir o canal
29 pushChannel.ChannelUriUpdated +=
new EventHandler<NotificationChannelUriEventArgs>
(PushChannel_ChannelUriUpdated);
30 pushChannel.ErrorOccurred +=
new EventHandler<NotificationChannelErrorEventArgs>
(PushChannel_ErrorOccurred);
31
32 pushChannel.Open();
33
34 // Adiciona o endereo do nosso Web Server como confivel
35 Collection<Uri> remoteUris = new Collection<Uri>();
36 remoteUris.Add(new Uri(uriBaseImagesTile));
37
38 // Fixa ao canal os eventos de tile.
39 pushChannel.BindToShellTile(remoteUris);
40 }
41 else
42 {
43 // Fixa ao canal os eventos de tile.
44 if (!pushChannel.IsShellTileBound)
45 {
46 // Adiciona o endereo do nosso Web Server como confivel
47 Collection<Uri> remoteUris = new Collection<Uri>();
48 remoteUris.Add(new Uri(uriBaseImagesTile));
49
50 // Fixa ao canal os eventos de tile.
51 pushChannel.BindToShellTile(remoteUris);
52 }
53
54 //Se o canal j existir, apenas se registra aos eventos
55 pushChannel.ChannelUriUpdated +=
new EventHandler<NotificationChannelUriEventArgs>
(PushChannel_ChannelUriUpdated);
56 pushChannel.ErrorOccurred +=
new EventHandler<NotificationChannelErrorEventArgs>
(PushChannel_ErrorOccurred);
57
58 if (pushChannel.ChannelUri != null)
59 {
60 // Exibe a nova URI, apenas para exemplo. Em um ambiente real,
// a nova URI dever ser enviada ao servidor Web.
61 System.Diagnostics.Debug.WriteLine(pushChannel.ChannelUri.ToString());
62 MessageBox.Show(String.Format(Channel Uri is {0},
63 pushChannel.ChannelUri.ToString()));
64 }
65 }
66 }
67 void PushChannel_ErrorOccurred(object sender, NotificationChannelError
EventArgs e)
68 {
69 // Passivel para tratamento de erro por parte da aplicao.
70 Dispatcher.BeginInvoke(() =>
71 MessageBox.Show(String.Format(Um erro de notificao
{0} ocorreu. {1} ({2}) {3},
72 e.ErrorType, e.Message, e.ErrorCode, e.ErrorAdditionalData))
73 );
74 }
75
76 void PushChannel_ChannelUriUpdated(object sender, NotificationChannelUri
EventArgs e)
77 {
78 Dispatcher.BeginInvoke(() =>
79 {
80 // Exibe a nova URI, apenas para exemplo. Em um ambiente real,
// a nova URI dever ser enviada ao servidor Web.
81 System.Diagnostics.Debug.WriteLine(e.ChannelUri.ToString());
82 MessageBox.Show(String.Format(A nova Uri {0},
83 e.ChannelUri.ToString()));
84
85 });
86 }
Listagem 7. Inicializao para as notificaes do tipo Tile
Notificaes Push no Windows Phone 8 Notificaes Push no Windows Phone 8
Edio 110 .Net Magazine 11
01 private void InicializarToast()
02 {
03 // Tenta encontrar o canal
04 pushChannel = HttpNotificationChannel.Find(channelName);
05
06 // Se no encontrado tenta criar uma nova conexo com o cliente Push.
07 if (pushChannel == null)
08 {
09 pushChannel = new HttpNotificationChannel(channelName);
10
11 // Registra em todos o eventos antes de abrir o canal
12 pushChannel.ChannelUriUpdated +=
new EventHandler<NotificationChannelUriEventArgs>
(PushChannel_ChannelUriUpdated);
13 pushChannel.ErrorOccurred +=
new EventHandler<NotificationChannelErrorEventArgs>
(PushChannel_ErrorOccurred);
14
15 // Registra esse evento, caso seja necessrio receber
// uma notificao Toast enquanto o App estiver aberto.
16 pushChannel.ShellToastNotificationReceived +=
new EventHandler<NotificationEventArgs>
(PushChannel_ShellToastNotificationReceived);
17
18 pushChannel.Open();
19
20 // Fixa ao canal os eventos toast.
21 pushChannel.BindToShellToast();
22
23 }
24 else
25 {
26 // Fixa ao canal os eventos toast.
27 if(!pushChannel.IsShellToastBound)
28 pushChannel.BindToShellToast();
29
30 //Se o canal j existir, apenas se registra aos eventos
31 pushChannel.ChannelUriUpdated +=
new EventHandler<NotificationChannelUriEventArgs>
(PushChannel_ChannelUriUpdated);
32 pushChannel.ErrorOccurred +=
new EventHandler<NotificationChannelErrorEventArgs>
(PushChannel_ErrorOccurred);
33
34 // Registra esse evento, caso seja necessrio receber
// uma notificao Toast enquanto o App estiver aberto.
35 pushChannel.ShellToastNotificationReceived +=
new EventHandler<NotificationEventArgs>
(PushChannel_ShellToastNotificationReceived);
36
37 if (pushChannel.ChannelUri != null)
38 {
39 // Exibe a nova URI, apenas para exemplo. Em um ambiente real,
// a nova URI dever ser enviada ao servidor Web.
40 System.Diagnostics.Debug.WriteLine(pushChannel.ChannelUri.ToString());
41 MessageBox.Show(String.Format(A Uri do canal {0},
42 pushChannel.ChannelUri.ToString()));
43 }
44
45 }
46
47 }
48
49 private void PushChannel_ShellToastNotificationReceived
(object sender, NotificationEventArgs e)
50 {
51 StringBuilder message = new StringBuilder();
52 string relativeUri = string.Empty;
53
54 // Criao de mensagem apenas para demontrar o recebimento
// do toast enquanto o App est aberto
55 message.AppendFormat(Toast recebido {0}:\n, DateTime.Now.ToShortTime
String());
56
57 // Recupera todas as informaes que esto na mensagem.
58 foreach (string key in e.Collection.Keys)
59 {
60 message.AppendFormat({0}: {1}\n, key, e.Collection[key]);
61
62 if (string.Compare(
63 key,
64 wp:Param,
65 System.Globalization.CultureInfo.InvariantCulture,
66 System.Globalization.CompareOptions.IgnoreCase) == 0)
67 {
68 relativeUri = e.Collection[key];
69 }
70 }
71
72 // Exibe todos os campos da mensagem do toast
73 Dispatcher.BeginInvoke(() => MessageBox.Show(message.ToString()));
74
75 //Navega para a pgina recebida no toast
76 Dispatcher.BeginInvoke(() => NavigationService.Navigate
(new Uri(e.Collection[wp:Param], UriKind.Relative)));
77 }
Listagem 8. Inicializao para as notificaes do tipo Toast
Sendo assim, temos que liberar o acesso do emulador do Win-
dows Phone, o qual roda em um ambiente virtualizado, atravs
da execuo da linha de comando exibida na Figura 10. Apenas
substitua pela porta especificada no projeto, caso seja diferente,
em um prompt de comando (cmd.exe) em modo administrador
para liberar o acesso atravs do firewall do Windows Vista, 7 e 8.
Caso voc tenha outro programa de firewall, provavelmente
precisar liberar acesso a essa porta tambm.
Ento, por ltimo, temos que configurar o acesso ao site do IIS
Express ao endereo IP em que o emulador do Windows Phone
est trabalhando. Para isso, podemos utilizar esse mesmo prompt
de comando e executar ipconfig, e assim localizar o endereo
IP do adaptador cujo nome aparece Windows Phone Emulator
Internal Switch, como se v na Figura 11.
Depois de recuperar o IP, iremos utiliz-lo para adicionar o
acesso atravs do arquivo de configurao do IIS Express, loca-
lizado na pasta IISExpress dentro da pasta Meus Documentos,
que pode ser facilmente acessada pelo caminho: %userprofile%\
documents\IISExpress\config\applicationhost.config.
Abrindo o arquivo, temos que localizar o site configurado no nosso
projeto, que dever ser compilado e executado pelo menos uma vez
para que o Visual Studio possa cri-lo dentro do arquivo applica-
tionhost.config. Assim, devemos copiar a linha j existente, colar
e editar, conforme a linha selecionada na Figura 12, onde 2704
representa a porta em que o IISExpress ir executar e 169.254.80.80
o IP referente ao emulador do Windows Phone 8.
Agora que temos o projeto devidamente configurado para fun-
cionar junto com o Windows Phone, criaremos uma nica pagina
Notificaes Push no Windows Phone 8 Notificaes Push no Windows Phone 8
12 .Net Magazine Edio 110
Figura 9. Imagem com a configurao do projeto Web Forms
Figura 10. Linha de comando para adicionar uma exceo ao firewall do Windows
01 private void InicializarRaw()
02 {
03 // Tenta encontrar o canal
04 pushChannel = HttpNotificationChannel.Find(channelName);
05
06 // Se no encontrado tenta criar uma nova conexo com o cliente Push.
07 if (pushChannel == null)
08 {
09 pushChannel = new HttpNotificationChannel(channelName);
10
11 // Registra em todos o eventos antes de abrir o canal
12 pushChannel.ChannelUriUpdated +=
new EventHandler<NotificationChannelUriEventArgs>
(PushChannel_ChannelUriUpdated);
13 pushChannel.ErrorOccurred +=
new EventHandler<NotificationChannelErrorEventArgs>
(PushChannel_ErrorOccurred);
14 pushChannel.HttpNotificationReceived +=
new EventHandler<HttpNotificationEventArgs>
(PushChannel_HttpNotificationReceived);
15
16 pushChannel.Open();
17 }
18 else
19 {
20 //Se o canal j existir, apenas se registra aos eventos
21 pushChannel.ChannelUriUpdated +=
new EventHandler<NotificationChannelUriEventArgs>
(PushChannel_ChannelUriUpdated);
22 pushChannel.ErrorOccurred +=
new EventHandler<NotificationChannelErrorEventArgs>
(PushChannel_ErrorOccurred);
23 pushChannel.HttpNotificationReceived +=
new EventHandler<HttpNotificationEventArgs>
(PushChannel_HttpNotificationReceived);
24
25 if (pushChannel.ChannelUri != null)
26 {
27 // Exibe a nova URI, apenas para exemplo. Em um ambiente
// real, a nova URI dever ser enviada ao servidor Web.
28 System.Diagnostics.Debug.WriteLine(pushChannel.ChannelUri.ToString());
29 MessageBox.Show(String.Format(A Uri do canal {0},
30 pushChannel.ChannelUri.ToString()));
31 }
32 }
33 }
34
35 private void PushChannel_HttpNotificationReceived
(object sender, HttpNotificationEventArgs e)
36 {
37 string message;
38
39 //L o conteudo do corpo da notificao
40 using (System.IO.StreamReader reader = new System.IO.StreamReader
(e.Notification.Body))
41 {
42 message = reader.ReadToEnd();
43 }
44
45 // Uso de Linq to XML para recuperar o valor dos elementos do XML
46 XDocument doc = XDocument.Parse(message);
47 Dispatcher.BeginInvoke(() =>
48 {
49 TituloJogo = doc.Descendants().Where
(n => n.Name == TituloJogo).First().Value;
50 InformacoesJogo.Add(doc.Descendants().Where
(n => n.Name == InformacaoJogo).First().Value);
51 });
52
53 //Exibe uma mensagem, apenas para mostrar o contedo recebido
54 Dispatcher.BeginInvoke(() =>
55 MessageBox.Show(String.Format(Received Notification {0}:\n{1},
56 DateTime.Now.ToShortTimeString(), message))
57 );
58 }
Listagem 9. Inicializao para as notificaes do tipo Raw
Figura 11. Recuperando o endereo IP do emulador do Windows Phone 8
ASPX que servir como entrada para parametrizar e enviar o XML
ao MPNS. Assim, criaremos a pgina EnviarPush.aspx, respon-
svel por enviar informaes e fotos de um jogo de futebol.
Partindo do design da pgina, criaremos apenas elementos b-
sicos, sem se preocupar com estilo e apresentao, com objetivo
Notificaes Push no Windows Phone 8 Notificaes Push no Windows Phone 8
Figura 12. Editando o arquivo de configurao do IISExpress para permitir o acesso do emulador ao site do projeto
apenas de mostrar como funciona o envio
de notificaes push. Desse modo, na
Listagem 10 criamos um primeiro menu
que ter a diviso entre os tipos Toast, Tile
e Raw de notificao, e um segundo menu
interno ao menu de Tile com os trs tipos
de notificao para Tile que existem para
o Windows Phone 8, que so: Flip, Iconic e
Cycle. Na Listagem 10 est sendo exibido
apenas o contedo do corpo da pgina, ou
seja, que se encontra dentro da tag body.
Aps o design da pgina, implementa-
remos a lgica para seu o funcionamento,
nesse caso, entre os eventos d pagina
utilizaremos o clique do boto Enviar
Notificao e o clique sobre os menus
de troca do tipo de Tile e notificao, de
acordo com a Listagem 11. A partir desse
momento conseguimos testar se o emula-
dor do Windows Phone est conseguindo
acessar o nosso projeto Web, e assim
garantir que quando as notificaes para
Tile forem enviadas, o mesmo conseguir
baixar as imagens para exibio, como
Estas solues so monitoradas pela
tecnologia FairCom todos os dias!
www.falroom.oom 11-S872-9802
2013 FairCom Corporation
t
e
c
n
o
l
o
g
i
a

d
e

b
a
n
c
o

d
e

d
a
d
o
s
C
M
Y
CM
MY
CY
CMY
K
FairCom121212BRhalffinal.pdf 1 1/3/13 2:16 PM
demonstrado na Figura 13. Caso no tenha
sucesso no teste, verifique as configura-
es explicadas anteriormente.
Para o envio das notificaes, chamaremos
um mtodo a partir do clique do boto. Para
cada tipo de notificao existe um modelo de
XML diferente a ser seguido, apesar disso,
todos partem do mesmo princpio. Nesse
caso, preciso utilizar uma URI do canal
Push, enviar apenas requisies do tipo
POST, complementar o modelo do XML
respeitando o uso de caracteres especiais
conforme a Tabela 3, adicionar ao cabea-
lho da requisio o tipo da notificao e a
prioridade para entrega e, por fim, enviar a
requisio e recuperar do status do envio.
Notificaes Push no Windows Phone 8 Notificaes Push no Windows Phone 8
14 .Net Magazine Edio 110
01 <form id=form1 runat=server>
02 URI Canal:<br />
03 <asp:TextBox ID=TextBoxUri runat=serverWidth=50%></asp:TextBox><br />
04 Tipo:
05 <asp:Menu ID=TipoPushWidth=100% runat=server Orientation=Horizontal
06 StaticEnableDefaultPopOutImage=False OnMenuItemClick=
TipoPush_MenuItemClick>
07 <Items>
08 <asp:MenuItem Text=ToastValue=0 Selected=true></asp:MenuItem>
09 <asp:MenuItem Text=TileValue=1></asp:MenuItem>
10 <asp:MenuItem Text=RawValue=2></asp:MenuItem>
11 </Items>
12 </asp:Menu>
13 <div style=border: 1px solid black; width: 75%; padding: 10px>
14 <asp:MultiView ID=MultiViewPush runat=server ActiveViewIndex=0>
15 <asp:View ID=Tab1 runat=server>
16 Title:<br />
17 <asp:TextBox ID=TextBoxTitle runat=server
Width=50%></asp:TextBox><br />
18 Subtitle:<br />
19 <asp:TextBox ID=TextBoxSubTitle runat=server
Width=50%></asp:TextBox><br />
20 Titulo Jogo:<br />
21
<asp:TextBox ID=TextBoxTituloJogo runat=server
Width=50%></asp:TextBox><br />
22 </asp:View>
23 <asp:View ID=Tab2 runat=server>
24 <asp:Menu ID=TipoTileWidth=100% runat=server
Orientation=Horizontal
25 StaticEnableDefaultPopOutImage=False
OnMenuItemClick=TipoTile_MenuItemClick>
26 <Items>
27 <asp:MenuItem Text=FlipValue=0
Selected=true></asp:MenuItem>
28 <asp:MenuItem Text=IconicValue=1></asp:MenuItem>
29 <asp:MenuItem Text=CycleValue=2></asp:MenuItem>
30 </Items>
31 </asp:Menu>
32 <div style=border: 1px solid black; width: 50%; padding: 10px>
33 <asp:MultiView ID=MultiViewTile runat=server
ActiveViewIndex=0>
34 <asp:View ID=View1 runat=server>
35 <br />
36 Flip<br />
37 Front Title:<br />
38 <asp:TextBox ID=TextBoxFrontTitle runat=server>
</asp:TextBox><br />
39 Front Background Image:<br />
40 <asp:TextBox ID=TextBoxBackgroundImage runat=server>
</asp:TextBox><br />
41 Front Count:<br />
42 <asp:TextBox ID=TextBoxCount runat=server
MaxLength=2></asp:TextBox><br />
43 Back Title:<br />
44 <asp:TextBox ID=TextBoxBackTitle runat=server>
</asp:TextBox><br />
45 Back Background Image:<br />
46 <asp:TextBox ID=TextBoxBackBackgroundImage
runat=server></asp:TextBox><br />
47 Back Content:<br />
48 <asp:TextBox ID=TextBoxBackContent runat=server>
</asp:TextBox><br />
49 </asp:View>
50 <asp:View ID=View2 runat=server>
51 <br />
52 Iconic<br />
53 Title:<br />
54 <asp:TextBox ID=TextBoxIconicTitle runat=server>
</asp:TextBox><br />
55 Icon Image:<br />
56 <asp:TextBox ID=TextBoxIconImage runat=server>
</asp:TextBox><br />
57 Content1:<br />
58 <asp:TextBox ID=TextBoxContent1 runat=server>
</asp:TextBox><br />
59 Content2:<br />
60 <asp:TextBox ID=TextBoxContent2 runat=server>
</asp:TextBox><br />
61 Content3:<br />
62 <asp:TextBox ID=TextBoxContent3 runat=server>
</asp:TextBox><br />
63 Count:<br />
64 <asp:TextBox ID=TextBoxIconicCount runat=server
MaxLength=2></asp:TextBox><br />
65 Background Color:<br />
66 <asp:TextBox ID=TextBoxBackgroundColor runat=server>
</asp:TextBox><br />
67 </asp:View>
68 <asp:View ID=View3 runat=server>
69 Cycle<br />
70 Title:<br />
71 <asp:TextBox ID=TextBoxCycleTitle runat=server>
</asp:TextBox><br />
72 Count:<br />
73 <asp:TextBox ID=TextBoxCycleCount runat=server
MaxLength=2></asp:TextBox><br />
74 </asp:View>
75 </asp:MultiView>
76 </div>
77 </asp:View>
78 <asp:View ID=Tab3 runat=server>
79 Titulo Jogo:<br />
80 <asp:TextBox ID=TextBoxTituloJogoRaw runat=server
Width=50%></asp:TextBox><br />
81 Informao Jogo:<br />
82 <asp:TextBox Rows=5 ID=TextBoxInformacaoJogo runat=server
TextMode=MultiLineWidth=50%></asp:TextBox><br />
83 </asp:View>
84 </asp:MultiView>
85 </div>
86 <asp:Button ID=ButtonSend runat=server OnClick=ButtonSend_Click
Text=Enviar Notificacao /><br />
87 Resposta:<br />
88 <asp:Label ID=LabelRespostaMPNS runat=serverWidth=50%></asp:Label>
89 </form>
Listagem 10. Design da pgina que enviar as notificaes
Notificaes Push no Windows Phone 8 Notificaes Push no Windows Phone 8
Edio 110 .Net Magazine 15
01 //Uri do Projeto WebServer
02 protected readonly string uriBaseImagesTile = http://169.254.80.80:2704;
03
04 protected void TipoPush_MenuItemClick(object sender, MenuEventArgs e)
05 {
06 //Troca o menu de Push ativo
07 MultiViewPush.ActiveViewIndex = Int32.Parse(e.Item.Value);
08 }
09
10 protected void TipoTile_MenuItemClick(object sender, MenuEventArgs e)
11 {
12 //Troca o menu de Push de Tile ativo
13 MultiViewTile.ActiveViewIndex = Int32.Parse(e.Item.Value);
14 }
15
16 protected void ButtonSend_Click(object sender, EventArgs e)
17 {
18 //Faz o envio da Notificao de acordo com o menu selecionado
19 switch (Convert.ToInt16(TipoPush.SelectedItem.Value))
20 {
21 case 0:
22 EnviarToast();
23 break;
24 case 1:
25 EnviarTile();
26 break;
27 case 2:
28 EnviarRaw();
29 break;
30 }
31 }
Listagem 11. Mtodos acionados atraves dos eventos
Figura 13. O emulador conseguiu abrir a pgina que criamos no projeto Web, a comunicao
no momento do Push ter sucesso
A partir do status da resposta do envio da requisio possvel
identificar alguns cenrios que dizem a respeito da entrega das
notificaes e estado do canal, de acordo com a Tabela 4.
Os estados de conexo com o telefone podem ser definidos
entre Connected, Temp Disconnected e Disconnected, os quais
possuem as transies demonstradas na Figura 14. No caso, pelo
Caracter Codificao XML
< &lt;
> &gt;
& &amp;
&apos;
&quot;
Tabela 3. Caracteres que devem ser tratados quando inseridos dentro
das tags do XML da notificao.
estado Connected pode ser entendido que o telefone tem uma
conexo ativa com o servidor de notificao Push e pode receber
notificaes em tempo real.
O estado Temp Disconnected um estado temporrio onde a
conexo com o servidor de notificao Push foi perdida e ser
tentado restabelecer a comunicao assim que o telefone tiver
uma conexo vlida com a Internet. Nesse estado, o aparelho pode
permanecer por 24 horas e todas as notificaes so enfileiradas
Notificaes Push no Windows Phone 8 Notificaes Push no Windows Phone 8
16 .Net Magazine Edio 110
Cdigo de Resposta
Status da
Notificao
Status da Conexo
com o telefone
Status do
Canal
Descrio
200 OK Received Connected Active
A requisio da notificao foi aceita e includa na fila para entrega. O MPNS pode respon-
der com esse status mesmo que o telefone esteja alternando para o estado Temp Discon-
nected. Isso significa que a notificao no ser entregue at que o telefone retorne do
estado Temp Disconnected.
200 OK Received Temp Disconnected Active
A requisio foi aceita e includa na fila para entrega. No entanto, o telefone est tempora-
riamente desconectado.
200 OK QueueFull Connected Active
O MPNS mantem no mximo 30 notificaes de cada canal para entrega. Uma vez que
esse limite atingido, todas as mensagens so descartadas at que o telefone se conecte
e a fila seja esvaziada.
200 OK QueueFull Temp Disconnected Active
O MPNS mantem no mximo 30 notificaes para entrega de cada canal. Uma vez que
esse limite atingido, todas as mensagens so descartadas at que o telefone se conecte
e a fila seja esvaziada.
200 OK Suppressed Connected Active
A notificao foi recebida e foi descartada pelo servio de notificao push. O status de
descartada pode ocorrer se o tipo de notificao no foi ativado pela chamada BindTo-
ShellTile ou BindToShellToast pelo App, ou no caso de uma notificao do tipo Raw, a
requisio foi enviada enquanto o App no estava em execuo em primeiro plano, ou se
foi uma notificao do tipo Tile, nenhum Tile est fixado.
200 OK Suppressed Temp Disconnected Active
A notificao foi recebida e foi descartada pelo servio de notificao push. O status de
descartada pode ocorrer se o tipo de notificao no foi ativado pela chamada BindTo-
ShellTile ou BindToShellToast pelo App, ou no caso de uma notificao do tipo Raw, a
requisio foi enviada enquanto o App no estava em execuo em primeiro plano, ou se
foi uma notificao do tipo Tile, nenhum Tile est fixado.
400 BadRequest N/A N/A N/A
Esse erro ocorre quando o servio Web enviou uma requisio de notificao com um XML
ou URI que contem erros.
401 Unauthorized N/A N/A N/A
Uma notificao no autorizada se existe alguma divergncia entre o nome da pessoa
no certificado do servio Web com o nome da pessoa no certificado do servio de notifica-
o push, ou mesmo se o token no valido para o canal ou foi modificado.
404 Not Found Dropped Connected Expired
O canal invlido e no est presente no servio de notificao push. O servio Web deve
parar de enviar novas notificaes para esse canal.
404 Not Found Dropped Temp Disconnected Expired
O canal invlido e no est presente no servio de notificao push. O servio Web deve
parar de enviar novas notificaes para esse canal.
404 Not Found Dropped Disconnected Expired
O canal invlido e no est presente no servio de notificao push. O servio Web deve
parar de enviar novas notificaes para esse canal.
405 Method Not
Allowed
N/A N/A N/A Apenas o mtodo POST aceito no envio das requisies das notificaes.
406 Not Acceptable Dropped Connected Active
Esse erro pode acontecer quando um servio Web est utilizando o modo sem autenti-
cao de envio de notificao e esse atingiu o limite por dia de envio para determinado
canal. Quando ocorrer esse erro, o servio Web pode tentar enviar uma notificao a cada
hora, no entanto, pode ser necessrio esperar at 24 horas para que o envio de notifica-
es seja normalizado.
406 Not Acceptable Dropped Temp Disconnected Active
Esse erro pode acontecer quando um servio Web est utilizando o modo sem autenti-
cao de envio de notificao e esse atingiu o limite por dia de envio para determinado
canal. Quando ocorrer esse erro, o servio Web pode tentar enviar uma notificao a cada
hora, no entanto, pode ser necessrio esperar at 24 horas para que o envio de notifica-
es seja normalizado.
412 Precondition
Failed
Dropped Disconnected N/A
O telefone est em um estado desconectado. O servio Web deve continuar enviando as
notificaes normalmente.
503 Service Unavai-
lable
N/A N/A N/A
O servio de notificao Push no foi capaz de processar a requisio, desse modo, a
requisio pode ser reenviada mais tarde.
Tabela 4. Tabela com os cdigos de retorno do MPNS
at que a fila no esteja cheia. Algumas razes podem levar o
telefone entrar nesse estado, como: o telefone pode estar em rea
de roaming e por isso a conexo pode ser interrompida; o sinal de
celular onde o usurio est sofre instabilidades; alguns proxys de
acesso Internet podem interromper essa conexo direta; o modo
economia de bateria se encontra ligado e com isso as notificaes
Push so desligadas temporariamente.
J no estado Disconnected o telefone est sem conexo com o
servidor de notificao por mais de 24 horas. Quando o telefone
entra nesse estado, todas as notificaes que foram enfileiradas
Notificaes Push no Windows Phone 8 Notificaes Push no Windows Phone 8
Edio 110 .Net Magazine 17
para esse telefone so descartadas e no sero entregue quando
o mesmo restabelecer a comunicao.
Um dos requisitos para o envio da notificao do tipo Toast
o preenchimento do cabealho da requisio, de acordo com os
cabealhos da Tabela 5. Tambm existe um modelo de XML a ser
seguido, que deve ser devidamente preenchido de acordo com a
necessidade, nesse caso, podemos ver na Listagem 12 que o XML
composto pelos elementos wp:Text1, wp:Text2 e wp:Param, de-
monstrados na Figura 15, onde o elemento wp:Param corresponde
pgina na qual a App ser aberta, caso o usurio clique sobre
o Toast. Caso o contedo desse elemento seja vazio, a App ser
Figura 14. Transio entre os estados de conexo dos telefones com o servidor de notificao
Push, fonte: MSDN Figura 15. Visualizao de cada elemento da notificao Toast - Fonte: MSDN
Cabealho da Requisio Valor Descrio
X-WindowsPhone-Target toast Identificao da notificao
X-NotificationClass
2 Entrega imediata.
12 Entrega dentro de 450 segundos.
22 Entrega dentro de 900 segundos.
Tabela 5. Cabealhos que devem conter no envio da requisio para notificaes do tipo Toast
01 private void EnviarToast()
02 {
03 try
04 {
05 // URI retornada pelo cliente Push quando criado o canal para notificao
06 string subscriptionUri = TextBoxUri.Text.ToString();
07
08 HttpWebRequest sendNotificationRequest =
(HttpWebRequest)WebRequest.Create(subscriptionUri);
09
10 // HTTP POST o unico method aceito para as nofitificaes
11 sendNotificationRequest.Method = POST;
12
13 // O cabealho X-MessageID opcional e pode ser usado
// para identificar uma mensagem de notificao.
14 // Se estiver presente, o mesmo valor retornado na resposta da requisio.
15 // sendNotificationRequest.Headers.Add(X-MessageID, <UUID>);
16
17 // Criando uma mensagem para a notificao.
18 string toastMessage = <?xml version=\1.0\ encoding=\utf-8\?> +
19 <wp:Notification xmlns:wp=\WPNotification\> +
20 <wp:Toast> +
21 <wp:Text1> + TextBoxTitle.Text + </wp:Text1> +
22 <wp:Text2> + TextBoxSubTitle.Text + </wp:Text2> +
23 <wp:Param>/MainPage.xaml?TituloJogo= +
TextBoxTituloJogo.Text + </wp:Param> +
24 </wp:Toast> +
25 </wp:Notification>;
26
27 // Convertendo para byte[].
28 byte[] notificationMessage = Encoding.UTF8.GetBytes(toastMessage);
29
30 // Apontando o tamanho e tipo do corpo da requisio.
31 sendNotificationRequest.ContentLength = notificationMessage.Length;
32 sendNotificationRequest.ContentType = text/xml;
33
34 // A configurao 2 do cabealho X-NotificationClass
// serve para solicitar uma entrega imediata.
35 sendNotificationRequest.Headers.Add(X-WindowsPhone-Target, toast);
36 sendNotificationRequest.Headers.Add(X-NotificationClass, 2);
37
38 using (Stream requestStream = sendNotificationRequest.GetRequestStream())
39 {
40 requestStream.Write(notificationMessage, 0, notificationMessage.Length);
41 }
42
43 // Recuperando a resposta do MPNS.
44 HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.
GetResponse();
45 string notificationStatus = response.Headers[X-NotificationStatus];
46 string notificationChannelStatus = response.Headers[X-SubscriptionStatus];
47 string deviceConnectionStatus = response.Headers[X-DeviceConnection
Status];
48
49 // Exibindo resposta recebida. Recomendado tratamento de erros,
// at porque as notificaes podem no ser enviadas ao telefone
50 LabelRespostaMPNS.Text = notificationStatus + | +
deviceConnectionStatus + | + notificationChannelStatus;
51 }
52 catch (Exception ex)
53 {
54 LabelRespostaMPNS.Text = Ocorreu uma exceo ao enviar a requisio:
+ ex.ToString();
55 }
56 }
Listagem 12. Rotina que faz o envio da notificao do tipo Toast para o MPNS
Notificaes Push no Windows Phone 8 Notificaes Push no Windows Phone 8
18 .Net Magazine Edio 110
aberta na pgina inicial padro. Na Figura 16 vemos a aplicao
sendo testada, com a notificao sendo enviada pela pgina web
e recebida pelo telefone.
Figura 16. Notificao do tipo Toast recebida
Figura 19. Visualizao de cada elemento da notificao para Tiles do tipo Cycle, fonte: MSDN
Figura 18. Visualizao de cada elemento da notificao para Tiles do tipo Iconic - Fonte: MSDN
Figura 17. Visualizao de cada elemento da notificao para Tiles do tipo Flip - Fonte: MSDN
Assim como a notificao do tipo Toast, as notificaes do tipo
Tile tambm apresentam o mesmo requisito, tanto para o pre-
enchimento do modelo do XML, exemplificado na Listagem 13,
como o preenchimento do cabealho da requisio de acordo com
a Tabela 6. Alm dos requisitos, existem outros parmetros do
XML, todos visualmente demonstrados nas Figuras 17, 18 e 19, que
so utilizados nesse tipo de notificao, como o elemento ID, que
deve ser utilizado para indicar o Tile que ser atualizado. Sendo
assim, o valor desse elemento deve conter a URI exata do Tile
que dever ser atualizado, caso esse atributo no seja informado,
o Tile principal da App ser atualizado. Cabe observar que este
deve estar fixado na tela inicial para funcionar.
Outro atributo exclusivo para esse tipo de notificao o atributo/
valor Action=Clear, que quando utilizado ir limpar as informa-
es contidas no Tile. No caso de deixar um dos elementos a ser
preenchido, como wp:Count para a notificao do tipo Iconic, e no
explicitar o uso do atributo Action=Clear, o nmero exibido no
tile no ser limpo, nem sobrescrito, assim o valor que estiver no
momento da atualizao ir permanecer. Outra observao com re-
lao ao tipo Iconic que o valor para o elemento BackgroundColor
tem que iniciar em #FF, como #FFAB4434, seno ao invs de exibir
essa cor, ser exibida a cor do tema padro do telefone.
Durante a parametrizao do XML, temos que lembrar que para
os tipos Flip e Iconic, as imagens podem ser carregadas do servidor
Web, j para o tipo Cycle, apesar de poder exibir at nove imagens,
permitido apenas a exibio de imagens que esto no gravadas
localmente telefone. Nas Figuras 20, 21 e 22 exibido o exemplo
em execuo, com as novas notificaes recebidas.
Cabealho da Requisio Valor Descrio
X-WindowsPhone-Target token Identificao da notificao
X-NotificationClass
1 Entrega imediata.
11 Entrega dentro de 450 segundos.
21 Entrega dentro de 900 segundos.
Tabela 6. Cabealhos que devem conter no envio da requisio para notificaes do tipo Tile.
Notificaes Push no Windows Phone 8 Notificaes Push no Windows Phone 8
Edio 110 .Net Magazine 19
01 private void EnviarTile()
02 {
03 try
04 {
05 // URI retornada pelo cliente Push quando criado o canal para notificao
06 string subscriptionUri = TextBoxUri.Text.ToString();
07 HttpWebRequest sendNotificationRequest =
(HttpWebRequest)WebRequest.Create(subscriptionUri);
08 // HTTP POST o unico method aceito para as nofitificaes
09 sendNotificationRequest.Method = POST;
10 // O cabealho X-MessageID opcional e pode ser usado
// para identificar uma mensagem de notificao.
11 // Se estiver presente, o mesmo valor retornado na resposta da requisio.
12 // sendNotificationRequest.Headers.Add(X-MessageID, <UUID>);
13 // Criando uma mensagem para a notificao.
14 string tileMessage;
15 switch (Convert.ToInt16(TipoTile.SelectedItem.Value))
16 {
17 // Iconic
18 case 1:
19 tileMessage = <?xml version=\1.0\ encoding=\utf-8\?>
20 +<wp:Notification xmlns:wp=\WPNotification\Version=\2.0\>
21 + <wp:Tile Id=\/MainPage.xaml?TituloJogo=BRA x
ESP&amp;Tile=iconic\Template=\IconicTile\>
22 + <wp:SmallIconImage + (string.IsNullOrEmpty
(TextBoxIconImage.Text) ? Action=\Clear\ : ) + >
+ uriBaseImagesTile + TextBoxIconImage.Text
+ </wp:SmallIconImage>
23 + <wp:IconImage + (string.IsNullOrEmpty
(TextBoxIconImage.Text) ? Action=\Clear\ : )
+ > + uriBaseImagesTile + TextBoxIconImage.Text
+ </wp:IconImage>
24 + <wp:WideContent1 + (string.IsNullOrEmpty
(TextBoxContent1.Text) ? Action=\Clear\ : )
+ > + TextBoxContent1.Text + </wp:WideContent1>
25 + <wp:WideContent2 + (string.IsNullOrEmpty
(TextBoxContent2.Text) ? Action=\Clear\ : )
+ > + TextBoxContent2.Text + </wp:WideContent2>
26 + <wp:WideContent3 + (string.IsNullOrEmpty
(TextBoxContent3.Text) ? Action=\Clear\ : )
+ > + TextBoxContent3.Text + </wp:WideContent3>
27 + <wp:Count + (string.IsNullOrEmpty
(TextBoxIconicCount.Text) ? Action=\Clear\ : )
+ > + TextBoxIconicCount.Text + </wp:Count>
28 + <wp:Title + (string.IsNullOrEmpty
(TextBoxIconicTitle.Text) ? Action=\Clear\ : )
+ > + TextBoxIconicTitle.Text + </wp:Title>
29 + <wp:BackgroundColor + (string.IsNullOrEmpty
(TextBoxBackgroundColor.Text) ? Action=\Clear\ : )
+ > + TextBoxBackgroundColor.Text + </wp:BackgroundColor>
30 +</wp:Tile>
31 +</wp:Notification>;
32 break;
33 // Cycle
34 case 2:
35 tileMessage = <?xml version=\1.0\ encoding=\utf-8\?>
36 +<wp:Notification xmlns:wp=\WPNotification\Version=\2.0\>
37 + <wp:Tile Id=\/MainPage.xaml?TituloJogo=BRA x
ESP&amp;Tile=cycle\Template=\CycleTile\>
38 + <wp:SmallBackgroundImage>
/Images/taca.jpg</wp:SmallBackgroundImage>
39 + <wp:CycleImage1>/Images/taca.jpg</wp:CycleImage1>
40 + <wp:CycleImage2>/Images/campeao.jpg</wp:CycleImage2>
41 + <wp:CycleImage3>/Images/carrinho.jpg</wp:CycleImage3>
42 + <wp:CycleImage4>/Images/chute.jpg</wp:CycleImage4>
43 + <wp:CycleImage5>/Images/comemoracao.jpg</wp:CycleImage5>
44 + <wp:CycleImage6>/Images/comemoracao2.jpg</wp:CycleImage6>
45 + <wp:CycleImage7>/Images/comemoracao3.jpg</wp:CycleImage7>
46 + <wp:CycleImage8>/Images/expulsao.jpg</wp:CycleImage8>
47 + <wp:CycleImage9>/Images/golneymar.jpg</wp:CycleImage9>
48 + <wp:Count + (string.IsNullOrEmpty(TextBoxCycleCount.Text)
? Action=\Clear\ : ) + > + TextBoxCycleCount.Text
+ </wp:Count>
49 + <wp:Title + (string.IsNullOrEmpty(TextBoxCycleTitle.Text)
? Action=\Clear\ : ) + > + TextBoxCycleTitle.Text
+ </wp:Title>
50 +</wp:Tile>
51 +</wp:Notification>;
52
53 break;
54 // Flip
55 default:
56 tileMessage = <?xml version=\1.0\ encoding=\utf-8\?>
57 +<wp:Notification xmlns:wp=\WPNotification\Version=\2.0\>
58 + <wp:Tile Id=\/MainPage.xaml?TituloJogo=BRA x ESP&amp;Tile=flip\
Template=\FlipTile\>
59 + <wp:SmallBackgroundImage
+ (string.IsNullOrEmpty(TextBoxBackgroundImage.Text) ?
Action=\Clear\ : ) + > + uriBaseImagesTile
+ TextBoxBackgroundImage.Text + </wp:SmallBackgroundImage>
60 + <wp:WideBackgroundImage
+ (string.IsNullOrEmpty(TextBoxBackgroundImage.Text) ?
Action=\Clear\ : ) + > + uriBaseImagesTile
+ TextBoxBackgroundImage.Text + </wp:WideBackgroundImage>
61 + <wp:WideBackBackgroundImage
+ (string.IsNullOrEmpty(TextBoxBackBackgroundImage.Text) ?
Action=\Clear\ : ) + > + uriBaseImagesTile
+ TextBoxBackBackgroundImage.Text +
</wp:WideBackBackgroundImage>
62 + <wp:WideBackContent + (string.IsNullOrEmpty
(TextBoxBackContent.Text) ? Action=\Clear\ : ) + >
+ TextBoxBackContent.Text + </wp:WideBackContent>
63 + <wp:BackgroundImage + (string.IsNullOrEmpty
(TextBoxBackgroundImage.Text) ? Action=\Clear\ : ) + >
+ uriBaseImagesTile + TextBoxBackgroundImage.Text
+ </wp:BackgroundImage>
64 + <wp:Count + (string.IsNullOrEmpty(TextBoxCount.Text) ?
Action=\Clear\ : ) + > + TextBoxCount.Text + </wp:Count>
65 + <wp:Title + (string.IsNullOrEmpty(TextBoxFrontTitle.Text) ?
Action=\Clear\ : ) + > + TextBoxFrontTitle.Text + </wp:Title>
66 + <wp:BackBackgroundImage
+ (string.IsNullOrEmpty(TextBoxBackBackgroundImage.Text) ?
Action=\Clear\ : ) + > + uriBaseImagesTile
+ TextBoxBackBackgroundImage.Text + </wp:BackBackgroundImage>
67 + <wp:BackTitle + (string.IsNullOrEmpty(TextBoxBackTitle.Text) ?
Action=\Clear\ : ) + > + TextBoxBackTitle.Text
+ </wp:BackTitle>
68 + <wp:BackContent + (string.IsNullOrEmpty
(TextBoxBackContent.Text) ? Action=\Clear\ : ) + >
+ TextBoxBackContent.Text + </wp:BackContent>
69 +</wp:Tile>
70 +</wp:Notification>;
71 break;
72 }
73 // Convertendo para byte[].
74 byte[] notificationMessage = Encoding.UTF8.GetBytes(tileMessage);
75 // Apontando o tamanho e tipo do corpo da requisio.
76 sendNotificationRequest.ContentLength = notificationMessage.Length;
77 sendNotificationRequest.ContentType = text/xml;
78 // A configurao 1 do cabealho X-NotificationClass serve
// para solicitar uma entrega imediata.
79 sendNotificationRequest.Headers.Add(X-WindowsPhone-Target, token);
80 sendNotificationRequest.Headers.Add(X-NotificationClass, 1);
81 using (Stream requestStream = sendNotificationRequest.GetRequestStream())
82 {
Listagem 13. Rotina que faz o envio da notificao do tipo Tile para o MPNS
Notificaes Push no Windows Phone 8 Notificaes Push no Windows Phone 8
20 .Net Magazine Edio 110
O ltimo tipo demonstrado ser a notificao do tipo Raw, que
ser recebida somente quando a App estiver aberta em primeiro
plano. Por esse motivo, a sua utilizao destinada para notifi-
caes regulares que necessitem ser visualizadas apenas com a
App em execuo, que nesse caso, conforme a Listagem 14 est
sendo utilizada para atualizar a App com as informaes do
minuto a minuto do jogo de futebol. Conforme explicado ante-
riormente, o XML utilizado no possui formatao determinada
e deve ser utilizado livremente pelo desenvolvedor. Apesar disso,
a utilizao do cabealho da requisio obrigatria, conforme
a Tabela 7.
83 requestStream.Write(notificationMessage, 0, notificationMessage.Length);
84 }
85 // Recuperando a resposta do MPNS.
86 HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.
GetResponse();
87 string notificationStatus = response.Headers[X-NotificationStatus];
88 string notificationChannelStatus = response.Headers[X-SubscriptionStatus];
89 string deviceConnectionStatus = response.Headers[X-DeviceConnectionStatus];
90 // Exibindo resposta recebida. Recomendado tratamento de erros,
// at porque as notificaes podem no ser enviadas ao telefone
91 LabelRespostaMPNS.Text = notificationStatus + | + deviceConnectionStatus
+ | + notificationChannelStatus;
92 }
93 catch (Exception ex)
94 {
95 LabelRespostaMPNS.Text = Ocorreu uma exceo ao enviar a requisio:
+ ex.ToString();
96 }
97 }
Continuao: Listagem 13. Rotina que faz o envio da notificao do tipo Tile para o MPNS
Figura 22. Notificao do tipo Tile - Cycle recebida
Figura 21. Notificao do tipo Tile - Iconic recebida
Figura 20. Notificao do tipo Tile - Flip recebida
Cabealho da Requisio Valor Descrio
X-NotificationClass
3 Entrega imediata.
13 Entrega dentro de 450 segundos.
23 Entrega dentro de 900 segundos.
Tabela 7. Cabealho que devem conter no envio da requisio para notificaes do tipo Raw
Notificaes Push no Windows Phone 8 Notificaes Push no Windows Phone 8
Edio 110 .Net Magazine 21
01 private void EnviarRaw()
02 {
03 try
04 {
05 // URI retornada pelo cliente Push quando criado o canal para notificao
06 string subscriptionUri = TextBoxUri.Text.ToString();
07
08 HttpWebRequest sendNotificationRequest =
(HttpWebRequest)WebRequest.Create(subscriptionUri);
09
10 // HTTP POST o unico method aceito para as nofitificaes
11 sendNotificationRequest.Method = POST;
12
13 // Criando um XML. Esse XML no tem template, o App ter que trata-lo.
14 string rawMessage = <?xml version=\1.0\ encoding=\utf-8\?> +
15 <WP8Push> +
16 <TituloJogo> + TextBoxTituloJogoRaw.Text + </TituloJogo> +
17 <InformacaoJogo> + TextBoxInformacaoJogo.Text +
</InformacaoJogo> +
18 </WP8Push>;
19
20 // Convertendo para byte[].
21 byte[] notificationMessage = Encoding.UTF8.GetBytes(rawMessage);
22
23 // Apontando o tamanho e tipo do corpo da requisio.
24 sendNotificationRequest.ContentLength = notificationMessage.Length;
25 sendNotificationRequest.ContentType = text/xml;
26
27 // A configurao 3 do cabealho X-NotificationClass serve
// para solicitar uma entrega imediata.
28 sendNotificationRequest.Headers.Add(X-NotificationClass, 3);
29
30 // Enviando conteudo ao MPNS
31 using (Stream requestStream = sendNotificationRequest.
GetRequestStream())
32 {
33 requestStream.Write(notificationMessage, 0,
notificationMessage.Length);
34 }
35
36 // Recuperando a resposta do MPNS.
37 HttpWebResponse response = (HttpWebResponse)sendNotification
Request.GetResponse();
38 string notificationStatus = response.Headers[X-NotificationStatus];
39 string notificationChannelStatus = response.Headers[X-Subscription
Status];
40 string deviceConnectionStatus = response.Headers[X-DeviceConnection
Status];
41
42 // Exibindo resposta recebida. Recomendado tratamento de erros,
// at porque as notificaes podem no ser enviadas ao telefone
43 LabelRespostaMPNS.Text = notificationStatus + | + deviceConnection
Status
+ | + notificationChannelStatus;
44 }
45 catch (Exception ex)
46 {
47 LabelRespostaMPNS.Text = Ocorreu uma exceo ao enviar a requisio:
+ ex.ToString();
48 }
49 }
Listagem 14. Rotina que faz o envio da notificao do tipo Raw para o MPNS
Notificaes Push no Windows Phone 8 Notificaes Push no Windows Phone 8
22 .Net Magazine Edio 110
Figura 23. Notificaes do tipo Raw recebidas
Felipe Farias Ferrari
Especialista em Desenvolvimento de Software, graduado em Ci-
ncia da Computao pelo Centro Universitrio da FEI. Atua como
Desenvolvedor .NET pela Hewlett-Packard Company, e Consultor
Especializado em Arquitetura OO, Web, Mobile e Plataforma .Net.
Autor
Links:
Documentao oficial referente o Microsoft Push Notification Service
http://msdn.microsoft.com/en-us/library/windowsphone/develop/ff402558(v=vs.105).aspx
Adicionando os tipos de Notificao para Tiles do Windows Phone 8, no Windows
Phone 7.8
http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj720574(v=vs.105).aspx
Documentao oficial sobre notificao Push no Windows Phone
http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh202945(v=vs.105).aspx
D seu voto em www.devmedia.com.br/netmagazine/feedback
Ajude-nos a manter a qualidade da revista!
Voc gostou deste artigo?
O resultado desse exemplo apresentado na Figura 23.
Concluso
A utilizao das notificaes Push pode fazer com que sua App
tenha maior aceitao e, por consequncia, alcance maior popu-
laridade, visto que uma funcionalidade que permite ao usurio
estar sempre atualizado ou em contato mais vezes com a App, e
que d a sensao para o usurio de que ele est recebendo um
contedo exclusivo para ele. Para isso, necessrio que seja feita
uma anlise em relao a escolha do tipo de notificao, levando
em conta objetivo da notificao e a melhor maneira de apresen-
tao ao usurio.
Notificaes Push no Windows Phone 8 Notificaes Push no Windows Phone 8
Edio 110 .Net Magazine 23
Data Binding em WPF: interagindo com o banco de dados
24 .Net Magazine Edio 110
Porque esse artigo til::
Em geral, todas as aplicaes reais precisam trabalhar com dados
que, normalmente, vm na forma de um banco. Esse artigo til
porque traz informaes sobre como utilizar dados em aplicaes
WPF de forma segura e rpida. O Data Binding do WPF um recur-
so extremamente interessante e til para o desenvolvedor, que
consegue realizar a ligao de dados sem precisar criar um cdigo
muito extenso. Alm disso, o uso de LINQ se d pelo fato de ser uma
tecnologia muito til e fcil de utilizar para acesso a bancos de dados
relacionais, e o padro MVVM torna a separao entre a lgica de
negcios, os dados e a interface de usurio muito clara, criando uma
maior organizao do cdigo.
Resumo DevMan
Data Binding em WPF:
interagindo com o
banco de dados
Como utilizar Data Binding, LINQ to SQL e MVVM
em aplicaes reais
O
WPF fornece ao desenvolvedor uma forma
muito poderosa e de fcil utilizao para criar
interfaces de usurio. Porm, como tem se
enxergado ao longo dos ltimos anos, as aplicaes
precisam trabalhar com dados para serem consideradas
completas. Uma aplicao comercial, por exemplo, no
pode simplesmente se esquivar de utilizar dados, geral-
mente organizados em bancos de dados relacionais. E,
em tempo de execuo, esses dados sero atualizados,
provavelmente. A partir disso, como os controles iro
saber que os dados que esto exibindo so os mais
recentes?
Para essa questo, o WPF fornece uma tecnologia
chamada de Data Binding, ou ligao de dados, em uma
traduo literal. Com essa tecnologia, possvel realizar
a ligao entre as propriedades de controles, uma fonte
e um alvo, no caso. No cenrio mais comum, isso ser
utilizado para realizar a conexo entre os controles que
mostram dados com a fonte de dados que faz a popula-
o do mesmo. Ento, quando a propriedade do objeto
fonte (no caso, os dados) alterada, a propriedade do
outro objeto (no caso, o controle) atualizada. Isso se d
de uma forma bem simplificada para o desenvolvedor, e
quem cuida de todas as atividades que existem por trs
dessa atualizao o WPF.
Outro ponto importante que as aplicaes necessitam
de uma organizao para serem mantidas. O padro
MVVM fornece ideias interessantes a esse respeito,
trazendo um padro de projetos que permite uma clara
separao entre a interface de usurio e sua lgica de ne-
gcios. Isso muito til nesse caso, porque, obviamente,
os dados devem ser buscados em algum lugar, fora dos
arquivos XAML que compem a interface bsica do aplicativo.
E o MVVM fornece as ferramentas necessrias para que isso seja
realizado de forma organizada e totalmente independente. Por
exemplo, os Models sero as classes do LINQ que representaro o
banco de dados, e os ViewModels sero responsveis pela ligao
entre os Models e as Views, criando todas as rotinas que envolvem
o banco de dados.
WPF Data Binding
O Data Binding uma parte fundamental da plataforma do WPF.
Com os poderes dessa tecnologia, possvel criar uma conexo
entre as propriedades de dois objetos, permitindo que, quando a
propriedade do objeto fonte alterada, a propriedade do objeto
alvo atualizada. Um excelente exemplo a utilizao de um
controle Slider para modificar a propriedade de outro controle.
A mudana refletida em tempo de execuo.
Data Binding em WPF: interagindo com o banco de dados
Edio 110 .Net Magazine 25
Com isso, Data Binding tambm um conceito chave na cria-
o de animaes em WPF. importante notar que, em WPF,
possvel criar uma ligao entre objeto e fonte de dados atravs
de forma procedural, atravs de cdigo, ou de forma declarativa,
via XAML.
Basicamente, o Data Binding no WPF possui quatro peas
bsicas:
Target: o objeto que ir utilizar o resultado da ligao;
Target Property: a propriedade do objeto alvo que ir utilizar
o resultado;
Source: o objeto que fornece o valor;
Path: o caminho que localiza o valor dentro do objeto fonte.
Dessas quatro, as duas primeiras so as mais fceis de serem
entendidas. O Target o controle que contm a ligao, ou seja,
o controle que receber o valor que o Source ir enviar. J a
Target Property a propriedade desse objeto alvo que ir receber
o valor da ligao. importante notar que a Target Property de
um Binding deve ser uma dependency property (BOX 1). Como
a maioria das propriedades cujo Data Binding traria alguma
vantagem so dependency properties, isso acaba no sendo um
grande problema. A fonte do objeto (Source) o objeto do qual a
ligao busca o valor. Esse objeto pode ser um controle, dados ou
um objeto definido em code-behind.
O propsito de dependency properties fornecer um meio de basear o valor de uma propriedade
no valor de outras entradas. Essas outras entradas incluem propriedades de sistema, mecanismos
de determinao de propriedades em tempo de execuo, templates, estilos, etc. Alm disso, elas
podem ser implementadas para fornecer a validao dos dados que so passados a ela, valores
padro,monitoramento de mudanas em outras propriedades,entre outros.Em resumo,dependency
properties so propriedades que podem ser definidas atravs de mtodos como estilizao, data
binding, animao e herana.
BOX 1. Dependency Properties
interessante observar que existem trs tipos de propriedades
que podem ser definidas para a especificao da fonte, que so
ElementName, Source e RelativeSource (BOX 2). S possvel
especificar uma delas por vez, ou seja, o desenvolvedor precisa
escolher uma, dependendo da aplicao em questo. Por fim,
mas no menos importante, vem o caminho da ligao de dados
(Path). Na maior parte dos casos, ele definido pelo nome da
propriedade fonte que o desenvolvedor deseja utilizar. No caso
da utilizao de dados de um banco relacional, ele ir representar
o campo a ser mostrado.
Em WPF, alguns controles, como botes e caixas de texto, so
considerados controles de contedo, ou content controls. Eles fo-
ram criados para mostrar apenas um dado, geralmente um texto.
Outros controles, como listBoxes e comboBoxes, foram criados
para mostrar uma sequncia de valores de um mesmo tipo, e
como tal, so considerados controles de itens, ou item controls.
Como possvel perceber facilmente, realizar a ligao de dados
a controles de contedo muito simples e direto. Basta setar os
quatro elementos bsicos (Target, Target Property, Source e Path)
e est concludo o servio. No caso de controles de itens, a coisa
fica um pouco mais complexa. Para determinar o que mostrar para
cada item, o controle chama o mtodo ToString() da classe base.
No caso de nmeros ou strings, classes que existem por padro,
esse mtodo retorna a representao textual dos itens. Porm, no
caso de objetos mais complexos, como as classes de dados que
queremos definir, ele simplesmente retorna o nome da classe.
A soluo mais simples sobrescrever o mtodo ToString() na
classe de dados que foi definida para que ele retorne algo mais
til para o usurio. Uma soluo mais elaborada, e melhor do
ponto de vista da qualidade da aplicao, criar um template
que mostre os dados de outra forma. Ser nesse template que
ser realizada a ligao com os dados da classe. Essa abordagem
permite que o listBox mostre mais que um tipo de dados por
linha, transformando a experincia do usurio em algo muito
mais interessante.
Como foi dito anteriormente, a fonte da ligao de dados pode ser definida de trs formas:
atravs de ElementName, Source ou RelativeSource. Dessas trs, a primeira a mais simples.
A propriedade ElementName simplesmente recebe o nome de um controle, o controle fonte, no caso.
J a propriedade Source um pouco mais complexa, e geralmente definida atravs de um recurso
esttico (StaticResource). Ela identifica um objeto que deve ser utilizado como a fonte da ligao de
dados, ou seja, utilizada, geralmente, para realizar a ligao com dados oriundos de uma classe. Por
fim, o RelativeSource permite que o objeto fonte seja especificado pela sua relao com o controle
alvo. Normalmente utilizado quando se desejam duas propriedades no mesmo controle.
Alm desses trs, existe um meio adicional de definir a fonte de ligao em um Data Binding:
definindo a propriedade DataContext do controle. Uma vez que controles herdam essa propriedade
de seus ancestrais, esse mtodo permite que vrios controles dividam a mesma fonte de dados.
BOX 2. Binding Source
Outro recurso muito importante que o WPF traz para o Data
Binding a possibilidade de mudana de modos. O WPF possui
quatro modos de ligao de dados que permitem ao desenvolvedor
especificar a relao entre os objetos alvo e fonte. Com o modo
OneWay, como o prprio nome sugere, apenas mudanas no objeto
fonte so importantes, e atualizaro o objeto alvo. No modo Two-
Way, a abordagem um pouco diferente, permitindo atualizao
em qualquer um dos objetos para refletir as mudanas em qual-
quer dos dois. J o modo OneWayToSource o completo inverso
do modo OneWay, e permite que mudanas no objeto alvo sejam
refletidas no objeto fonte. Por fim, o modo OneTime permite que
o objeto alvo seja alterado apenas uma vez, e as demais mudanas
tanto na fonte como no alvo no so refletidas no outro.
LINQ to SQL
LINQ, ou Language Integrated Query, uma linguagem
criada pela Microsoft que permite ao desenvolvedor escrever
consultas estruturadas seguras em torno de colees locais de
objetos e fontes remotas de dados. Basicamente, a LINQ permite
a realizao de consultas em qualquer coleo, seja um array,
uma lista ou uma fonte remota de dados, como uma tabela em
Data Binding em WPF: interagindo com o banco de dados Data Binding em WPF: interagindo com o banco de dados
26 .Net Magazine Edio 110
um banco relacional. Os tipos fundamentais que do suporte
LINQ esto definidos nos namespaces System.Linq, System.
Linq.Expressions e System.Core.
J a LINQ to SQL uma das subtecnologias que permeiam a
LINQ. Ela permite que o desenvolvedor utilize qualquer classe
para representar dados, desde que utilize alguns atributos sim-
ples. Por exemplo, o atributo [Table] diz LINQ to SQL que um
objeto deste tipo totalmente equivalente a uma linha em uma
tabela do banco de dados. Ou seja, a classe em si representa uma
das tabelas do banco.
Como em um diagrama E-R (Entidade-Relacionamento), em
LINQ to SQL tambm existe o conceito de entidades. Uma classe
com o atributo que define a mesma como uma tabela chamada
de entidade. importante ter em mente que esse mapeamen-
to com relao a um banco de dados, para ser til, deve ser no
mnimo aproximadamente igual tabela do banco de dados. A
linguagem traz outros atributos, como [Column], responsvel
por definir colunas de uma tabela. Alm disso, cada um dos
atributos possui propriedades, que dizem se a mesma uma chave
primria, entre outras informaes importantes para bancos de
dados. Alm disso, como o que est sendo definido um banco
de dados, tambm importante definir o relacionamento entre
as tabelas, atravs de referncias a chaves estrangeiras. Isso
realizado atravs do atributo [Association].
Com as entidades j criadas, interessante partir para as con-
sultas aos dados. A LINQ possui diversas formas de consulta aos
dados, como consultas Lambda (BOX 3), consultas de compre-
enso e subconsultas. As consultas Lambda so mais flexveis
e fundamentais, funcionando melhor para expresses com um
nico operador, enquanto consultas de compreenso so muito
mais simples para expresses mais complexas, e mais complexas
para expresses mais simples. Depende muito do desenvolvedor
qual utilizar em quais situaes. preciso analisar cada caso para
ter uma noo do que melhor.
Expresses Lambda so expresses e mtodos annimos com uma sintaxe no sentido de tornar
mais agradvel e elegante a leitura do cdigo. As expresses Lambda surgiram dos delegates, que
nada mais so do que ponteiros para funes. Logo, expresses Lambda so funes, onde a parte
esquerda do smbolo => (operador lambda) so os argumentos da funo e a parte direita da
mesma contm o corpo do mtodo. Elas so utilizadas para expresses simples de consulta a dados,
por serem extremamente flexveis e elegantes, com pouco cdigo para realizar muita coisa.
BOX 3. Consultas Lambda
O designer LINQ to SQL no Visual Studio traz uma ferramenta
de gerao automtica de entidades que muito simples e interes-
sante. No caso de uma aplicao que possui um banco de dados
existente, muito mais interessante pedir a uma ferramenta para
gerar o cdigo automaticamente do que simplesmente construir
todas as tabelas e colunas em cdigo. Alm disso, para muitos
bancos de dados reais, isso impraticvel, devido grande exten-
so dos mesmos. Alm desse designer, existe uma ferramenta de
linha de comando chamada SqlMetal que faz o mesmo servio.
Ambas geram entidades como classes parciais, de forma que
lgica adicional possa ser incorporada em arquivos separados.
Mais importante, as duas ferramentas tambm so responsveis
pela gerao das associaes entre as tabelas.
Padro MVVM (Model-View-View Model)
Para todo desenvolvedor, importante considerar que a interface
de usurio, alm de expor o sistema abaixo dela, deve satisfazer
os imprevisveis requerimentos estilsticos dos usurios. Logo, ela
deve ser a parte mais voltil da aplicao. Existem muitos padres
de design que auxiliam o desenvolvedor na tarefa de tornar a
interface de usurio mais independente do cdigo, entre eles o
MVP (Model-View-Presenter), o MVC (Model-View-Controller) e o
prprio MVVM. Com vrias possibilidades, importante entender
bem todas elas, para que a melhor escolha seja feita.
Porm, antes de tudo, interessante notar que padres de design
nem sempre so necessrios. Em aplicaes simples, pequenas,
totalmente desnecessrio e contra produtivo utiliz-los, uma vez
que qualquer desenvolvedor capaz de entender algumas poucas
linhas de cdigo. Mas, conforme a aplicao comea a crescer,
importante, essencial at, que haja um padro de design por
trs da mesma. Isso ir auxiliar na manuteno da aplicao, ir
permitir que outros desenvolvedores possam dar continuidade
mesma, alm de que a organizao estar l, permitindo que a
complexidade da aplicao continue a aumentar atravs de no-
vas funcionalidades adicionadas. Para cada caso, interessante
analisar os possveis padres a serem utilizados, e escolher o que
melhor se encaixa no escopo do aplicativo.
O MVP um dos mais populares padres de design do mercado.
Ele contm trs componentes: View, Model e Presenter. A primeira
a interface com o usurio, sendo que os dados que ela mostra
compem o Model, e o Presenter a interface entre os dois. J o
MVC tambm muito popular e vem sendo usado h dcadas.
MVP e MVVM nada mais so do que adaptaes do MVC a alte-
raes de tecnologia. O MVC tambm possui um modelo e uma
view, porm o elemento que une os dois o Controller. Existem
algumas diferenas entre o Controller e o Presenter, entre as quais o
fato de que o controlador responsvel por determinar qual View
ser mostrada em resposta a qualquer ao, incluindo quando a
aplicao iniciada, enquanto o Presenter utilizado pela View
para trabalhar com dados, reagir a entradas do usurio e prover
validao das entradas do mesmo.
J o padro MVVM foi criado em 2005 por John Goosman, um
dos arquitetos do WPF e Silverlight na Microsoft. Conceitual-
mente, o MVVM muito parecido com o MVP, diferenciando-se
pelo fato de que o MVVM tpico para WPF e Silverlight (e, pos-
teriormente, Windows Phone e Windows Store Apps), enquanto
o MVP completamente independente de plataforma. Ou seja,
no MVVM as Views so definidas atravs de arquivos XAML que
contm todos os elementos de interface com o usurio.
Em termos de utilidade, o MVVM visa estabelecer uma clara
separao entre o modelo de objetos e a interface com o usurio,
definida em XAML. Ele traz uma clara separao de camadas
Data Binding em WPF: interagindo com o banco de dados Data Binding em WPF: interagindo com o banco de dados
Edio 110 .Net Magazine 27
(Figura 1), em que a View Model utilizada para realizar a ligao
entre a View e o Model, que no se conhecem. A comunicao entre
a View e a View Model se d atravs do mecanismo de binding do
WPF, alm de routed events e routed commands (BOX 4). So esses
trs ltimos elementos que, juntos, fazem do MVVM um padro
extremamente poderoso para construo de aplicaes WPF,
Silverlight, Windows Phone e Windows Store.
possvel obter a primeira fase na diferenciao das responsabi-
lidades de subsistemas dentro do produto. Porm, preciso que
haja uma ligao entre eles. Implementaes de padres de pro-
jetos mais recentes, do conta de uma arquitetura Model-View-X,
onde X o elemento responsvel por realizar a integrao entre
o Model e a View. No caso do MVVM, a integrao realizada
atravs da ViewModel.
A partir daqui, interessante focar o desenvolvimento da apli-
cao no modelo MVVM. Como possvel notar a partir do que
foi visto, a ViewModel o elemento mais importante dessa trinca
que compe o MVVM. Mas, ao mesmo tempo, a menos familiar,
e a mais complicada de entender. Aqui, ser criada a estrutura
completa de uma aplicao com o padro MVVM, bem como uma
classe ViewModelBase, utilizada para trazer operaes bsicas que
dizem respeito ViewModel e sero posteriormente sobrescritas
para mais especificidade.
Antes de tudo, preciso definir o que sero os Models, as
ViewModels e as Views. As Views so as mais simples de serem
definidas. Como se trata de uma aplicao WPF, as vistas sero
os arquivos XAML contendo as interfaces com o usurio. Alm
disso, eles sero responsveis por realizar o Data Binding com as
ViewModels. J os modelos so um pouco mais complexos. Aqui,
ser criada apenas uma pasta no projeto, chamada Models, que
conter todos os modelos de dados. Essas classes modelo sero
criadas posteriormente, quando o banco de dados for criado e
mapeado como classes do LINQ. Por fim, e mais importante,
preciso que se criem as ViewModels. Elas sero colocadas em uma
pasta separada no projeto, com esse mesmo nome, e essa pasta,
inicialmente, conter apenas a classe ViewModelBase, que ser
criada a seguir. Vale ressaltar que esse modelo de pastas em um
projeto s no o nico possvel para aplicaes com o padro
MVVM. Models, Views e ViewModels poderiam ser criados em
projetos separados, referenciando uns aos outros. A Figura 2
mostra a organizao do projeto no Visual Studio.
View ViewModel Model
Notifications
Data Binding/
Commands
Figura 1. Interao entre camadas MVVM
Eventos roteados so eventos que navegam para cima ou para baixo na rvore de visual da aplicao,
dependendo da estratgia de roteamento. Isso significa que ele pode invocar manipuladores em
mltiplos ouvintes ao longo da rvore de elementos, ao invs de apenas no prprio elemento que
levantou o evento. As estratgias de roteamento so Tunneling, Bubbling ou Direct. Normalmente,
eventos roteados aparecem em pares, sendo o primeiro um evento Tunneling e o segundo um
Bubbling, sempre nessa ordem.
Comandos roteados so comandos que implementam a interface ICommand, ao invs de apenas
herdarem da mesma, como fazem os comandos comuns. Assim como eventos roteados, eles podem
navegar pela hierarquia de elementos do WPF.Basicamente, pelo fato de implementarem a interface
ICommand, Routed Commands so comandos que no sabem o que fazem. Quando recebem a
ordem de executar, eles simplesmente delegam essa responsabilidade a outro, navegando para
cima ou para baixo (dependendo da estratgia de roteamento) na rvore de visual da aplicao,
procurando algum que seja capaz de executar o comando.
Esses dois elementos Routed Events e Routed Commands esto relacionados um ao outro. Eles
formam a base para a comunicao ao longo das partes da interface de usurio, sejam essas partes
controles ou mesmo toda a janela.
BOX 4. Routed Events e Routed Commands
interessante ressaltar que, no caso de projetos diferentes para Models, Views e ViewModels,
preciso haver referncias entre eles. Porm, essas referncias devem ser cuidadas, pois sabido que,
pelo padro MVVM, ViewModels referenciam Models e Views referenciam ViewModels. Qualquer
referncia direta entre Views e Models pode levar a problemas no futuro, seja ela implcita ou
explcita, alm de quebrar o padro MVVM.
Nota
Criando e organizando a aplicao no padro MVVM
Antes mesmo de se falar de forma mais aprofundada em MVVM,
preciso ter uma noo do que significa, e porque feita, a separa-
o entre Model e View. O modelo a representao via software
da soluo a um problema, enquanto a vista utilizada para per-
mitir que o usurio interaja com o modelo para resolver o mesmo
problema. A separao entre eles exige uma grande quantidade de
trabalho extra, portanto, preciso entender porque eles precisam
ser separados. Geralmente, em software, aceito que um design
modular melhor do que um monoltico. E designs modulares
bons possuem duas caractersticas em comum: loose coupling e high
cohesion. A primeira diz respeito ao nvel de dependncia entre os
dois mdulos, ou seja, quanto menos dependente os mdulos so
uns dos outros, melhor. J o segundo uma questo de coeso: o
mdulo deve fazer apenas aquilo a que se prope, nem mais, nem
menos. Um mdulo com baixa coeso normalmente possui vrias
funes irrelevantes para a resoluo do problema.
Os programadores vm enxergando o valor de dividir o modelo
e as views por um longo tempo. Separando esses dois elementos,
A partir da, preciso que haja alguma coisa na classe bsica das
ViewModels, ou seja, a classe ser utilizada como uma base para
as demais. Ela ir simplesmente implementar a interface INoti-
fyPropertyChanged. Isso necessrio para que os ViewModels
sejam capazes de entender quando as propriedades so alteradas
pela View. Isso fundamental, pois, essencialmente, no haver
nenhum tipo de cdigo administrvel na View, de acordo com
o padro MVVM. A questo aqui que a interface em questo
contm apenas um evento, chamado PropertyChanged, que
deve ser implementado. Esse evento deve ser pblico, pois pode
Data Binding em WPF: interagindo com o banco de dados Data Binding em WPF: interagindo com o banco de dados
28 .Net Magazine Edio 110
ser acessado por qualquer classe. Para as classes que implemen-
tam esse evento, faz sentido escrever um ajudante simples, que
simplifica a chamada do evento. Esse mtodo aqui chamado
de OnPropertyChanged(string prop). A Listagem 1 mostra o
resultado da classe base de ViewModels. Posteriormente, ser
visto como esse mtodo utilizado para controlar a mudana de
propriedades na View.
em excesso podem quebrar o padro MVVM, gerando problemas
futuros.
Com essas tcnicas de design em mente, a criao da classe
RelayCommand muito simples. Ela implementar a interface
ICommand e, como tal, ter disposio os mtodos CanExecu-
te(), Execute() e o evento CanExecuteChanged, que como o nome
sugere, ser disparado quando a possibilidade de execuo pas-
sar de true para false ou vice-versa. Como visvel na Listagem 2,
trata-se de uma implementao bastante simples, genrica, mas
que contm todos os elementos necessrios a um comando, sendo
intuitiva para usar. Como vemos na linha 27, a tarefa de executar
o comando delegada ao delegate Action<object>, portanto no
h sobrecarga de dependncias extras, o que aconteceria se fosse
utilizado um CommandExecuteHandler, por exemplo. Outro de-
legate utilizado com o mesmo propsito foi o Predicate<object>,
que evita uma chamada ao CanCommandExecuteHandler. Como
a presena do canExecute opcional, foram criados dois cons-
trutores (linhas 03 e 05). J o mtodo CanExecute() simplesmente
diz que caso o campo _canExecute no tenha sido especificado
no construtor, o comando pode ser executado sim, delegando a
responsabilidade da execuo para o Predicate<object>. Por fim,
o evento criado diz respeito a quando o mtodo CanExecute()
muda seu valor de retorno. Como possvel ver nas linhas 20 e 21,
o CommandManager (BOX 5) fornece um evento chamado Re-
querySuggested, que chamado quando ele acredita que houve
mudana no valor de retorno.
Figura 2. Organizao do projeto
Listagem 1. Classe ViewModelBase
01 namespace DadosEmWPFArtigo.ViewModels
02 {
03 class ViewModelBase : INotifyPropertyChanged
04 {
05 public event PropertyChangedEventHandler PropertyChanged;
06 protected virtual void OnPropertyChanged(string prop)
07 {
08 if (PropertyChanged != null)
09 {
10 PropertyChanged(this, new PropertyChangedEventArgs(prop));
11 }
12 }
13 }
14 }
A partir da, a classe bsica est definida. Porm, com essa classe
base, a comunicao entre ViewModel e View ser realizada so-
mente atravs de eventos. Mas essa comunicao tambm pode ser
realizada atravs de comandos. Para isso, ser criada uma classe
bsica, chamada RelayCommand, ou comando de transmisso,
em uma traduo literal. a classe base de todos os comandos
que podero ser chamados na ViewModel que ser criada. Essa
classe vista em muitos projetos MVVM, e se tornou quase um
padro. Embora varie de projeto para projeto, em essncia ela
sempre muito parecida, servindo como uma base a qualquer co-
mando. Porm, preciso entender que existem alguns requisitos
que a classe RelayCommand deve atender. Ela deve manter a
separao entre os controles e o mtodo que ir ser chamado, a
implementao deve ser to artificial quanto for necessrio, nem
mais, nem menos, fazendo com que a mesma seja extremamente
intuitiva para usar, e tambm que dependncias extras devem
ser mantidas ao mnimo, sempre lembrando que dependncias
Listagem 2. Classe RelayCommand
01 class RelayCommand : ICommand
02 {
03 public RelayCommand(Action<object> execute) : this(execute, null)
04 { }
05 public RelayCommand(Action<object> execute,
Predicate<object> canExecute)
06 {
07 if (execute == null)
08 {
09 throw new ArgumentNullException(execute);
10 }
11 _execute = execute;
12 _canExecute = canExecute;
13 }
14 public bool CanExecute(object parameter)
15 {
16 return _canExecute == null ? true : _canExecute(parameter);
17 }
18 public event EventHandler CanExecuteChanged
19 {
20 add { CommandManager.RequerySuggested += value; }
21 remove { CommandManager.RequerySuggested -= value; }
22 }
23 public void Execute(object parameter)
24 {
25 _execute(parameter);
26 }
27 private readonly Action<object> _execute;
28 private readonly Predicate<object> _canExecute;
29 }
Data Binding em WPF: interagindo com o banco de dados Data Binding em WPF: interagindo com o banco de dados
Edio 110 .Net Magazine 29
Data Binding em WPF: interagindo com o banco de dados Data Binding em WPF: interagindo com o banco de dados
30 .Net Magazine Edio 110
Criando o banco de dados com LINQ
Como foi visto, a LINQ to SQL oferece uma srie de ferramentas
que permitem ao desenvolvedor representar dados atravs de
classes. Para isso, basta que estas sejam decoradas com alguns
atributos especiais, como [Table] ou [Column]. Cada atributo
possui um propsito e vrias propriedades, todas elas dizendo
respeito a bancos de dados. Por exemplo, o atributo [Column]
possui uma propriedade chamada IsPrimaryKey, do tipo boolean,
para indicar se a coluna corresponde chave primria da tabela.
Esse um conceito unicamente de bancos de dados relacionais,
o que refora a ideia de que a LINQ foi feita para que as classes
sejam transformadas em tabelas de bancos de dados.
Para este exemplo, ser criada uma tabela de consumidores, cha-
mada Customer. Essa tabela conter as colunas correspondentes
ao Nome do consumidor, seu CPF e seu Endereo, apenas, como
uma forma de simplificao da mesma, alm, obviamente, de seu
identificador nico, Id. Como possvel observar na Listagem 3, a
classe Customer possui o atributo [Table] decorando-a, indicando
que se trata de uma tabela. Alm disso, tambm se v que todas as
propriedades da classe foram transformadas em colunas, atravs
do atributo [Column]. possvel notar uma propriedade comum
a todos eles, chamada Storage. Essa propriedade responsvel
por indicar ao banco de dados que o local de onde o dado deve
ser buscado, e onde ele deve ser armazenado, no aquela pro-
priedade pblica ali, e sim o campo privado que foi declarado no
comeo da classe.
Porm, como facilmente perceptvel, essa classe apenas uma
representao do banco de dados; o banco em si ainda no foi
criado. Para isso, ser criada uma segunda classe, que representar
o DataContext do banco de dados. Na LINQ, essa classe que
efetua a comunicao com a fonte de dados. A classe que ser
criada deve derivar da classe base em System.Data.Linq.Data-
Context. Ela contm a informao e os mtodos para efetuar a
conexo com o banco de dados, alm de manipular esses dados.
Como visvel na Listagem 4, essa classe simples, DBDataContext,
apenas possui um campo, cust, para a tabela de consumidores
do banco de dados. Essa ser a nica tabela do banco, mas, caso
existissem outras, elas tambm seriam definidas aqui. Tambm
possvel ver que o construtor da classe simplesmente chama o
construtor da classe base DataContext, com a string de conexo ao
banco. Essa abordagem de classes parciais dita como fortemente
tipada, e muito mais elegante e recomendada que a abordagem
comum, onde se instancia um DataContext genrico e passa-se
as tabelas a ele.
Mas um problema persiste. Embora a classe de conexo ao banco
de dados tenha sido criada, o banco em si ainda no existe. Para
isso, ser criada uma terceira classe, chamada CustomerData. Essa
classe ser responsvel pela criao e por toda a manipulao
dos dados na aplicao. Ou seja, ela ser responsvel por adicio-
nar, atualizar, excluir e buscar dados no banco. E, para isso, ela
utilizar o DBDataContext criado anteriormente. Inicialmente,
conforme mostrado na Listagem 5, a classe simplesmente ir,
em seu construtor, realizar uma chamada ao DataContext. Com
isso, ir ser realizada uma simples verificao: se o banco de
dados existe ele continua, se no existe ele cria o banco. Isso
uma funo que a LINQ traz que muito importante, pois ele
garante que o banco de dados existir antes de comear a realizar
qualquer operao nele.
A seguir, temos a criao dos mtodos responsveis pela adi-
o, atualizao e excluso de linhas do banco de dados, alm do
mtodo responsvel por criar uma lista de consumidores. Esses
uma classe selada que prov mtodos teis para utilizao em comandos. Alm disso, a classe
fornece servios que permitem descobrir o status de um comando. Os mtodos teis variam desde
mtodos de registro de objetos de binding at handlers de eventos de comandos. Como visto h
pouco, o nico evento da classe o RequerySuggested, que ocorre quando ele detecta condies que
podem alterar a capacidade do comando de executar.
BOX 5. CommandManager
Listagem 5. Construtor da Classe CustomerData
01 public CustomerData()
02 {
03 using (var c = new DBDataContext(conn))
04 {
05 if (!c.DatabaseExists())
06 {
07 c.CreateDatabase();
08 }
09 }
10 }
Listagem 4. Classe DBDataContext
public partial class DBDataContext : DataContext
{
public Table<Customer> cust;
public DBDataContext(String connectionString) : base(connectionString)
{...}
}
Listagem 3. Classe de dados Customer
01 [Table]
02 public class Customer
03 {
04 private int id;
05 private string name;
06 private string cpf;
07 private string endereco;
08 [Column (IsPrimaryKey=true, Storage=id)]
09 public int Id {...}
10 [Column (Storage=name)]
11 public string Name {...}
12 [Column (Storage=cpf)]
13 public string Cpf {...}
14 [Column (Storage=endereco)]
15 public string Endereco {...}
16 }
Data Binding em WPF: interagindo com o banco de dados Data Binding em WPF: interagindo com o banco de dados
Edio 110 .Net Magazine 31
mtodos foram criados tambm dentro da classe CustomerData,
e utilizam novamente o mesmo DBDataContext que respons-
vel pela conexo ao banco de dados. O mtodo Add(Customer
c), basicamente, realiza a insero do consumidor passado como
parmetro na tabela do banco de dados. Isso realizado con-
forme a Listagem 6, que mostra que primeiramente realizado
um InsertOnSubmit(c), na tabela de consumidores do banco, e
posteriormente essas mudanas so enviadas ao banco de dados
pelo DataContext. Os demais mtodos, Update(Customer c) e
Delete(Customer c) seguem o mesmo padro, recuperando, entre-
tanto, o consumidor do banco de dados atravs de uma consulta,
para realizar a alterao e a excluso dos dados. Isso necessrio,
pois o mtodo no sabe que o valor passado por parmetro cor-
responde a um dado do banco de dados. A Listagem 7 mostra em
detalhes esse comportamento. Por fim, o mtodo List() retorna
uma lista que contm todos os elementos da tabela Customer do
banco de dados.
Como vimos, essas trs classes so os modelos da aplicao.
Elas contm a representao dos dados, bem como o acesso aos
mesmos. Porm, esses dados ainda esto completamente sem
uso, isolados nos Models. Para que eles possam ser acessados,
necessrio que ViewModels sejam criadas para buscar esses dados
e envi-los, de alguma forma, para a View exibi-los e para que o
usurio tenha alguma liberdade para realizar alguma atividade
com esses dados. Isso ser feito a seguir.
Criando a ViewModel
Agora, chegou a hora da criao das ViewModels. Como sabe-
mos, pelo padro MVVM, cada uma das Views deve possuir uma
ViewModel, que ir realizar toda a interface entre o Model e a
prpria View. Ou seja, como a aplicao exemplo possui apenas
uma View (MainWindow), s existir uma ViewModel, que ser
chamada de MainWindowViewModel. importante notar que,
como a declarao da classe base de ViewModels tinha apenas um
evento, ele que ser utilizado para saber quando a propriedade
ser alterada pelo usurio.
Como sabido, a comunicao entre as ViewModels e as Views
realizada atravs de eventos e comandos. No necessrio
declarar ambos, mas pelo menos um deles sempre preciso; do
contrrio no haver meio de comunicao entre a ViewModel e
a View e a aplicao ficar completamente sem propsito. Neste
caso, a comunicao entre ambos consistir da verificao de se
a propriedade do objeto do Binding foi alterada ou no, como
j foi comentado. Alm disso, como tambm foi criada uma
classe base de comandos, a ViewModel ir utilizar essa classe
base para realizar comandos de adio, remoo e atualizao
no banco de dados.
Antes da criao das ViewModels, preciso ter em mente que
as ViewModels so modelos das Views. Embora bvio, a maior
parte dos desenvolvedores no d ateno a esse detalhe, e acaba
no sabendo exatamente onde colocar o cdigo: na ViewModel
ou no code-behind da View. Pode ser tentador colocar o cdigo
diretamente na View, por uma simples questo de convenincia.
Porm, isso quase sempre acarreta problemas futuros e, como foi
explicada anteriormente, uma boa aplicao MVVM precisa ser
loosely coupled, ou seja, quanto menos dependente a View for da
ViewModel, e vice-versa, melhor. importante limitar as Views a
apenas o cdigo que especfico aos eventos, elementos, recursos,
entre outros. Essa separao um objetivo que vale a pena, e deve
ser muito claro quando da criao das aplicaes.
Nessa criao de ViewModel especfica, toda a lgica ser feita
atravs da ViewModel, como ser visto. Ou seja, a View no ter
responsabilidade alguma, em termos de lgica de negcios, con-
fiando na ViewModel para isso, o que totalmente condizente
com o padro MVVM. importante ter em mente que, como a
ViewModel ir referenciar o Model, ela poder utilizar algumas
aes que foram colocadas no modelo. Em outras palavras, as
aes que o Model realiza e que devem ser expostas View devem
ser utilizadas pela ViewModel. Aqui, vale um adendo: o modelo
apenas define funes. J a ViewModel deve definir comandos ou
eventos que sirvam para utilizar essas funes na View, atravs
do Data Binding.
Com esses conceitos em mente, hora da construo da View-
Model em si. Como foi criada anteriormente uma classe base de
ViewModels, chamada ViewModelBase, que implementa INoti-
fyPropertyChanged, no necessrio fazer isso agora. Basta que
a classe que ser criada herde dessa classe bsica. Como vimos,
ela possui apenas um evento e um mtodo que trata esse evento.
Ou seja, todo o resto ter que ser implementado pela MainWin-
dowViewModel, a ViewModel especfica nesse caso.
Primeiramente: a classe deve referenciar o modelo. Ou seja,
necessrio trazer um objeto do tipo CustomerData para que ele
Listagem 6. Mtodo Add da classe CustomerData
01 public void Add(Customer c)
02 {
03 using (var ctx = new DBDataContext(conn))
04 {
05 ctx.cust.InsertOnSubmit(c);
06 ctx.SubmitChanges();
07 }
08 }
Listagem 7. Mtodo Delete da classe CustomerData
01 public void Delete(Customer c)
02 {
03 Customer aux = new Customer();
04 using(var ctx = new DBDataContext(conn))
05 {
06 var query = from cust in ctx.cust
where cust.Id == c.Id select cust;
07 foreach (Customer cus in query)
08 {
09 aux = cus;
10 }
11 ctx.cust.DeleteOnSubmit(aux);
12 ctx.SubmitChanges();
13 }
14 }
Data Binding em WPF: interagindo com o banco de dados Data Binding em WPF: interagindo com o banco de dados
32 .Net Magazine Edio 110
possa ter acesso ao banco de dados. Alm disso, a classe Customer-
Data traz uma srie de mtodos, como vimos anteriormente,
para adio, remoo e atualizao de dados no banco. Agora,
na ViewModel, preciso realizar a ponte entre o modelo e a
vista. Basicamente, o que ser feito aqui a transformao
desses mtodos em comandos que podem ser entendidos pela
View. Repare que poderiam ser utilizados eventos, sem problema
nenhum. Porm, a abordagem por comandos se justifica devido
sua maior simplicidade de operao e codificao.
Em um segundo momento, preciso estabelecer os requisitos.
importante lembrar que antes de tudo, a ViewModel uma classe
e, como tal, ela ter atributos, propriedades e mtodos. Portanto, em
termos de atributos, necessrio que haja um do tipo CustomerDa-
ta, para criao do banco de dados. Esse objeto ser inicializado no
construtor da classe e somente l. Por outro lado, tambm neces-
sria a criao de trs objetos do tipo RelayCommand, que sero os
comandos de adio, remoo e atualizao do banco. Tambm so
necessrios dois atributos do tipo Customer, uma vez que a View
precisa indicar quem ser adicionado, atualizado ou removido do
banco de dados. Um deles ser o consumidor atual, que pode ser
excludo ou atualizado, enquanto o outro ser o consumidor a ser
adicionado. Tudo isso mostrado na Listagem 8. Todos esses atri-
butos possuiro suas respectivas propriedades, para que possam
ser acessados pelo arquivo XAML.
A questo dos comandos importante de ser ressaltada, uma
vez que no muito trivial. Caso no seja a primeira vez que eles
esto sendo chamados, ou seja, o comando diferente de nulo,
o cdigo ir criar uma nova instncia de RelayCommand, para
tratar daquela chamada de comando. Cada um dos comandos
define uma chamada de funo como parmetro, sendo que essas
funes so simplesmente chamadas quelas definidas no Model
CustomerData. Alm disso, eles s possuem o getter; o setter
desnecessrio, uma vez que eles no recebero atribuies ser
somente leitura. A Listagem 9 mostra o resultado para o comando
de adio. Os demais comandos (atualizao e remoo) utilizam
o consumidor atual (currentCustomer) para realizar a operao,
conforme dito anteriormente.
Por fim, preciso que a ViewModel utilize a lista que foi criada
na classe CustomerData. Para isso, foi criada uma propriedade
chamada ListData, que receber a lista no construtor da View-
Model. Ou seja, quando for criada uma instncia da ViewModel,
ser criada a lista que corresponde a todos os dados do banco.
Esses dados sero atualizados a cada comando, como foi visto na
Listagem 9. importante ressaltar a necessidade de se referenciar
a propriedade ListData, e no o atributo listData. Isso essencial
porque, do contrrio, no haveria chamada ao mtodo OnPro-
pertyChanged() (pois no seria a propriedade que mudaria) e o
listBox da View no seria atualizado.
Realizando o Data Binding com a View do WPF
Finalmente, a hora de realizar o to falado Data Binding entre
a MainWindowViewModel e a View. Para tanto, so necessrios
alguns elementos. O primeiro e principal deles: preciso refe-
renciar o namespace dos ViewModels no cdigo XAML. Com
isso, possvel referenciar qualquer uma das classes (no caso, as
ViewModels) dentro do cdigo da janela. A partir disso, pre-
ciso definir um recurso que ser utilizado por toda a janela da
aplicao. Ou seja, esse recurso ser definido localmente, e ser
simplesmente a classe MainWindowViewModel. Ele declarado
como recurso porque contm uma srie de elementos que foram
criados especialmente para a View ter acesso aos dados dos mo-
delos. Por fim, preciso definir os controles que recebero esses
dados, e faro tambm a sua atualizao, mas vamos por etapas.
A Listagem 10 mostra a importao do namespace e definio
do recurso MainWindowViewModel. O namespace foi rotulado
como vm, e o recurso, vmMainWindow.
Listagem 9. Comando Add
01 public RelayCommand AddCommand
02 {
03 get
04 {
05 if (addCommand == null)
06 {
07 addCommand = new RelayCommand(param => this.Add());
08 }
09 return addCommand;
10 }
11 }
12 public void Add()
13 {
14 cData.Add(newCustomer);
15 ListData = cData.List();
16 }
Listagem 10. Cdigo inicial da View
01 <Window x:Class=DadosEmWPFArtigo.MainWindow
02 xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
03 xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
04 xmlns:vm=clr-namespace:DadosEmWPFArtigo.ViewModels
05 Title=MainWindow Height=350Width=525>
06 <Window.Resources>
07 <vm:MainWindowViewModel x:Key=vmMainWindow/>
08 </Window.Resources>
09 <Grid DataContext={StaticResource vmMainWindow}>
Listagem 8. Atributos e Construtor da classe MainWindowsViewModel
01 class MainWindowViewModel : ViewModelBase
02 {
03 private CustomerData cData;
04 private RelayCommand addCommand;
05 private RelayCommand updateCommand;
06 private RelayCommand delCommand;
07 private Customer currentCustomer;
08 private Customer newCustomer;
09
10 public MainWindowViewModel()
11 {
12 cData = new CustomerData();
13 }
14 ...
15 }
Data Binding em WPF: interagindo com o banco de dados Data Binding em WPF: interagindo com o banco de dados
Edio 110 .Net Magazine 33
Agora que h uma definio com relao ao recurso a ser utili-
zado, interessante preparar a interface. Trata-se de uma interface
bastante simples, dividida, basicamente, em trs partes: uma com
os campos para adio de novos consumidores, uma com os cam-
pos para atualizao e excluso dos mesmos e outra com o listBox
que contm todos os consumidores do banco de dados. A Figura 3
mostra como ficou a interface, ainda sem nenhum dado. Repare
que, como no h nenhum dado, o listBox direita se encontra
totalmente vazio. interessante ressaltar um detalhe com rela-
o Listagem 10. Na ltima linha, definido um DataContext
para o Grid. Os controles WPF possuem a capacidade de herdar
propriedades de seus pais. Com isso, todos os controles filhos
do Grid que no possurem uma definio de DataContext iro
procurar, e encontrar essa definio, no prprio GridView.
Figura 3. UI sem Data Binding
A primeira ao a ser realizada garantir que o listBox ir
receber os dados referentes do banco. Ou seja, realizar um
DataBinding com a propriedade ListData, da MainWindow-
ViewModel. Como se trata de um listBox, a propriedade que
deve ser setada com esse binding a propriedade que contm
a fonte dos itens, ou ItemsSource. Essa propriedade foi defini-
da, conforme a Listagem 11. Como observvel nessa mesma
listagem, a propriedade DisplayMemberPath foi definida para
mostrar o nome do consumidor no listBox. Caso essa proprie-
dade no fosse definida, ele chamaria o mtodo ToString()
da classe Customer, o que no aconselhvel, pois mostraria
uma sada mais ou menos como mostra a Figura 4. O mtodo
ToString() poderia ser sobrescrito, porm essa no uma pr-
tica recomendada de programao. Caso o interessante seja
mostrar algo mais elaborado no listBox, recomendado o uso
de DataTemplates (BOX 6).
Agora que o listBox j est habilitado para mostrar os objetos
Customer, necessrio criar meios de adio, atualizao e ex-
cluso desses mesmos objetos atravs do XAML. Para isso, sero
utilizados os vrios textBoxes criados esquerda da interface de
usurio. Para tanto, necessria a realizao de uma DataBinding.
Para a adio, essa ligao realizada com a propriedade NewCus-
tomer, que enviado juntamente com o comando de adio para
ser adicionado ao banco de dados. Como visvel na Listagem 12,
trata-se de um binding de modo OneWayToSource. Isso realizado
dessa forma, pois no h nenhuma necessidade de os textBoxes
receberem de volta os dados que esto sendo enviados para o
banco de dados. interessante ressaltar tambm o binding adi-
cionado ao comando do boto, pois ele ir simplesmente realizar
uma chamada e executar o comando de adio definido na
ViewModel.
Porm, com isso ainda existem alguns textBoxes sem utilizao.
Eles sero utilizados para realizar a atualizao de dados do
banco. Os trs recebero os dados do item selecionado no listBox,
sendo responsveis pela atualizao do mesmo quando houver
mudanas. O cdigo se assemelha muito quele verificado para a
adio de um novo consumidor, com algumas diferenas bsicas.
Ao invs de realizar a ligao com a propriedade NewCustomer,
ele liga os dados com a propriedade CurrentCustomer. Alm disso,
esse novo binding utiliza uma propriedade diferente, chamada
UpdateSourceTrigger, nesse caso o evento PropertyChanged. Esse
gatilho utilizado cada vez que a propriedade alterada, e fun-
ciona para garantir que o valor ser atualizado quando alterado.
Figura 4. Sada sem definio da propriedade a ser mostrada
Templates de dados so utilizados para mostrar dados de um jeito particular. Basicamente, eles so
utilizados juntamente com objetos complexos, ou seja, objetos que possuem vrias propriedades
bsicas, como os Customers que foram criados nesse artigo. No caso, possvel mostrar em listBoxes,
comboBoxes e controles similares vrios tipos de itens de uma maneira particular,definida no prprio
template. Como um exemplo, com o advento desses templates, possvel para o desenvolvedor
mostrar Nome, Endereo e Telefone dos consumidores de uma forma organizada e rica. um dos
principais diferenciais do WPF para criao de interfaces de usurio ricas.
BOX 6. DataTemplates
Listagem 11. Cdigo do ListBox
<ListBox Grid.Column=1 Grid.Row=0 Grid.RowSpan=18
ItemsSource={Binding Path=ListData, Mode=OneWay}
DisplayMemberPath=Name Name=lstDados/>
Data Binding em WPF: interagindo com o banco de dados Data Binding em WPF: interagindo com o banco de dados
34 .Net Magazine Edio 110
J o comando de excluso chamado atravs do boto Delete, que
responsvel por chamar o comando atravs do mecanismo de
binding e excluir a linha correspondente ao CurrentCustomer no
banco. Por fim, a Figura 5 mostra o resultado desses DataBindings
na interface com o usurio. Por questes de simplificao, o cdigo
XAML desses textBoxes foram omitidos desse artigo, mas o leitor
pode ter acesso ao cdigo completo da aplicao, na pgina de
download da revista, no portal DevMedia.
O MVVM um padro de design que foi criado principalmente
para criao de aplicaes WPF e Silverlight. Isso porque, na poca,
eram as duas tecnologias permeadas pelo XAML. Hoje em dia,
h outras tecnologias que utilizam o poder dessa linguagem de
marcao e, por isso, o MVVM se aplica a elas tambm. Realizando
uma citao, aplicaes para Windows Phone e Windows Store
utilizam essa linguagem para criao de interfaces com o usurio.
Alm do MVVM, outros padres podem ser utilizados tranqui-
lamente para criao de aplicaes empresariais, como MVP ou
MVC. Todos eles possuem suas particularidades, vantagens e
desvantagens. A principal vantagem na abordagem com MVVM
que ele foi criado para ser utilizado com o WPF, sendo, portanto,
o melhor meio de tirar vantagem dos poderes dessa tecnologia.
Por fim, a questo do acesso a dados tambm poderia ter sido
realizada de outra forma. A escolha por LINQ to SQL se deu pelo
fato de ser uma tecnologia do .NET framework que simplificou
muito as coisas para o acesso e consulta a dados. O principal poder
da tecnologia LINQ so suas consultas a dados, que podem ser
feitas de vrias formas. Alm disso, a LINQ oferece uma forma
interessante, simples e intuitiva de representar dados no forma-
to de classes de dados, o que encaixa perfeitamente no modelo
MVVM para aplicaes WPF, como foi visto ao longo do artigo.
Figura 5. UI concluda
Listagem 12. DataBinding para adio de Customers
01 <TextBlock Text=Nome: Grid.Row=0
Grid.Column=0/>
02 <TextBox Text={Binding Path=NewCustomer.Name,
Mode=OneWayToSource}
03 Grid.Row=1 Grid.Column=0/>
04 <TextBlock Text=Endereo: Grid.Row=2
Grid.Column=0/>
06 <TextBox Text={Binding Path=NewCustomer.Endereco,
Mode=OneWayToSource}
06 Grid.Row=3 Grid.Column=0/>
08 <TextBlock Text=CPF: Grid.Row=4 Grid.Column=0/>
09 <TextBox Text={Binding Path=NewCustomer.Cpf,
Mode=OneWayToSource}
10 Grid.Row=5 Grid.Column=0/>
11 <Button Content=Add Grid.Column=0 Grid.Row=6
Grid.RowSpan=2
12 Command={Binding Path=AddCommand}/>
Concluso
Esse artigo trouxe uma nova abordagem a respeito de Data Bin-
ding em WPF. Alm disso, trouxe uma srie de conceitos, tericos
e prticos, a respeito de MVVM, que no possui muita literatura a
respeito, e a respeito de LINQ to SQL, com a criao de um banco
de dados puramente em classes do C#. So ferramentas muito
poderosas, que podem ser utilizadas juntas ou separadamente,
trazendo uma excelente forma de trabalhar com dados em apli-
caes WPF.
Henrique Machado Gasparotto
hmgasparotto@hotmail.com
Estudante de Engenharia de Computao na Universidade Federal
de Santa Maria UFSM e Tcnico em Informtica pelo SENAC
Santa Maria. Experincia em programao C# .NET e Java. Atualmente,
trabalha como bolsista no Laboratrio de Computao para Clima Espacial
no Centro Regional Sul de Pesquisas Espaciais (LCCE/CRS/INPE), com atividades voltadas
computao de alto desempenho.
Autor
Links e Referncias:
LINQ to SQL: .NET Language-Integrated Query for Relational Data
http://msdn.microsoft.com/en-us/library/bb425822.aspx
Entendendo o pattern Model-View-ViewModel (MVVM)
http://imasters.com.br/artigo/18900/desenvolvimento/entendendo-o-pattern-model-view-
viewmodel-mvvm/
Data Binding (WPF)
http://msdn.microsoft.com/en-us/library/ms750612(v=vs.110).aspx
D seu voto em www.devmedia.com.br/netmagazine/feedback
Ajude-nos a manter a qualidade da revista!
Voc gostou deste artigo?
Data Binding em WPF: interagindo com o banco de dados Data Binding em WPF: interagindo com o banco de dados
Edio 110 .Net Magazine 35
Integration Services2012: implementando solues de ETL - Parte 1
36 .Net Magazine Edio 110
Porque esse artigo til::
Este artigo tem por finalidade apresentar o SQL Server Integration
Services 2012 e de que maneira este servio (que parte integrante
do SQL Server) pode ser til na integrao entre diferentes aplicaes.
Combinando recursos do .NET Framework a funcionalidades para a
manipulao de bases relacionais, XML e outros formatos para a repre-
sentao de informaes, esta ferramenta permite a implementao
dos mais variados tipos de solues voltadas ao gerenciamentos de
dados. A implementao de projetos baseados no Integration Services
acontece atravs do Visual Studio, sendo que demonstraremos isto
atravs de dois exemplos (o primeiro envolvendo a exportao de
informaes, ao passo que um segundo exemplo descreve de que ma-
neira informaes podem ser carregadas em uma base de dados).
Resumo DevMan
Integration Services2012:
implementando solues
de ETL - Parte 1
ESTE ARTIGO FAZ PARTE DE UM CURSO
Construindo solues para a integrao entre
sistemas
A
necessidade de implementao de projetos en-
volvendo a integrao de diferentes sistemas
algo extremamente comum nos dias atuais. As
solues resultantes podem se basear tanto no compar-
tilhamento de dados em tempo real atravs do uso de
Web Services, quanto na transferncia em lotes e num
horrio especfico de informaes que partam de uma
origem para um determinado repositrio de destino.
Embora Web Services representem um meio rpido
e instantneo para a troca de dados entre aplicaes,
o comum que a utilizao destes componentes esteja
restrita a contextos caracterizados por um trfego menor
de informaes. Por outro lado, grandes quantidades
de dados so geralmente manipuladas por softwares
executados dentro de intervalos de tempo pr-definidos,
de forma a no comprometer com isto a performance na
utilizao de um ou mais sistemas.
No caso especfico desta segunda alternativa, as rotinas
responsveis por essas tarefas de integrao costumam
ser implementadas empregando as mais variadas tec-
nologias. bastante comum que tais solues possuam
um cdigo extenso e complexo, dificultando no apenas
a sua manuteno, como tambm o entendimento do
processo como um todo. A inexistncia de uma docu-
mentao que detalhe o fluxo das diferentes atividades
realizadas durante o processamento s vem agravar esta
situao, no sendo raro que modificaes em aplicaes
deste tipo produzam efeitos indesejveis e exijam esfor-
os posteriores na correo de problemas.
O SQL Server Integration Services (SSIS) representa a soluo
oferecida pela Microsoft para atender a esses cenrios de integra-
o. Combinando a utilizao de tecnologias heterogneas para
a manipulao de dados (tais como bancos de dados relacionais,
XML, arquivos texto, planilhas do Excel, dentre outras alternati-
vas) a recursos do .NET Framework, esta ferramenta possibilita
a construo de aplicaes capazes de se comportar de uma
forma robusta e escalvel (BOX 1) diante de grandes volumes de
informaes.
Outro ponto que pesa a favor do uso do Integration Services
est na construo de projetos a partir da modelagem grfica
de fluxos divididos em tarefas. Isto contribui para tornar mais
simples o desenvolvimento de novas aplicaes, evitando assim a
implementao de extensos trechos de cdigo que coordenem as
interaes entre atividades. O entendimento de como uma soluo
do Integration Services funciona tambm se torna mais intuitivo,
Integration Services2012: implementando solues de ETL - Parte 1
Edio 110 .Net Magazine 37
caracterstica esta que facilita o aprendizado desta ferramenta
por parte de desenvolvedores que no estejam familiarizados
com a mesma.
A meta da primeira parte deste artigo apresentar as principais
caractersticas do Integration Services e de que maneira esta fer-
ramenta pode ser til na integrao entre sistemas. Para isto ser
apresentada uma aplicao que aborda a exportao de dados de
uma base relacional, gerando como resultado arquivos no formato
.csv. Numa prxima edio demonstraremos o processo inverso,
com a importao de informaes para um banco de dados a partir
de arquivos em diferentes formatos.
O conceito de escalabilidade refere-se capacidade de um sistema se adequar a uma demanda
crescente no seu uso, sem que com isto deixe de corresponder ao que se esperava inicialmente para
o mesmo.
BOX 1. Escalabilidade
SQL Server Integration Services: uma viso geral
O SQL Server Integration Services pode ser considerado uma
evoluo de outra ferramenta de ETL (BOX 2) da Microsoft: trata-
se do Data Transformation Services (DTS), que foi disponibilizado
quando do lanamento da verso 7 do SQL Server. J a primeira
verso daquilo que atualmente se conhece como Integration Ser-
vices surgiu com o SQL Server 2005.
Desde ento, cada novo release do SQL Server vem acompa-
nhado por avanos no que se refere aos recursos oferecidos pelo
Integration Services. Na verso 2012 isto no foi diferente, com
melhorias em questes como a configurao e o deployment
de solues, monitoramento de aplicaes e resoluo de pro-
blemas, mecanismos que possibilitam uma maior qualidade
em transformaes de dados, dentre outros aspectos. Uma
relao completa dos novos recursos do Integration Services
pode ser encontrada num dos endereos listados na seo de
Links deste artigo.
O processo conhecido como ETL (sigla do ingls Extraction, Transformation and Load) funciona,
em termos gerais, da seguinte forma: a partir de um repositrio de origem sero extrados dados,
com os mesmos sendo transformados seguindo critrios especficos a um determinado contexto.
Por fim, tais dados sero carregados numa base de destino. Solues prprias de ETL podem vir a ser
desenvolvidas, muito embora existam ferramentas prticas e bastante flexveis como o SQL Server
Integration Services.
BOX 2. ETL
Do ponto de vista arquitetural, uma aplicao do Integration
Services constituda por um ou mais packages (pacotes). J um
package formado por tasks (tarefas) que seguem geralmente
um fluxo de execuo contnuo. A implementao de um pacote
feita por meio do Visual Studio, atravs da modelagem grfica
de um fluxo com as tarefas que iro compor o mesmo; essa ltima
caracterstica torna a construes de solues para o Integration
Services um processo intuitivo e, portanto, mais fcil de ser as-
similado por desenvolvedores que comeam a ter os primeiros
contatos com esta ferramenta.
Na prtica, um package nada mais do que um arquivo XML
com a extenso .dtsx, podendo combinar instrues para o aces-
so a bancos de dados, arquivos e outros tipos de repositrios a
trechos de cdigo baseados em recursos da plataforma .NET.
No caso especfico da verso 2012, o SQL Server conta com o su-
porte para bibliotecas geradas sob do .NET Framework 4.0, sendo
que essa caracterstica se estende ao Integration Services.
Packages podem acessar repositrios de dados dos mais varia-
dos tipos:
Bases de dados relacionais que suportem drivers ODBC, OLE
DB e ADO.NET;
Bases multidimensionais mantidas atravs da ferramenta Analy-
sis Services (BOX 3);
Arquivos de texto;
Planilhas do Excel;
Web Services.
O Analysis Services um servio que integra o SQL Server, sendo utilizado na construo de
aplicaes baseadas em conceitos de Business Intelligence. Esta ferramenta viabiliza a realizao de
sofisticadas anlises, as quais normalmente servem de suporte para a tomada de decises no meio
corporativo. Isto acontece atravs da implementao de bases histricas alimentadas a partir de
bancos de dados transacionais, sendo que tais repositrios costumam ser modelados de uma forma
multidimensional (empregando para isto estruturas como cubos e dimenses).
BOX 3. Analysis Services
Quanto sua forma de execuo, packages podem ser acionados
das seguintes maneiras:
A partir de uma aplicao .NET que tenha acesso ao diretrio
em que se encontra um determinado package;
Remotamente, atravs de instrues .NET para se acessar um
package previamente instalado num servidor SQL Server.
Maiores detalhes a respeito do funcionamento e da implemen-
tao de packages do Integration Services sero abordados mais
adiante nos exemplos prticos deste artigo.
Possveis cenrios de utilizao do Integration Services
Graas sua flexibilidade e ao suporte no acesso a diferentes
repositrios de dados, diversos so os cenrios em que o Inte-
gration Services poder ser empregado. A seguir esto listadas
algumas das possibilidades de uso desta ferramenta:
Na replicao de informaes entre diferentes bases de
dados;
Na integrao entre sistemas fiscais/contbeis e rgos
governamentais, sendo possvel destacar iniciativas como o
SPED (sigla de Sistema Pblico de Escriturao Digital). Este
ltimo um projeto do governo federal que procura automa-
tizar o recebimento de informaes relativas a Livros Fiscais,
Contbeis e de PIS / COFINS mantidos por organizaes dos
mais variados segmentos;
Integration Services2012: implementando solues de ETL - Parte 1 Integration Services2012: implementando solues de ETL - Parte 1
38 .Net Magazine Edio 110
Em processos de ETL, os quais normalmente esto associados
produo de dados para a gerao de complexas anlises em
solues de BI (BOX 4);
Na exportao de dados sob a forma de arquivos, em situaes
que geralmente envolvem a integrao entre um sistema de ori-
gem e outras aplicaes. Exemplos disso a gerao de listas de
preo disponibilizadas por um fornecedor ou fabricante de um
conjunto de produtos, o envio de informaes para cobrana ban-
cria utilizando o padro conhecido como CNAB, dentre outros
processos relacionados ao compartilhamento de dados.
BI (sigla em ingls para Business Intelligence; termo tambm conhecido como Inteligncia
Empresarial) um conjunto de tcnicas que envolvem a coleta, o processamento e a gerao de
informaes a partir de dados gerados em operaes cotidianas de uma organizao. Este tipo de
procedimento busca, a partir de tais prticas, prover anlises que auxiliem profissionais de gesto
em atividades relacionadas tomada de decises.
BOX 4. Business Intelligence
Exemplos de solues utilizando o Integration Services
A fim de demonstrar como o SQL Server Integration Services
2012 pode ser utilizado, sero criadas quatro solues no Microsoft
Visual Studio 2012 Professional:
TesteIntegration01: solution em que constar um projeto do Inte-
gration Services para a exportao de informaes de produtos sob
a forma de arquivos .csv. Existiro ainda nesta soluo trs projetos
do tipo Console Application, sendo que os mesmos apresentam
diferentes maneiras de se executar um package do Integration
Services por meio de recursos da plataforma .NET;
TesteIntegration02: nesta soluo ser demonstrada a importao
de arquivos .csv, .xlsx e .txt a partir de aplicaes do Integration
Services. Ser criado para isto um projeto em que sero carregadas
informaes sobre notas fiscais que envolvam o pagamento de
servios contratados por uma empresa hipottica.
Antes de iniciar a implementao destas Solutions, ser necess-
rio instalar o pacote Microsoft SQL Server Data Tools - Business
Intelligence for Visual Studio 2012 (caso este procedimento
ainda no tenha sido realizado anteriormente). Essa extenso
responsvel por ativar dentro do Visual Studio 2012 templates
que permitem a construes de solues baseadas no Integration
Services, Analysis Services e Reporting Services (BOX 5).
Implementando o primeiro exemplo
Conforme j discutido na parte inicial deste artigo, arquivos
ainda representam um dos principais meios para o comparti-
lhamento de informaes entre sistemas. Muitas organizaes
investem pesado na automao de processos que envolvam a
transferncia de informaes, construindo assim solues que
permitem a manipulao de grandes volumes de informaes
em formatos padronizados.
Neste primeiro exemplo estaremos implementando uma soluo
chamada TesteIntegration01, a qual ser responsvel pela gerao
de um arquivo CSV (BOX 6) contendo o catlogo de uma distri-
buidora de produtos alimentcios fictcia. O arquivo em questo
no possuir cabealho, sendo formado pelos seguintes campos
(estes j na sequncia esperada, devendo ainda estar separados
por ponto-e-vrgula):
Cdigo do produto;
Nome do produto;
Categoria;
Fornecedor;
Preo Unitrio.
O Reporting Services uma soluo da Microsoft para a criao e o gerenciamento de relatrios no
ambiente corporativo. Trata-se de uma ferramenta extremamente flexvel, que possibilita inclusive
a exportao de relatrios para formatos como planilhas do Excel e documentos PDF. Muito embora
corresponda a mais um dos servios que compem o SQL Server, o Reporting Services tambm pode
ser empregado na produo de relatrios que acessem outras bases relacionais (como Oracle, por
exemplo), bancos multidimensionais do Analysis Services ou, at mesmo, fontes de dados como XML
e Web Services.
BOX 5. Reporting Services
CSV (sigla do ingls Comma-separated values) um padro para a representao de dados em
um formato tabular. Arquivos deste tipo possuem a extenso .csv e, em termos prticos, nada mais
so do que sequncias de texto separadas por um caracter especial (o mais comum que se utilize
vrgula ou ponto-e-vrgula em tais representaes). O uso de arquivos .csv para a integrao entre
diferentes sistema corresponde a um tipo de prtica bastante comum, sendo que o prprio pacote
Office (por meio do Excel) oferece suporte a este tipo de formato.
BOX 6. Arquivos CSV
Na seo de Links desse artigo possvel encontrar o endereo para download da extenso
Microsoft SQL Server Data Tools - Business Intelligence for Visual Studio 2012.
Nota
No caso especfico dos campos Nome do Produto, Categoria
e Fornecedor, as informaes associadas aos mesmos sero
sequncias de texto com todos os caracteres em maisculo. J o
campo Preo Unitrio ser um valor numrico com duas casas
decimais (estas ltimas separadas por vrgula), ao passo que a co-
luna Cdigo do Produto corresponder a um nmero inteiro.
Eventuais clientes desta companhia receberiam tal catlogo,
com o preo de comercializao sugerido para cada item. A base
que fornecer essas informaes o banco de dados Northwind,
com que pode ser obtido a partir de um endereo listado na seo
de Links deste artigo.
A Solution TesteIntegration01 ser formada pelos seguintes
projetos:
TesteIntegration01.SSIS: aplicao baseada no Integration Servi-
ces e na qual acontecer a gerao do arquivo CSV com os dados
do catlogo de produtos;
TesteIntegration01.ExecucaoLocalPackage: Console Application
em que ser demonstrada a execuo de um package localizado
em um determinado diretrio;
Integration Services2012: implementando solues de ETL - Parte 1 Integration Services2012: implementando solues de ETL - Parte 1
Edio 110 .Net Magazine 39
TesteIntegration01.ExecucaoRemotaPackage: outro projeto do
tipo Console Application, sendo que esta aplicao apresentar
como executar via .NET Framework um package previamente
instalado num servidor SQL Server;
TesteIntegration01.ExecucaoRemotaJob: neste ltimo projeto
(tambm uma Console Application) ser demonstrado como
acionar um Job do SQL Server que executa uma aplicao do
Integration Services.
O projeto TesteIntegration01.SSIS ser gerado a partir do
template Integration Services Project (Figura 1), o qual habi-
litado aps a instalao da extenso Microsoft SQL Server Data
Tools - Business Intelligence for Visual Studio 2012.
O prximo passo agora consistir na criao do package
GeracaoCSVProdutos.dtsx (Figura 2), removendo ainda o arquivo
Package.dtsx (que foi gerado automaticamente ao se executar a
etapa anterior).
Figura 1. Criando o projeto TesteIntegration01.SSIS
Figura 2. Criando o package GeracaoCSVProdutos.dtsx
Neste momento j ser possvel iniciar a implementao da apli-
cao para a exportao de informaes sobre produtos. Conforme
possvel observar na Figura 3, o package GeracaoCSVProdutos.
dtsx conta com as seguintes sees:
Control Flow: corresponde ao centro nervoso de um pacote no
Integration Services. neste local em que acontece a orquestrao das
diferentes tarefas (tasks) definidas para um package, seguindo para
isto um fluxo de execuo que obedece a uma sequncia lgica;
Data Flow: o principal tipo de funcionalidade oferecido pelo
Integration Services consiste na extrao de dados de um local
de origem, alguma forma de processamento produzindo um tipo
especfico de informao e, finalmente, a transferncia disto para
um ponto de destino que pode ser um banco de dados relacional
ou, mesmo, um arquivo que faa uso de um padro especfico de
representao (XML, planilhas do Excel, CSV, texto com posies
delimitadas, etc.). Conjuntos de instrues definidos nesta seo
so executados atravs de tarefas acionadas dentro do fluxo prin-
cipal (Control Flow) de um package;
Figura 3. O package GeracaoCSVProdutos.dtsx ainda no implementado
Parameters: aqui so declarados itens de configurao (BOX 7)
que servem de base para a execuo de um package;
Event Handlers: permite a implementao de rotinas (Event
Handlers) para o tratamento de eventos que ocorram ao longo do
processamento de um package. possvel tambm a definio de
rotinas em resposta a eventos que associados a elementos espec-
ficos de um package. Quanto utilizao de estruturas desse tipo,
comum que Event Handlers sejam implementados em tarefas
que envolvam tarefas como logging e tratamento de erros;
Package Explorer: neste local possvel a visualizao e o acesso
a todos os elementos definidos dentro de um package;
Connection Managers: itens declarados nesta seo possibi-
litam a conexo de elementos de um package a repositrios de
dados como bases relacionais e/ou arquivos dos mais variados
tipos.
As estruturas conhecidas como Parameters (parmetros) passaram a fazer parte do Integration
Services com o lanamento do SQL Server 2012. Em termos prticos, um parmetro nada mais
do que uma configurao formada por um identificador, alm de um valor previamente definido.
Importante destacar que tal valor no sofre alterao durante o processamento da aplicao que
se est considerando.
Tambm merece destaque o fato de que este recurso surgiu com o intuito de simplificar o
gerenciamento de configuraes para aplicaes do Integration Services, algo que em verses
anteriores era feito por meio do uso de arquivos no formato XML.
Todo parmetro criado com base em um tipo de dado especfico. Atualmente, esses itens podem
ser declarados com base nos tipos: Boolean, Byte, DateTime, Decimal, Double, Int16, Int32, Int64,
SByte, Single, String, UInt32 e UInt64.
Quanto ao escopo de execuo, parmetros podem ser definidos de forma global (acessveis,
portanto, a todos os packages de um projeto), ou ainda, dentro de um package especfico (sendo
utilizados neste ltimo caso apenas por elementos que constem nessa estrutura).
BOX 7. Parmetros no Integration Services 2012
Integration Services2012: implementando solues de ETL - Parte 1 Integration Services2012: implementando solues de ETL - Parte 1
40 .Net Magazine Edio 110
No caso do package GeracaoCSVProdutos.dtsx, estaremos
definindo um parmetro do tipo String chamado pCaminho-
GeracaoArquivosCSV (Figura 4). Esta configurao indicar o
caminho no qual sero gerados os arquivos .csv contendo o cat-
logo de produtos (num primeiro momento, partiu-se da premissa
que existir o caminho C:\Devmedia\TesteVisualStudio\ na
mquina em que a aplicao de exemplo for executada).
A interao entre as diferentes tarefas definidas em um pa-
ckage possvel graas ao uso de variveis (BOX 8). Para o pa-
ckage GeracaoCSVProdutos.dtsx, estar sendo criada a varivel
vNomeArquivoCSV (Figura 5). Embora preenchida com o valor
C:\Devmedia\TesteVisualStudio\Produtos.csv (para efeitos de
configurao dentro do Visual Studio), esta referncia do tipo
String ter o seu valor gerado dinamicamente, armazenando o
nome completo para o arquivo de produtos que ser criado duran-
te a execuo do pacote GeracaoCSVProdutos.dtsx. Alm disso,
possuir um escopo que a torna acessvel a todos os elementos
deste package.
Figura 4. Criando o parmetro pCaminhoGeracaoArquivosCSV
Figura 5. Criando a varivel vNomeArquivoCSV
Dentro do Visual Studio, a janela para definio de variveis pode ser acessada atravs do menu
SSIS, opo Variables.
Nota
Variveis so elementos que auxiliam na manipulao de dados e na comunicao entre as diferentes
tasks que compem um package do Integration Services.
Assim como acontece nas linguagens de programao convencionais, uma varivel possui um
identificador e armazena um valor baseado em um tipo de dado especfico. Para este tipo de
estrutura, o Integration Services disponibiliza os seguintes tipos de dados: Boolean, Byte, Char,
DateTime, DBNull, Decimal, Double, Int16, Int32, Int64, Object, SByte, Single, String, UInt32 e UInt64.
Diferentemente daquilo que acontece com parmetros, os valores associados variveis podem ser
modificados em tempo de execuo. Graas a esta caracterstica, variveis representam a alternativa
ideal para a manipulao de dados em cenrios com um comportamento mais dinmico, tais como
loopings sobre colees de valores, desvios condicionais e construes de cdigo .NET que envolvam
a produo de novos valores a partir de dados pr-existentes.
Variveis tambm possuem um escopo. Ao criar um novo item deste tipo, possvel definir que
tal elemento estar disponvel a todos os elementos de um package ou, at mesmo, apenas para
conjuntos de elementos especficos.
BOX 8. Variveis no Integration Services
Duas conexes tambm devero ser criadas a partir da seo
Connection Managers.
A primeira destas conexes (chamada connNorthwind) faz uso
do ADO.NET como mecanismo de acesso a dados, permitindo a
execuo de consultas base Northwind (Figura 6). justamente
este o repositrio de onde sero obtidas as informaes para a
gerao do arquivo com a listagem de produtos.
J a conexo connArquivoCSVProdutos ser empregada na gra-
vao de novos arquivos .csv contendo o catlogo de produtos.
Figura 6. Configuraes da conexo connNorthwind
A conexo connNorthwind foi criada a partir da opo New ADO.NET Connection..., a qual est
disponvel atravs do menu de atalho da seo Connection Managers.
Nota
A conexo connArquivoCSVProdutos foi gerada atravs da opo New Flat File Connection..., que
tambm est localizada no menu de atalho da seo Connection Managers.
Nota
Na Figura 7 esto algumas das configuraes necessrias para
a gerao do arquivo .csv. Esses ajustes foram efetuados dentro
da seo General na janela Flat File Connection Manager
Editor:
No campo Connection manager name foi informado o valor
connArquivoCSVProdutos, ao passo que em Description est
um comentrio que descreve a finalidade desta nova conexo;
O campo File name foi preenchido com um caminho que apon-
ta para um novo arquivo .csv a ser criado durante o processamento
do package GeracaoCSVProdutos.dtsx (apenas para efeito de
Integration Services2012: implementando solues de ETL - Parte 1 Integration Services2012: implementando solues de ETL - Parte 1
Edio 110 .Net Magazine 41
configurao da conexo connArquivoCSVProdutos). Embora
com um contedo fixo, este valor ser gerado posteriormente de
forma dinmica (por meio da varivel vNomeArquivoCSV);
O item Locale foi configurado de maneira que a criao
do arquivo .csv acontea em conformidade com os padres de
formatao regionais adotados no Brasil;
J no campo Format foi marcada a opo Delimited, que indica
a gerao de um arquivo delimitado por um separador (caracte-
rstica tpica do formato CSV);
O elemento Header row delimiter determina o conjunto de
caracteres empregado na quebra de linhas em um arquivo;
Por fim, a opo Column names in the first row desmarcada
far com que o arquivo .csv seja criado sem um cabealho.
Figura 7. Configurando a conexo connArquivoCSVProdutos
Na seo Columns foi selecionada a opo Semicolon {;} para
o campo Column delimiter (Figura 8). Com essa configurao
determinamos que todos os valores do arquivo .csv estaro se-
parados por ponto e vrgula.
Na Tabela 1 esto as configuraes para cada uma das colunas
que faro parte do arquivo .csv contendo o catlogo de produtos.
Estes itens devero ser preenchidos na seo Advanced da janela
Flat File Connection Manager Editor (Figura 9).
Figura 8. Definindo o separador para as colunas na conexo connArquivoCSVProdutos
Name DataType OutputColumnWidth DataScale
CodProduto
four-byte signed integer
[DT_I4]
- -
NomeProduto string [DT_STR] 40 -
Categoria string [DT_STR] 15 -
Fornecedor string [DT_STR] 40 -
PrecoUnitario decimal [DT_DECIMAL] - 2
Tabela 1. Colunas a serem configuradas para a conexo connArquivoCSVProduto
Figura 9. Configurando as colunas para a conexo connArquivoCSVProdutos
Confirmadas as definies do arquivo .csv de produtos, ser
necessrio ainda um ltimo ajuste. Como a gerao do nome de tal
arquivo ocorre de forma automtica, a conexo connArquivoCS-
VProdutos precisar receber este valor (por meio da propriedade
ConnectionString), a fim de que o processo de gravao dos dados
acontea de maneira correta.
O Integration Services permite que os valores de expresses
baseadas em variveis e parmetros sejam atribudos ao contedo
de uma propriedade, com este processo acontecendo dinami-
camente durante a execuo da aplicao. Essa caracterstica
possvel graas a uma propriedade chamada Expressions, a qual
Integration Services2012: implementando solues de ETL - Parte 1 Integration Services2012: implementando solues de ETL - Parte 1
42 .Net Magazine Edio 110
pode conter uma coleo de expresses que vinculam os valores
correspondentes a outras propriedades de um componente.
Praticamente todos os controles disponveis para a implementao
de um package contam com a propriedade Expressions.
Na Figura 10 apresentada a janela a partir da qual acontece
o preenchimento da propriedade Expressions (nota-se que foi
selecionada a propriedade ConnectionString da conexo conn-
ArquivoCSVProdutos). Um assistente (no caso, a janela
Expression Builder) pode ser utilizado para a gerao de novas
expresses, combinando variveis, parmetros e funes para
manipulao de valores, conforme indicado na Figura 11.
Figura 10. Preenchendo a propriedade Expressions para a conexo connArquivoCSVProdutos
Figura 11. A janela Expression Builder
Figura 12. Expresso que preencher a propriedade ConnectionString
J na Figura 12 est a expresso responsvel pelo preenchimento
automtico da propriedade ConnectionString da conexo conn-
ArquivoCSVProdutos (atravs da varivel vNomeArquivoCSV).
Concludo o processo de gerao das conexes, iniciaremos agora
a configurao das diferentes tarefas que faro parte do package
GeracaoCSVProdutos.dtsx. Este procedimento acontecer a partir
da seo Control Flow.
Para acessar a propriedade Expressions de um controle, utilize a janela Properties do Visual Studio.
Nota
Conforme mencionado anteriormente, o fluxo principal que
define um package formado por uma sucesso de tarefas (tasks).
Outros elementos conhecidos como containers permitem o agru-
pamento lgico de uma srie de tarefas, alm de disponibilizar
informaes para a realizao de aes especficas.
Na Figura 13 apresentada a janela Toolbox com alguns dos
controles que podem vir a ser empregados na construo do flu-
xo principal de um pacote. Outros tipos de tasks (agrupadas na
seo Other Tasks) tambm esto disponveis para uso, sendo
possvel se obter um maior detalhamento sobre os mesmos a partir
da documentao online do Integration Services.
Figura 13. Principais tasks e containers para a construo de um package
Integration Services2012: implementando solues de ETL - Parte 1 Integration Services2012: implementando solues de ETL - Parte 1
Edio 110 .Net Magazine 43
Quantos s tasks que podem ser empregadas em packages do
Integration Services, merecem destaque os seguintes controles:
Data Flow Task: permite a obteno de dados de uma fonte de
origem, o seu processamento e, consequentemente, a gravao das
informaes produzidas em um repositrio de destino;
Execute SQL Task: possibilita a execuo de instrues SQL e
stored procedures a partir de uma base de dados relacional;
Analysis Services Processing Task: realiza o processamento de
alguma estrutura (cubos, dimenses, modelos de data mining)
definida no Analysis Services;
Bulk Insert Task: efetua o carregamento de dados em uma
tabela empregando para isto o comando BULK INSERT do SQL
Server (BOX 9);
Bulk Copy um tipo de operao empregada na transferncia de grandes volumes de informaes
para uma base relacional. O comum que aes desse gnero envolvam a carga de arquivos no
formato texto para tabelas de um banco de dados especfico. O SQL Server oferece total suporte a
operaes de Bulk Copy, disponibilizando para isto o comando BULK INSERT; no caso do ADO.NET, este
mecanismo de acesso a dados disponibiliza a classe SqlBulkCopy (namespace namespace System.
Data.SqlClient) para a implementao deste tipo de funcionalidade em aplicaes .NET.
BOX 9. Bulk Copy
Data Profiling Task: permite a execuo de anlises, a fim
de identificar potenciais problemas relativos qualidade dos
dados;
Execute Package Task: torna possvel a execuo de outro packa-
ge, a partir do pacote em que esta task for utilizada;
Execute Process Task: permite a execuo de programas externos
a um package, como acionar um utilitrio para compactao de
arquivos, por exemplo;
File System Task: possibilita a realizao de operaes envolven-
do diretrios (criar, renomear ou excluir uma pasta) e arquivos
(mover, copiar ou, at mesmo, excluir um arquivo);
FTP Task: tarefa utilizada no envio e/ou recebimento de arqui-
vos via FTP;
Script Task: graas a esta task possvel a codificao de scripts
em .NET para a realizao de uma ou mais aes especficas;
Send Mail Task: permite o envio de uma mensagem de e-mail,
fazendo uso para isto do protocolo SMTP;
Web Service Task: aciona um mtodo definido em um Web
Service;
XML Task: tarefa utilizada no processamento de documentos
XML.
Dos componentes citados, as tasks Data Flow Task, Execute SQL
Task e Script Task correspondem, basicamente, aos controles cuja
utilizao mais comum em solues baseadas no Integration
Services.
Dentre os containers disponibilizados pelo Integration Services,
podem ser mencionados os seguintes componentes:
For Loop Container: permite a repetio de um conjunto de
tasks dentro de um package. As sucessivas iteraes dentro
deste controle so controladas por expresses atribudas a uma
propriedade chamada EvalExpression;
Foreach Loop Container: assim como o controle For Loop
Container, este container permite a repetio de uma srie de
tarefas por meio de iteraes. A diferena est no fato de que o
componente Foreach Loop Container funciona de uma maneira
similar instruo foreach em .NET, efetuando iteraes sobre
um conjunto de registros retornados de uma base de dados ou,
at mesmo, em uma lista de arquivos localizados em um diretrio
especfico;
Sequence Container: permite o agrupamento lgico de um
conjunto de tarefas relacionadas.
Para o package GeracaoCSVProdutos.dtsx sero adicionadas
duas tasks, conforme listado na Tabela 2. Alterar a propriedade
Name destes controles com um valor sugestivo uma boa prtica:
eventuais erros durante a execuo do package GeracaoCSVPro-
dutos.dtsx a partir do SQL Server produziro informaes em
log; levando tal falto em considerao, uma clara identificao
do ponto em que ocorreu um problema facilitar na posterior
resoluo do mesmo.
Na Figura 14 possvel observar o fluxo principal do pacote
GeracaoCSVProdutos.dtsx, com as tasks que faro parte do mesmo
j adicionadas.
Tipo da Task Valor da propriedade Name
Script Task Script Task - Gerar nome do arquivo CSV
Data Flow Task Data Flow Task - Gerar arquivo CSV
Tabela 2. Tasks a serem adicionadas no package GeracaoCSVProdutos.dtsx
Figura 14. Fluxo principal do package GeracaoCSVProdutos.dtsx
O Script Task que foi adicionado ao package GeracaoCSV-
Produtos.dtsx ir receber o caminho associado ao parmetro
pCaminhoGeracaoArquivosCSV. A partir disso ser gerado
um novo nome para o arquivo .csv que conter o catlogo de
Integration Services2012: implementando solues de ETL - Parte 1 Integration Services2012: implementando solues de ETL - Parte 1
44 .Net Magazine Edio 110
produtos, com este valor sendo finalmente associado varivel
vNomeArquivoCSV.
A Figura 15 apresenta o componente Script Task devidamente
configurado. Sobre os itens preenchidos na janela Script Task
Editor, possvel destacar:
ScriptLanguage: indica a linguagem que ser empregada para a
implementao do cdigo associado ao controle Script Task. Alm
de C# (que estaremos utilizando neste exemplo), este componente
aceita ainda o uso de instrues escritas em VB.NET;
EntryPoint: indica o mtodo em .NET que ser executado quando
a task em questo for acionada. Por default criada uma operao
de nome Main, sendo este o ponto em que sero executadas as
instrues definidas para um controle Script Task;
ReadOnlyVariables: variveis ou parmetros que sero utiliza-
dos como parmetros de leitura. Caso se tente atribuir um valor
a algum dos itens informados nesta configurao, um erro ser
gerado em tempo de execuo;
ReadWriteVariables: neste local normalmente so definidas
variveis nas quais tambm ser possvel a atribuio de valores.
Os itens aqui definidos normalmente armazenam o resultado das
aes desencadeadas dentro do mtodo Main.
Para a codificao das aes que faro parte do controle Script
Task, acione a opo Edit Script. Uma tela como a que consta
na Figura 16 aparecer ento.
O cdigo que constar num componente Script far parte de
uma classe chamada ScriptMain, a qual baseada no tipo bsico
VSTARTScriptObjectModelBase (namespace Microsoft.SqlServer.
Dts.Tasks.ScriptTask). Essa ltima estrutura faz parte de um
mecanismo do .NET Framework conhecido como Visual Studio
Tools for Applications ou, simplesmente, VSTA (BOX 10). Dentro
do tipo ScriptMain existir, por sua vez, um mtodo Main, sendo
este o local em que acontecer as aes definidas para o controle
Script Task adicionado a um package.
recomendvel o uso de prefixos como p e v para identificar, respectivamente, parmetros e
variveis. Essa prtica ajuda a evitar equvocos durante a manipulao destes recursos em controles
do tipo Script Task.
Nota
Para se configurar uma task dentro do Visual Studio necessrio apenas clicar duas vezes com o
mouse sobre este controle. Uma janela ento aparecer, com os principais elementos que podero
ser preenchidos para este componente (como no caso do Script Task adicionado ao package
GeracaoCSVProdutos.dtsx).
Nota
O Visual Studio Tools for Applications (VSTA) um conjunto de ferramentas da plataforma .NET
que pode ser utilizado em solues dos mais variados tipos, de forma a permitir a customizao de
funcionalidades pr-existentes ou, at mesmo, possibilitar a estenso das capacidades oferecidas
por tais recursos. Surgido ainda com o Visual Studio 2005, justamente este o mecanismo que torna
possvel o uso de instrues em .NET dentro de solues do Integration Services.
BOX 10. Visual Studio Tools for Applications
Figura 15. Configurando o controle Script Task
Figura 16. Editando o cdigo de um controle Script Task
Na Listagem 1 est o cdigo esperado para o mtodo Main do
controle Script Task. Quanto implementao desta operao,
necessrio destacar:
O uso do objeto associado propriedade Dts (linhas 4, 6 e 10), o
qual representa uma instncia do tipo ScriptObjectModel (names-
pace Microsoft.SqlServer.Dts.Tasks.ScriptTask). Esta referncia
serve de base para a manipulao de variveis e parmetros,
com isso acontecendo atravs da propriedade Variables, alm de
indicar se a execuo do mtodo Main aconteceu com sucesso ou
no (por meio da propriedade TaskResult);
Na linha 3 o contedo definido para o parmetro pCaminho-
GeracaoArquivosCSV acessado, de forma a se determinar o
diretrio em que ocorrer a gravao do arquivo .csv com o
catlogo de produtos;
Integration Services2012: implementando solues de ETL - Parte 1 Integration Services2012: implementando solues de ETL - Parte 1
Edio 110 .Net Magazine 45
J na linha 6 a varivel vNomeArquivoCSV est sendo preen-
chida com o nome completo (incluindo diretrio) do arquivo com
informaes de produtos;
Por fim, o valor de enumeration ScriptResults.Success atribu-
do propriedade TaskResult do objeto Dts, indicando assim que
a execuo do cdigo definido para o controle Script Task teve
sucesso (no caso de uma eventual falha, seria utilizado o valor
ScriptResults.Failure).
Finalizada a configurao do componente Script Task, o ltimo
passo antes de se concluir a implementao do package Geracao-
CSVProdutos.dtsx ser a definio do fluxo associado ao controle
Data Flow Task (dentro da seo Data Flow). Ser a partir da
sequncia de aes configuradas nesta tarefa que acontecer a
leitura dos dados de produtos armazenados na base Northwind
e, finalmente, a gravao do catlogo sob a forma de um arquivo
com a extenso .csv.
O fluxo de dados definido para uma tarefa do tipo Data Flow
Task costuma envolver:
Uma fonte de origem (Source), de onde sero obtidos dados que
podem estar sujeitos a alguma forma de processamento;
O processamento de tais informaes, com provveis transfor-
maes (reformatao de valores, concatenao de dois ou mais
dados etc.);
Uma estrutura de destino (Destination) que receber os dados
j transformados. Bancos de dados relacionais e arquivos so
algumas das possibilidades para este caso especfico.
Para o exemplo que envolve a construo do package Geracao-
CSVProdutos.dtsx, estaro sendo utilizados apenas controles para
a manipulao de dados na origem e gravao num repositrio
de destino. Na prxima edio abordaremos alguns dos controles
que podero ser utilizados na transformao de dados.
Na Figura 17 possvel observar alguns dos controles dispo-
nveis para a configurao de um Data Flow Task. J a Tabela 3
apresenta alguns desses elementos, assim como a tecnologia
empregada pelos mesmos no processamento de informaes.
Ser preciso adicionar ao fluxo de dados do controle Data Flow
Task os controles listados na Tabela 4, modificando ainda o valor
da propriedade Name para esses itens.
Figura 17. Alguns dos controles utilizados na definio de um Data Flow
Listagem 1. Mtodo Main com as instrues para gerao de um novo nome de
arquivo
01 public void Main()
02 {
03 string nomeArquivoCSV =
04 Dts.Variables[pCaminhoGeracaoArquivosCSV].Value.ToString() +
05 Produtos_{0}.csv;
06 Dts.Variables[vNomeArquivoCSV].Value =
07 String.Format(nomeArquivoCSV,
08 DateTime.Now.ToString(yyyy-MM-dd_HHmmss));
09
10 Dts.TaskResult = (int)ScriptResults.Success;
11 }
Origem Destino Tecnologia empregada
ADO NET Source ADO NET Destination Drivers ADO.NET
Excel Source Excel Destination Planilhas do Microsoft Excel
Flat File Source Flat File Destination
Arquivos de texto (delimitados por
caracteres, posies fixas)
ODBC Source ODBC Destination Drivers ODBC
OLE DB Source OLE DB Destination Driver OLE DB
Raw File Source Raw File Destination Arquivos binrios
Tabela 3. Alguns dos controles disponveis para a implementao de um Data Flow
Na Figura 18 est a representao para o fluxo de dados que
resultar na gerao de um novo arquivo .csv contendo o catlogo
de produtos.
J as definies esperadas para o controle ADO NET Source
so apresentadas na Figura 19. A configurao da fonte de dados
requer o preenchimento dos seguintes itens na seo Connection
Manager da janela ADO.NET Source Editor:
ADO.NET connection manager: conexo do tipo ADO.NET
empregada no acesso a uma base de dados relacional (para este
exemplo ser a conexo connNorthwind criada anteriormente);
Tipo do Controle Valor da propriedade Name
ADO NET Source ADO NET Source - Northwind
Flat File Destination Flat File Destination - Arquivo CSV
Tabela 4. Controles a serem adicionados para o componente Data Flow Task
Integration Services2012: implementando solues de ETL - Parte 1 Integration Services2012: implementando solues de ETL - Parte 1
46 .Net Magazine Edio 110
Data access mode: indica se um comando SQL ser executado
para a obteno dos dados de origem (opo SQL Command)
ou ainda, se tais informaes viro de uma tabela ou view que
pertena base para a qual o controle ADO NET Source est
apontando (opo Table or view). Para o package GeracaoCSV-
Produtos.dtsx ser utilizada uma query (Listagem 2) que relaciona
as tabelas Products (produtos), Categories (categorias) e Suppliers
(fornecedores) do banco Northwind.
Na seo Columns da janela ADO.NET Source Editor pos-
svel observar as colunas que estaro disponveis para a gerao
do arquivo .csv de produtos (Figura 20).
Figura 19. Configurando o controle ADO.NET Source
Figura 20. Colunas geradas a partir do controle ADO NET Source
Figura 18. Fluxo do componente Data Flow Task
Listagem 2. Query para a obteno de informaes sobre o catlogo de produtos
01 SELECT
02 CdProduto = P.ProductID,
03 NmProduto = P.ProductName,
04 VlPrecoUnitario = P.UnitPrice,
05 DsCategoria = C.CategoryName,
06 NmFornecedor = S.CompanyName
07 FROM dbo.Products P
08 INNER JOIN dbo.Categories C ON
09 C.CategoryID = P.CategoryID
10 INNER JOIN dbo.Suppliers S ON
11 S.SupplierID = P.SupplierID
12 WHERE P.Discontinued = 0
13 ORDER BY P.ProductID
Concluindo a implementao do package GeracaoCSVProdutos
.dtsx, estaremos configurando agora o controle Flat File Destina-
tion. Na seo Connection Manager da janela Flat File Desti-
nation Editor efetuar os seguintes ajustes (Figura 21):
Selecionar a conexo connArquivoCSVProdutos em Flat File
connection manager;
Manter a opo Overwrite data in the file desmarcada, uma
vez que a cada execuo do pacote GeracaoCSVProdutos.dtsx um
novo arquivo .csv ser gerado;
Opcionalmente um cabealho para o arquivo .csv poder ser
definido ao se preencher o elemento Header (o que no o caso
para o exemplo aqui abordado).
Na seo Mappings da janela Flat File Destination Editor
(Figura 22) sero realizados os mapeamentos entre as colunas
da instruo SQL definida no componente ADO NET Source e
os campos correspondentes do arquivo .csv de destino (os quais
foram configurados na conexo connArquivoCSVProdutos).
Finalizada a construo do package GeracaoCSVProdutos.
dtsx, estaremos executando este arquivo para efeitos de testes a
Integration Services2012: implementando solues de ETL - Parte 1 Integration Services2012: implementando solues de ETL - Parte 1
Edio 110 .Net Magazine 47
Figura 21. Configurando o controle Flat File Destination
Figura 22. Mapeamentos das colunas empregadas na gerao do arquivo .csv
Figura 24. Visualizando detalhes da execuo do package GeracaoCSVProdutos.dtsx
Figura 23. Package GeracaoCSVProdutos.dtsx executado com sucesso
partir do Visual Studio 2012 (da mesma maneira que uma apli-
cao .NET convencional). To logo o IDE tenha concludo este
procedimento, marcaes em verde aparecero em cada task da
seo Control Flow, indicando que a gerao do arquivo .csv teve
sucesso (Figura 23).
Na seo Execution Results (ainda dentro do Visual Studio)
ser ainda visualizar detalhes da execuo do pacote Geracao-
CSVProdutos.dtsx (Figura 24). Eventuais erros estaro indicados
nesse local, servindo assim para que desenvolvedores possam
diagnosticar e corrigir problemas existentes em um package.
Um arquivo .csv dever constar ento no diretrio C:\Devmedia\
TesteVisualStudio\, como indicado na Figura 25.
Figura 25. Arquivo .csv gerado aps a execuo do package GeracaoCSVProdutos.dtsx
Na Figura 26 possvel visualizar o contedo do arquivo .csv
dentro do Bloco de Notas do Windows. J a Figura 27 exibe os
dados deste arquivo a partir do Microsoft Excel.
Executando um package localmente
Packages do Integration Services podem ser acionados a partir
de solues .NET dos mais variados tipos. Isto possvel graas
Integration Services2012: implementando solues de ETL - Parte 1 Integration Services2012: implementando solues de ETL - Parte 1
48 .Net Magazine Edio 110
aos recursos disponibilizados pela biblioteca Microsoft.SqlSer-
ver.ManagedDTS.dll, a qual permite que aplicaes Windows
Forms, Windows Service, ASP.NET e, at mesmo, Web Services
executem arquivos .dtsx sem maiores dificuldades.
A fim de demonstrar como este procedimento pode ser imple-
mentado em projetos .NET, estaremos criando uma Console Ap-
plication chamada TesteIntegration01.ExecucaoLocalPackage.
Figura 27. Arquivo .csv sendo visualizado a partir do Microsoft Excel
Figura 26. Arquivo .csv sendo visualizado a partir do Bloco de Notas
Na Listagem 3 est o arquivo app.config com as configuraes
esperadas para este projeto:
No item CaminhoPackageGeracaoCSVProdutos foi definido o
caminho em que se encontra o pacote a ser executado (no caso o
package GeracaoCSVProdutos.dtsx definido na seo anterior);
J para o item CaminhoGeracaoArquivosCSV, informe o
diretrio em que sero criados os arquivos .csv de produtos
quando a aplicao aqui descrita for executada.
A biblioteca Microsoft.SQLServer.ManagedDTS.dll pode ser encontrada no diretrio C:\Program Files
(x86)\Microsoft SQL Server\110\SDK\Assemblies\.
Nota
Listagem 3. Arquivo app.config do projeto TesteIntegration01.ExecucaoLocal-
Package
01 <?xml version=1.0 encoding=utf-8 ?>
02 <configuration>
03 <appSettings>
04 <add key=CaminhoPackageGeracaoCSVProdutos
05 value=... />
06 <add key=CaminhoGeracaoArquivosCSV
07 value=C:\Devmedia\TesteAplicacaoDotNet\ />
08 </appSettings>
09 </configuration>
Na Listagem 4 est a definio da classe Program. Quanto
estrutura deste tipo possvel observar:
Inicialmente criada uma instncia do tipo Application (names-
pace Microsoft.SqlServer.Dts.Runtime), sendo que esta referncia
servir de base para o acesso a packages do Integration Services
(linha 16);
O mtodo LoadPackage acionado a partir do objeto associado
varivel de nome appSSIS (linha 17), devolvendo como re-
sultado uma instncia da classe Package (namespace Microsoft.
SqlServer.Dts.Runtime). Esta operao recebe como parmetros o
caminho em que se encontra o package GeracaoCSVProdutos.dtsx
e, opcionalmente, uma referncia baseada na interface IDTSEvents
(namespace Microsoft.SqlServer.Dts.Runtime);
O parmetro pCaminhoGeracaoArquivosCSV do package
GeracaoCSVProdutos.dtsx est sendo preenchido atravs da
propriedade Parameters (linha 21), a qual parte integrante do
objeto representado pela varivel package. Esta ao substitui o
valor definido anteriormente no package pelo caminho indicado
no arquivo app.config;
A execuo do package GeracaoCSVProdutos.dtsx iniciada
ao se invocar o mtodo Execute pertencente instncia do tipo
Package (linha 28). O resultado disto ser um dos valores previstos
para o enumeration (namespace Microsoft.SqlServer.Dts.Runti-
me). Em caso de sucesso, a operao Execute retornar o valor
DTSExecResult.Success, ao passo que o valor DTSExecResult.
Failure corresponder a um erro durante o processamento.
Se a execuo da aplicao TesteIntegration01.ExecucaoLocalPa-
ckage ocorrer sem falhas (Figura 28), um arquivo .csv ser gerado
no diretrio especificado na seo appSettings do arquivo app.
config (Figura 29).
Efetuando o deploy de um projeto do Integration Services
Desenvolver solues para o Integration Services envolver,
quase que invariavelmente, a publicao de packages em um
servidor SQL Server. Dentre os motivos que contribuem para a
escolha por esse ambiente esto a possibilidade de se executar de
maneira programtica Jobs que acionaro um ou mais packages,
a prpria facilidade em se implementar esse tipo de alternativa (a
partir de uma interface grfica e sem a necessidade de construo
de aplicaes), alm um mecanismo de log que permite a anlise
de erros ocorridos durante o processamento de tais Jobs.
Integration Services2012: implementando solues de ETL - Parte 1 Integration Services2012: implementando solues de ETL - Parte 1
Edio 110 .Net Magazine 49
01 using System;
02 using System.Collections.Generic;
03 using System.Linq;
04 using System.Text;
05 using System.Configuration;
06 using Microsoft.SqlServer.Dts.Runtime;
07
08 namespace TesteIntegration01.ExecucaoLocalPackage
09 {
10 class Program
11 {
12 static void Main(string[] args)
13 {
14 Console.WriteLine(
15 Carregando o package GeracaoCSVProdutos.dtsx...);
16 Application appSSIS = new Application();
17 Package package = appSSIS.LoadPackage(
18 ConfigurationManager
19 .AppSettings[CaminhoPackageGeracaoCSVProdutos],
20 null);
21 package.Parameters[pCaminhoGeracaoArquivosCSV].Value =
22 ConfigurationManager
23 .AppSettings[CaminhoGeracaoArquivosCSV];
24
25 Console.WriteLine(
26 Executando localmente o package +
27 GeracaoCSVProdutos.dtsx...);
28 DTSExecResult resultado = package.Execute();
29 Console.WriteLine(
30 Resultado da execuo do package +
31 GeracaoCSVProdutos.dtsx: +
32 resultado.ToString());
33
34 Console.Write(
35 Pressione qualquer tecla para +
36 encerrar esta aplicao...);
37 Console.ReadKey();
38 }
39 }
40 }
Listagem 4. Classe Program (projeto TesteIntegration01.ExecucaoLocalPackage)
Figura 28. Executando a aplicao TesteIntegration01.ExecucaoLocalPackage
Figura 29. Arquivo .csv gerado aps a execuo do projeto TesteIntegration01.Execucao-
LocalPackage
Antes do lanamento da verso 2012 do SQL Server, o deployment
de aplicaes do Integration Services costumava ser uma tarefa
rdua para desenvolvedores familiarizados com esta tecnologia:
O Visual Studio no dispunha de nenhuma funcionalidade que
permitisse de forma direta o deployment de arquivos .dtsx em
um servidor SQL Server;
Um arquivo de manifesto precisava ento ser criado atravs do
Visual Studio e executado posteriormente, promovendo com isto
a instalao dos packages num determinado servidor;
A nica forma de modificar as configuraes esperadas para
um ou mais packages era atravs do uso de documentos XML
criados especificamente para esse fim. Outra possibilidade
(bem mais trabalhosa) seria alterar manualmente os diferentes
elementos em cada pacote antes de se proceder com a publicao
dos mesmos. Diante desse cenrio, no difcil de imaginar que
todo este processo estava sujeito a falhas, sobretudo em solues
que envolvessem o uso de inmeros packages;
Os packages poderiam ser publicados no banco de dados MSDB
(BOX 11) ou ainda, em um diretrio acessvel para o servidor SQL
Server responsvel pela execuo dos mesmos.
Este mtodo para a implantao de solues baseadas no Inte-
gration Services conhecido como Package Deployment Model
e, embora ainda seja possvel a utilizao desta alternativa, no
se recomenda mais que isso seja feito em conjunto com a verso
2012. Neste novo release do SQL Server foi disponibilizado um
modelo mais simplificado e flexvel para o deployment de apli-
caes do Integration Services: trata-se do mecanismo conhecido
como Project Deployment Model.
Quanto ao funcionamento do modelo Project Deployment Mo-
del, possvel destacar:
O deployment de packages acontece agora a partir do Visual
Studio, atravs de uma funcionalidade que dispensa assim o uso
dos arquivos de manifesto requeridos pelo mtodo anterior;
Parmetros substituram os arquivos XML utilizados na ma-
nipulao de configuraes, procurando com isto facilitar o
gerenciamento das informaes necessrias ao funcionamento
de aplicaes do Integration Services;
Ser num repositrio chamado de catlogo que acontecer a pu-
blicao de projetos do Integration Services. Para cada instncia de
um servidor SQL Server poder ser criado somente um catlogo,
com este recurso fazendo uso do mecanismo conhecido como CLR
Integration (BOX 12) para a execuo de packages.
Nesta seo demonstremos como realizar o deploy de uma
aplicao do Integration Services a partir do Visual Studio. Alm
deste IDE, estaremos fazendo uso ainda do Microsoft SQL Server
Management Studio 2012.
A base MSDB um dos bancos de dados de sistema do SQL Server, sendo utilizada por este SGDB
em operaes que envolvam o backup/restore de outras bases, envio de e-mail, agendamento e
execuo de Jobs, armazenamento de packages do Integration Services (sobretudo em releases
anteriores verso 2012), dentre outras funcionalidades.
BOX 11. O banco de dados MSDB
Integration Services2012: implementando solues de ETL - Parte 1 Integration Services2012: implementando solues de ETL - Parte 1
50 .Net Magazine Edio 110
Antes de proceder com a implantao de uma soluo do Inte-
gration Services, ser necessrio configurar o ambiente para a
execuo deste servio (caso isto ainda no tenha sido feito).
O primeiro passo consiste em habilitar o uso do Common Lan-
guage Runtime da plataforma .NET. Na Listagem 5 apresentado
um script que ativa este mecanismo, utilizando para isto as rotinas
SP_CONFIGURE e RECONFIGURE.
Com a integrao junto ao CLR ativada, estaremos prosseguindo
agora com a criao do catlogo que armazenar os projetos do
Integration Services. Selecione dentro do SQL Server Management
Studio a opo Create Catalog..., que estar disponvel a partir
do menu de contexto para o item Integration Services Catalogs
(Figura 30).
Importante ressaltar que um banco de dados (tambm chamado
SSISDB) ser gerado como resultado da criao de um catlogo
em uma instncia do SQL Server.
A fim de possibilitar uma melhor organizao dos diferentes
projetos que faro parte do catlogo SSISDB, pastas podero ser
criadas dentro deste repositrio. Quando utilizada (Figura 32), a
funcionalidade Create Folder... (acionada a partir do menu de
contexto do catlogo SSISDB) permite a separao de solues do
Integration Services em conformidade com algum critrio espec-
fico. Para os exemplos abordados nesta srie de artigos, estaremos
criando uma pasta chamada Testes (Figura 33).
O recurso conhecido como CLR Integration foi introduzido ainda na verso 2005 do SQL Server,
permitindo a integrao de estruturas deste SGBD ao Common Language Runtime (CLR) do .NET
Framework. Este mecanismo permite, dentre outras coisas, que objetos tpicos de bases de dados
relacionais como stored procedures, functions e triggers sejam implementados em .NET.
BOX 12. CLR Integration
Figura 32. Acionando a opo para a criao de pastas a partir do catlog SSISDB
Figura 31. Criando o catlogo SSISDB
Listagem 5. Habilitando o uso do CLR num servidor SQL Server
01 sp_configure clr enabled, 1
02 go
03 reconfigure
04 go
Figura 30. Acionando a opo para criao de um novo catlogo
Aparecer ento a janela Create Catalog (Figura 31) em
que constaro algumas opes referentes criao do catlogo
SSISDB:
Quando marcado, o item Enable automatic execution of
Integration Services stored procedure at SQL Server startup
determinar, logo aps a reinicializao do SGBD, a execuo
automtica de uma rotina responsvel por corrigir o status de
packages que estavam em processamento quando o servidor em
questo deixou de operar;
Uma senha que serve de base para a proteo da chave de crip-
tografia empregada pelo catlogo SSISDB.
Neste momento j estaremos com o ambiente devidamente
configurado para a publicao da aplicao TesteIntegration01.
SSIS, conforme pode ser observado na Figura 34.
Para iniciar o processo de publicao do projeto TesteInte-
gration01.SSIS, acione a opo Deploy a partir do menu de
contexto desta aplicao no Visual Studio (Figura 35). Ser exi-
bida neste instante a janela Integration Services Deployment
Wizard (Figura 36).
Integration Services2012: implementando solues de ETL - Parte 1 Integration Services2012: implementando solues de ETL - Parte 1
Edio 110 .Net Magazine 51
Figura 33. Criando a pasta Testes para o catlogo SSISDB
Figura 34. O catlogo SSISDB j configurado para a publicao de aplicaes
Figura 35. Acionando a opo para o deploy da aplicao TesteIntegration01.SSIS
Figura 36. A janela Integration Services Deployment Wizard
Figura 37. Selecionando o local em que o projeto TesteIntegration01.SSIS ser publicado
Na seo Select Destination, informe o servidor e o caminho
configurado anteriormente para a publicao da aplicao Tes-
teIntegration01.SSIS (Figura 37).
J na seo Review aparecero detalhes referentes ao projeto
que ser publicado, assim como o caminho em que este processo
acontecer (Figura 38). Acionar a opo Deploy, para com isto
concluir esse processo.
Caso no ocorram problemas, ser exibida uma confirmao de
que o projeto TesteIntegration01.SSIS foi publicado no catlogo
SSIDB abaixo da pasta Testes (Figura 39).
Retornando ao SQL Server Management Studio, ser possvel
observar o projeto TesteIntegration01.SSIS (incluindo nisto o pa-
ckage GeracaoCSVProdutos.dtsx) logo abaixo da pasta Testes
do catlogo SSISDB (Figura 40).
Integration Services2012: implementando solues de ETL - Parte 1 Integration Services2012: implementando solues de ETL - Parte 1
52 .Net Magazine Edio 110
Os valores dos parmetros e conexes utilizados pela aplicao
podem ser modificados acionando a opo Configure..., a partir
do menu de contexto da aplicao TesteIntegration01.SSIS. Altere
o valor do parmetro pCaminhoGeracaoArquivosCSV para C:\
Devmedia\TesteSQLServer\ (Figura 41); este caminho dever
existir fisicamente, a fim de que possamos executar com sucesso
os outros testes descritos mais adiante.
Criando um Job para a Execuo de um projeto do Integration
Services
A simples publicao da aplicao TesteIntegration01.SSIS
num servidor SQL Server no significa, necessariamente, que o
Figura 41. Configurando a aplicao TesteIntegration01.SSIS a partir do servidor SQL Server
Figura 40. Projeto TesteIntegration01.SSIS j publicado no servidor SQL Server
Figura 39. Publicao com sucesso do projeto TesteIntegration01.SSIS
Figura 38. Selecionando o local em que o projeto TesteIntegration01.SSIS ser publicado
processo de implantao desta soluo tenha se encerrado. Uma
das formas mais comuns para a execuo de solues do Integra-
tion Services consiste na criao de Jobs em uma instncia do SQL
Server, com tais estruturas sendo acionadas de forma automtica
e periodicamente atravs do mecanismo conhecido como servio
SQL Server Agent (BOX 13).
O SQL Server Agent mais um dos servios que fazem parte do SQL Server, fornecendo a estrutura
necessria para a criao e o agendamento da execuo de tarefas conhecidas como Jobs. Quanto
forma como os Jobs so definidos, este tipo de estrutura formado de um ou mais passos (steps),
com estes ltimos podendo executar uma instruo SQL, um stored procedure ou, at mesmo,
acionar um package do Integration Services.
BOX 13. SQL Server Agent
Nesta seo ser demonstrado de que maneira um Job pode ser
criado para a execuo diria do projeto TesteIntegration01.SSIS.
O primeiro passo para isto ser acessar (Figura 42), a partir do
elemento SQL Server Agent no utilitrio Management Studio, a
opo New Job... (acionando para isto o menu de contexto para
o item Jobs).
Dentro da janela New Job aconter a configurao de um
Job chamado Job TesteIntegration01.SSIS. Na seo General
sero preenchidas informaes para a identificao deste novo
Job (Figura 43).
Integration Services2012: implementando solues de ETL - Parte 1 Integration Services2012: implementando solues de ETL - Parte 1
Edio 110 .Net Magazine 53
Crie dentro da seo Steps (Figura 44) o passo que ir acio-
nar o package GeracaoCSVProdutos.dtsx. Na janela New Job
Step (Figura 45), preencha as seguintes configuraes:
Step name: identificao de um passo que far parte de um Job.
Informe o valor Acionar package GeracaoCSVProdutos.dtsx;
Type: tipo de ao a ser executada. O valor SQL Server In-
tegration Services Packages permite invocar um pacote .dtsx
(que pode ser ter sido previamente publicado num servidor
SQL Server ou ainda, estar localizado em algum diretrio do
servidor);
Seo Package: informar o servidor em que se encontra
instalado o package GeracaoCSVProdutos.dtsx, assim como o
caminho deste dentro do catlogo SSISDB.
Figura 43. Criando o job TesteIntegration01.SSIS
Figura 42. Acionando a opo para a criao de um novo Job
Figura 44. Configurando os steps que faro parte de um Job
Figura 45. Configurando o step que acionar o package GeracaoCSVProdutos.dtsx
J na seo Schedules (Figura 46), crie o agendamento para a
execuo do pacote GeracaoCSVProdutos.dtsx. A partir da janela
New Job Schedule (Figura 47), realize o preenchimento das
seguintes configuraes:
Name: texto que ir identificar o agendamento. Informe o valor
Agendamento - package GeracaoCSVProdutos.dtsx;
Schedule type: selecione a opo Recurring, indicando com
isto que o Job ser executado continuamente;
Frequency: selecione a opo Daily (execuo diria) para o item
Occurs e o valor 1 para Recurs every (intervalos de um dia);
Daily frequency: defina em Occurs every que a execuo
acontecer a cada 24 horas, sendo que isso ser feito entre 11:45:00
e 12:00:00;
Duration: certificar-se de que foi marcada a opo No end date.
Integration Services2012: implementando solues de ETL - Parte 1 Integration Services2012: implementando solues de ETL - Parte 1
54 .Net Magazine Edio 110
Na Figura 48 possvel visualizar o Job que acionar o package
GeracaoCSVProdutos.dtsx aps a criao do mesmo dentro do
SQL Server Agent. Aps a primeira execuo desta rotina, um
arquivo .csv ter sido gerado no diretrio C:\Devmedia\Teste-
SQLServer (Figura 49).
Todo job executado a partir do SQL Server Agent gera informa-
es de log que podero vir a ser consultadas posteriormente.
Na Figura 50 apresentando um exemplo disto, em que possvel
observar a execuo com sucesso desta rotina.
Executando um package remotamente
Packages publicados em um catlogo do Integration Services
tambm podem ser acessados por aplicaes .NET de forma
remota. Nesta seo apresentaremos de que forma isto feito,
Figura 46. Configurando o agendamento de um Job
Figura 47. Preenchendo as configuraes de agendamento de um Job
Figura 48. Job j criado no SQL Server Agent
Figura 49. Arquivo .csv gerado aps a execuo do Job
Figura 50. Consultando o log de um Job
criando para isto a Console Application TesteIntegration01.Exe-
cucaoRemotaPackage.
Este projeto far uso das seguintes bibliotecas:
Microsoft.SqlServer.Management.IntegrationServices.dll;
Microsoft.SqlServer.ConnectionInfo.dll;
Microsoft.SqlServer.Management.Sdk.Sfc.dll;
Microsoft.SqlServer.Smo.dll.
A execuo remota de um package tem como pr-requisito a
realizao de uma conexo junto ao servidor em que essa estrutura
foi publicada. Por esse motivo, ser preciso incluir no arquivo app.
config uma Connection String que aponte para a base SSISDB
Integration Services2012: implementando solues de ETL - Parte 1 Integration Services2012: implementando solues de ETL - Parte 1
Edio 110 .Net Magazine 55
(gerada juntamente com o catlogo de mesmo nome). A Listagem 6
apresenta o contedo do arquivo app.config com as configuraes
esperadas para este projeto de testes.
J na Listagem 7 est a implementao da classe Program.
Quanto s instrues para se acessar remotamente um package
previamente publicado em um servidor, merece ser destacado:
As classes IntegrationServices, Catalog, CatalogFolder, Project-
Info e PackageInfo esto sendo utilizadas ao longo do mtodo
Main, sendo que todas essas estruturas pertencem ao namespace
Microsoft.SqlServer.Management.IntegrationServices.
Uma instncia da classe IntegrationServices gerada (linha 17),
recebendo como parmetro uma referncia baseada no tipo
SqlConnection (namespace System.Data.SqlClient). Ser o objeto
associado varivel de nome integration que servir de base
para o acesso aos packages e projetos em uma determinada ins-
tncia do SQL Server;
Utilizando a referncia da classe IntegrationServices obtida
anteriormente, uma instncia da classe Catalog ser atribuda
varivel catalogo (linha 21);
O prximo passo agora ser a obteno de uma instncia da
classe CatalogFolder, a qual permitir o acesso a informaes da
pasta Testes dentro do catlogo SSISDB (linha 23);
A partir da varivel pasta ser retornada uma instncia do tipo
ProjectInfo (linha 25);
Por fim, atravs da instncia obtida no passo anterior ser asso-
ciado um objeto do tipo PackageInfo varivel package. Ser
com esta ltima referncia que iniciaremos a execuo do package,
invocando para isto o mtodo Execute (linha 33);
A operao Execute (definida na classe PackageInfo) est rece-
bendo dois parmetros. O primeiro deles um flag que indica
se o package ser processado como se estivesse num ambiente
de 32 bits (mesmo se o servidor SQL se basear numa arquitetu-
ra de 64 bits); j o segundo parmetro uma instncia do tipo
EnvironmentReference (namespace Microsoft.SqlServer.Manage-
ment.IntegrationServices), sendo que a passagem de tal referncia
opcional.
Com exceo da biblioteca Microsoft.SqlServer.Management.IntegrationServices (normalmente
localizada em C:\Windows\assembly\GAC_MSIL\), todas as demais DLLs que contam com recursos do
SQL Server utilizados pelo projeto TesteIntegration01.ExecucaoRemotaPackage podem ser encontradas
a partir do diretrio c:\Program Files (x86)\Microsoft SQL Server\110\SDK\Assemblies\.
Nota
Listagem 6. Arquivo app.config do projeto TesteIntegration01.ExecucaoRemota-
Package
01 <?xml version=1.0 encoding=utf-8 ?>
02 <configuration>
03 <connectionStrings>
04 <add name=SSISDB
05 connectionString=
06 Data Source=.;Initial Catalog=SSISDB;Integrated Security=SSPI;
07 providerName=System.Data.SqlClient />
08 </connectionStrings>
09 </configuration>
Listagem 7. Classe Program (projeto TesteIntegration01.ExecucaoRemotaPackage)
01 using System;
02 using System.Collections.Generic;
03 using System.Linq;
04 using System.Text;
05 using System.Configuration;
06 using System.Data.SqlClient;
07 using Microsoft.SqlServer.Management.IntegrationServices;
08
09 namespace TesteIntegration01.ExecucaoRemotaPackage
10 {
11 class Program
12 {
13 static void Main(string[] args)
14 {
15 Console.WriteLine(
16 Carregando o package GeracaoCSVProdutos.dtsx...);
17 IntegrationServices integration =
18 new IntegrationServices(new SqlConnection(
19 ConfigurationManager.ConnectionStrings[SSISDB]
20 .ConnectionString));
21 Catalog catalogo =
22 integration.Catalogs[SSISDB];
23 CatalogFolder pasta =
24 catalogo.Folders[Testes];
25 ProjectInfo projeto =
26 pasta.Projects[TesteIntegration01.SSIS];
27 PackageInfo package =
28 projeto.Packages[GeracaoCSVProdutos.dtsx];
29
30 Console.WriteLine(
31 Executando remotamente o package +
32 GeracaoCSVProdutos.dtsx...);
33 package.Execute(true, null);
34
35 Console.Write(
36 Pressione qualquer tecla para +
37 encerrar esta aplicao...);
38 Console.ReadKey();
39 }
40 }
41 }
Caso a aplicao TesteIntegration01.ExecucaoRemotaPackage
seja executada sem falhas (Figura 51), um novo arquivo .csv cons-
tar no diretrio C:\Devmedia\TesteSQLServer\ (Figura 52).
Executando remotamente um package a partir de um Job
Como ltimo exemplo de execuo remota de um package, esta-
remos criando o projeto TesteIntegration01.ExecucaoRemotaJob.
Isso acontecer atravs de uma chamada stored procedure SP_
START_JOB, que faz parte do banco de dados de sistema MSDB.
Na Listagem 8 est o arquivo app.config para esta aplicao de
testes, j constando no mesmo a string de conexo para acesso
base MSDB.
J na Listagem 9 est a definio da classe Program. Quanto
forma como o mtodo Main foi implementado, possvel ob-
servar:
A partir da varivel conexao (instncia do tipo System.Data.
SqlClient.SqlConnection) estabelecida uma conexo com a base
de dados MSDB (linha 15);
Integration Services2012: implementando solues de ETL - Parte 1 Integration Services2012: implementando solues de ETL - Parte 1
56 .Net Magazine Edio 110
A referncia cmd (objeto do tipo System.Data.SqlClient.Sql-
Command) invocar o stored procedure SP_START_JOB atravs
de uma chamada ao mtodo ExecuteNonQuery (linha 34), inician-
do assim a execuo da rotina Job TesteIntegration01.SSIS.
Se no ocorrerem falhas durante a execuo do projeto (Figura 53),
um novo arquivo .csv ter sido gerado no diretrio C:\Devmedia\
TesteSQLServer (Figura 54).
Figura 52. Arquivo .csv gerado aps a execuo do projeto TesteIntegration01.Execucao-
RemotaPackage
Figura 51. Executando a aplicao TesteIntegration01.ExecucaoRemotaPackage
Figura 54. Arquivo .csv gerado aps a execuo do projeto TesteIntegration01.Execucao-
RemotaJob
Figura 53. Executando a aplicao TesteIntegration01.ExecucaoRemotaJob
Listagem 8. Arquivo app.config do projeto TesteIntegration01.ExecucaoRemota-
Job
01 <?xml version=1.0 encoding=utf-8 ?>
02 <configuration>
03 <connectionStrings>
04 <add name=MSDB
05 connectionString=
06 Data Source=.;Initial Catalog=msdb;Integrated Security=SSPI;
07 providerName=System.Data.SqlClient />
08 </connectionStrings>
09 </configuration>
Listagem 9. Classe Program (projeto TesteIntegration01.ExecucaoRemotaJob)
01 using System;
02 using System.Collections.Generic;
03 using System.Linq;
04 using System.Text;
05 using System.Configuration;
06 using System.Data;
07 using System.Data.SqlClient;
08
09 namespace TesteIntegration01.ExecucaoRemotaJob
10 {
11 class Program
12 {
13 static void Main(string[] args)
14 {
15 using (SqlConnection conexao =
16 new SqlConnection(ConfigurationManager
17 .ConnectionStrings[MSDB]
18 .ConnectionString))
19 {
20 SqlCommand cmd = conexao.CreateCommand();
21 cmd.CommandText = SP_START_JOB;
22 cmd.CommandType = CommandType.StoredProcedure;
23
24 cmd.Parameters.Add(@JOB_NAME, SqlDbType.VarChar)
25 .Value = Job TesteIntegration01.SSIS;
26
27 Console.WriteLine(
28 Acessando a base de dados MSDB...);
29 conexao.Open();
30
31 Console.WriteLine(
32 Executando remotamente o Job que +
33 aciona o package GeracaoCSVProdutos.dtsx...);
34 cmd.ExecuteNonQuery();
35
36 conexao.Close();
37 }
38
39 Console.Write(
40 Pressione qualquer tecla para +
41 encerrar esta aplicao...);
42 Console.ReadKey();
43 }
44 }
45 }
Concluso
Este artigo procurou fornecer uma viso geral a respeito do Inte-
gration Services, enfatizando como tal servio pode ser empregado
na integrao entre diferentes sistemas. Por contar com um escopo
bastante abrangente no que se refere manipulao de informa-
es, esta ferramenta pode se revelar como um instrumento de
grande valia e flexibilidade nos mais variados contextos.
Dentre os cenrios mais comuns de uso do Integration Ser-
vices, possvel destacar situaes nas quais o processamento
de um grande volume de informaes requer um bom nvel de
desempenho. importante ressaltar que esta nfase em questes
envolvendo performance uma preocupao central em grandes
Integration Services2012: implementando solues de ETL - Parte 1 Integration Services2012: implementando solues de ETL - Parte 1
Edio 110 .Net Magazine 57
organizaes, representando um fator crtico para o sucesso em
muitos ramos de negcio.
Embora parte integrante do SQL Server, o Integration Services
pode ser utilizado em conjunto com outros tipos de bancos re-
lacionais (como Oracle, DB2, Postgre, Firebird), j que o mesmo
conta com suporte a mecanismos de acesso a dados como OLE DB,
ODBC e ADO.NET. Outras fontes como arquivos texto, planilhas
do Excel, documentos XML e Web Services tambm podem ser
utilizadas em projetos do Integration Services.
Renato Jos Groffe
renato.groffe@yahoo.com.br - http://www.devmedia.com.br/
renatogroffe
Atua como consultor em atividades voltadas ao desenvol-
vimento de softwares h mais de 10 anos. Bacharel em Sistemas de
Informao, com especializao em Engenharia de Software. Microsoft
Certified Technology Specialist (Web, WCF, Distributed Applications, ADO.NET, Windows
Forms), Microsoft Specialist (HTML5 with JavaScript and CSS3, Developing ASP.NET
MVC 4 Web Applications), Oracle Certified Associate (PL/SQL), Sun Certified (SCJP,
SCWCD), ITIL Foundation V2, Cobit 4.1 Foundation.
Autor
Links:
How to: Install Sample Databases
http://msdn.microsoft.com/en-us/library/vstudio/8b6y4c7s.aspx
Integration Services Programming Overview
http://technet.microsoft.com/en-us/library/ms403344.aspx
Microsoft SQL Server Data Tools - Business Intelligence for Visual Studio 2012
http://www.microsoft.com/en-us/download/details.aspx?id=36843
SQL Server Integration Services
http://technet.microsoft.com/en-us/library/ms141026.aspx
Whats New (Integration Services - SQL Server 2012)
http://technet.microsoft.com/en-us/library/bb522534.aspx
D seu voto em www.devmedia.com.br/netmagazine/feedback
Ajude-nos a manter a qualidade da revista!
Voc gostou deste artigo?
Criando uma aplicao para conexes remotas
58 .Net Magazine Edio 110
Porque esse artigo til:
A utilizao de servios de compartilhamento de tela e controle
remoto til em situaes onde preciso automatizar uma tarefa
que deve ser realizada diretamente na interface grfica do sistema
operacional. Esta automao pode ser realizada atravs do envio de
comandos (teclas) e eventos do mouse para diversos computadores
remotos que tiverem um servidor VNC instalado. Este artigo mostra
exemplos de como enviar caracteres e eventos do mouse para um
servidor VNC remoto atravs de uma aplicao cliente desenvolvida
em linguagem C#.
Resumo DevMan
Criando uma aplicao
para conexes remotas
Como criar uma aplicao cliente em C# que se
conecta a um servidor VNC remoto
A
utilizao de vrios computadores conecta-
dos em rede acabou atraindo diversos novos
servios que auxiliam o compartilhamento e
acesso a recursos. Um dos servios mais populares
representado pela categoria de softwares que permite
o compartilhamento da tela (screen sharing) e que pos-
sibilita o acesso e controle remoto da rea de trabalho
(desktop) de um computador.
As principais tecnologias para permitir o compar-
tilhamento e acesso remoto interface grfica de um
sistema operacional trabalham com o conceito de cliente/
servidor, onde um computador servidor (o host) executa
um servio que permitir clientes (clients) remotos aces-
sarem o desktop. O compartilhamento e o acesso remoto
so realizados atravs da transferncia da imagem (tela)
do host para o cliente e do envio das interaes do mouse
e teclado no cliente para o servidor. Dentre os softwares
existentes para trabalhar com estas tecnologias podemos
destacar o VNC, que a sigla utilizada para representar
as implementaes de cdigo livre que se baseiam no
uso do protocolo RFB.
A utilizao de ferramentas de compartilhamento de
desktop permite diversas aplicaes, como a possibili-
dade de suporte remoto e resoluo de problemas com
o acompanhamento do usurio, facilitar o processo de
deploy de componentes em servidores remotos, trei-
namento de usurios e monitoria de aes. Contudo,
tais usos da tecnologia de compartilhamento de tela
possuem implicaes relevantes para a privacidade e
segurana dos usurios.
Baseado nesse contexto, este artigo apresentar como
construir uma aplicao console em C# que acessa remo-
tamente um servidor VNC com a biblioteca VNCSharp.
Esta aplicao pode ser utilizada para automatizar a
execuo de tarefas administrativas (aplicao de service
pack, atualizao de configuraes, etc), treinamento de
usurios, colaborao, captura de tela e outras. A partir do projeto
de exemplo descrito neste artigo o leitor poder integrar as bibliote-
cas de acesso a um servidor VNC e montar suas prprias solues
que envolvam o acesso a computadores remotos atravs de um
cliente VNC que permite o envio de teclas e eventos do mouse.
O VNC e tecnologias de compartilhamento de tela
As tecnologias para o compartilhamento de tela e o acesso
remoto j existem h um bom tempo. Contudo, apenas recente-
mente estas ferramentas comearam a serem utilizadas em larga
escala, principalmente devido ao aumento da largura de banda
da conexo entre computadores.
Possuir uma largura de banda adequada necessrio para a uti-
lizao de tecnologias de compartilhamento de tela, uma vez que
necessrio transmitir frequentemente uma grande quantidade de
bytes associada tela do servidor remoto para os clientes. Apesar
de existirem tcnicas de compactao e reduo de informaes
necessrias para o compartilhamento de tela, ainda hoje esta
tecnologia requer uma conexo confivel, constante e adequada
entre o cliente e o servidor.
A definio de como a tela do servidor ser transmitida para os
clientes e como os eventos de mouse e teclado do cliente devem
Criando uma aplicao para conexes remotas
Edio 110 .Net Magazine 59
se fosse o usurio. Se o computador estiver bloqueado ou pedindo
credenciais pra realizar o logon, o usurio remoto deve fornecer
o login e senha como se estive em frente ao computador.
importante destacar que o servio de compartilhamento de tela
proporcionado pelo VNC no requer um login. Contudo, opcional-
mente possvel configurar apenas senha de acesso ao servidor
VNC. Uma vez que se tenha acessado o computador remoto,
geralmente necessrio fazer um login no sistema operacional
fornecendo as credenciais completas, ou seja, um usurio e senha
vlidos para o sistema operacional.
Quando um cliente se conecta remotamente a um servidor VNC,
ele assume o controle do mouse e do teclado, ou seja, os eventos do
teclado e do mouse so replicados para o servidor remoto. Porm,
isso no quer dizer que o usurio que est em frente ao mouse e
teclado do servidor remoto no possa utiliz-lo. O que acontece
que tanto os eventos de mouse/teclado remoto e local so aceitos
pelo sistema operacional. Deste modo, preciso coordenar como
ser a interao, uma vez que ambos os usurios (o remoto e o
local) podem controlar o computador.
Apesar desta situao de controle mtuo parecer estranha, exis-
tem diversas possibilidades para colaborao neste cenrio. H,
inclusive, ferramentas de udio e vdeo conferncia que exploram
esta possibilidade para permitir que, durante uma reunio, mais
de um usurio possa utilizar de forma sncrona uma aplicao de
desenho, por exemplo. Estes cenrios so comuns onde h uma
adoo de ferramentas de colaborao sncrona que so agregadas
aos canais de comunicao em tempo real com udio e vdeo.
O maior benefcio do compartilhamento de aplicativos que
um usurio remoto pode executar o software sem instalao
no seu computador, mesmo que o software no seja compatvel
com o seu sistema operacional ou que exija muito mais poder
de processamento do que o seu computador normalmente pode
possuir. Isso ocorre porque o usurio remoto no est executando
o software em seu computador, ele est apenas visualizando e
controlando o ambiente de trabalho (e, portanto, o software) do
computador host.
Apesar dos servidores e clientes VNC existentes possurem
algoritmos e tcnicas adequadas para reduzir e compactar a
quantidade de bytes necessrios para se utilizar remotamente um
computador como se ele estive local, a tecnologia e o protocolo
RFB no so adequados para a transmisso de vdeo e udio.
Sendo assim, a tecnologia recomendada para situaes onde
no h uma atualizao constante da tela e no h a necessidade
de transmisso de udio.
Contudo, certas empresas exploraram o conceito de controle
remoto e compartilhamento de tela para proporcionar servios
baseados em tecnologias armazenadas na nuvem (cloud compu-
ting). Um exemplo claro a empresa OnLive (ver seo Links)
que possui um servio onde possvel jogar diversos games sob
demanda diretamente no computador. O que a plataforma da
OnLive permite um servio de alta fidelidade e baixa latncia
para transferir a imagem do game, que est rodando em seus
servidores. A plataforma da OnLive tambm capta e envia para
ser transmitidos para o servidor detalhada no protocolo utili-
zado. Atualmente existem diversos protocolos empregados por
servidores de compartilhamento de tela, como o protocolo RDP
(Remote Desktop Connection), utilizado pelo servio Terminal
Services da Microsoft, e o protocolo RFB (Remote Framebuffer),
que empregado nos servidores de cdigo livre representados
pela sigla VNC (Virtual Network Connection). Este artigo se con-
centrar na utilizao do VNC devido facilidade de download,
instalao e execuo. Tambm se destaca a possibilidade de
criao de clientes VNC graas s bibliotecas de cdigo aberto
em C# existentes.
Antes de comearmos a detalhar como vamos criar uma aplica-
o cliente que acessa remotamente um servidor VNC, preciso
fazer a instalao do servidor e testar a conexo. Dentre as opes
gratuitas disponveis recomenda-se o RealVNC ou o TightVNC
(veja na seo Links). Estes dois softwares possuem pacotes para
download que contm tanto o servidor como ferramentas cliente
para as plataformas Windows, Mac OS e Linux.
Os leitores que desejarem executar os cdigos fontes apresen-
tados neste artigo devem possuir um servidor VNC instalado
e configurado. Executar esta instalao simples e no requer
muitos passos, apesar de serem necessrios privilgios admi-
nistrativos no computador e a eventual liberao de portas de
comunicao em um firewall. Uma vez que o servidor j esteja
instalado preciso saber qual o endereo IP (ou nome do host),
a porta utilizada (geralmente 5900) e definir uma senha para
controlar o acesso remoto. O protocolo VNC utiliza o tipo de
conexo TCP e, por isso, necessria uma conexo constante e
com uma boa qualidade para que o modo de interao remoto e
visualizao sejam adequados.
A partir do momento em que o servidor VNC est instalado
e com estas informaes em mos (endereo do host, porta e
senha), recomenda-se utilizar um segundo computador, ou seja,
um computador diferente daquele que possui o servidor VNC, e
testar a conexo remota com a ferramenta cliente disponibilizada
junto com o RealVNC ou o TightVNC. Uma vez que a conexo
esteja estabelecida, pode-se controlar remotamente o computador
que possui o servidor VNC instalado e interagir com o sistema
operacional como se o usurio estivesse fisicamente em frente
ao computador.
Um servidor VNC pode ser executado como um servio que
executado em background, isto , sem exigir interao com o
usurio. Desta maneira, quando o sistema operacional for ini-
ciado o servio VNC iniciado junto e, a partir desde momento,
o servidor pode receber conexes remotas. Em geral, os servios
que trabalham desta forma possuem suas permisses limitadas
ao usurio do sistema operacional associado ao servio. Contudo,
um usurio remoto que se conecta no servidor pode realizar um
logon com qualquer usurio (fornecendo um login e senha do
sistema operacional) e obter o acesso desejado. Esta caracterstica
no uma falha de segurana, pois o que o servio VNC propor-
ciona um acesso ao computador: se j houver algum usurio
logado, o servio VNC vai fornecer acesso ao computador como
Criando uma aplicao para conexes remotas Criando uma aplicao para conexes remotas
60 .Net Magazine Edio 110
o servidor as interaes do mouse/teclado/controle/Kinect/
Wiimote ou qualquer outro dispositivo utilizado para interagir
como game. Em resumo, o servio proporciona a um usurio
jogar um game sem ter que comprar e instalar o console e o jogo.
H, inclusive, a possibilidade de se conectar nas redes Xbox
Live, PSN Network e Nintendo network para jogar com colegas,
comprar filmes, visualizar estatsticas e trofus e interagir com a
comunidade de jogadores.
Outro exemplo de empresa que se especializou na utilizao de
tecnologias para o compartilhamento de tela a Citrix. O foco na
utilizao de sistemas gerenciais do tipo ERP, evitando que seja ne-
cessrio instalar e manter softwares adicionais nos computadores
dos clientes. Alm de proporcionar o acesso remoto a servidores
que contm o software, evitando o processo de instalao, atua-
lizao, manuteno e suporte, as tecnologias da Citrix tambm
possuem uma integrao com servidores virtuais, chegando ao
ponto de permitir a virtualizao e o acesso remoto completo do
desktop do usurio que pode acessar o software de qualquer PC,
Mac, Linux, Tablet ou smartphone.
Conhecendo as alternativas
O desenvolvedor da plataforma .NET que trabalha com C#
possui algumas alternativas para criar sua prpria aplicao
que age como cliente VNC. Tanto o RealVNC como o TightVNC
possuem verses com cdigo livre, porm elas so baseadas na
linguagem de programao C/C++. Os projetos mais populares
no .NET que disponibilizam classes e outros recursos para
acessar um servidor VNC em C# so o VNC-Client for .NET, o
.NET VNC Viewer e o VNCSharp.
O projeto VNC-Client for .NET contm apenas um exemplo de
como criar uma aplicao que se conecta a um servidor VNC
remoto. Ele faz uso do arquivo binrio das bibliotecas NzipLib
e DirectX e possui uma documentao simples das classes e
mtodos. Contudo, este projeto no foi criado na forma de uma
biblioteca autocontida que possa ser utilizada em qualquer
tipo de aplicao .NET (console, Windows Forms, WPF, ASP
.NET), o que requer do desenvolvedor um esforo grande para
trabalhar com seus mtodos e classes.
O projeto .NET VNC Viewer disponibilizado como uma
aplicao cliente criada a partir do tipo de projeto Windows
Forms. Apesar de ser completo, este projeto no disponibiliza
uma biblioteca e nem um controle. Alm disso, h no docu-
mentao do projeto e ele disponibilizado como um conjunto
de classes que deve ser compilado diretamente no console,
ou seja, no h uma soluo ou projeto do Visual Studio. Este
projeto no possui dependncias externas e nos testes reali-
zados apresentou boa performance de atualizao da tela do
computador remoto.
Por fim, o projeto VNCSharp segue o modelo de licena GPL e
tambm apresentou boa performance de atualizao da tela do
computador remoto. Este projeto disponibilizado como uma
biblioteca .NET (assembly) que contm classes e um controle
do tipo Windows Forms. Apesar do projeto no estar mais em
desenvolvimento, no possuir uma boa documentao e no
precisar de dependncias externas, o cdigo do projeto bem
comentado. Este projeto conta ainda com um exemplo simples
que mostra como utilizar a biblioteca e o controle em uma
aplicao do tipo Windows Forms.
Devido s caractersticas dos projetos descritos e facilidade
de uso, este artigo se concentrar na utilizao da biblioteca
VNCSharp para montar um exemplo de aplicao console em
C# que se conecta a um servidor VNC remoto e envia um con-
junto de letras como se elas tivessem sido digitadas pelo usurio
no teclado. O exemplo mostra tambm como enviar eventos do
mouse para mov-lo remotamente ou simular um clique.
O exemplo apresentado pode ser modificado para realizar
tarefas de manuteno automaticamente em diversos compu-
tadores de usurios finais, mesmo realizar um treinamento
remoto ou compartilhar uma aplicao existente entre vrios
usurios em uma aplicao de udio/vdeo conferncia.
Download, instalao e exemplo do VNCSharp
O projeto VNCSharp disponibiliza seus recursos em diferentes
arquivos. Neste artigo utilizou-se a verso 1.0 e o leitor pode
fazer o download do arquivo vncsharp-1.0-bin.zip, que contm a
biblioteca compilada no assembly VncSharp.dll, ou o download do
arquivo vncsharp-1.0-src.zip, que contm uma soluo do Visual
Studio com os cdigos fontes deste projeto. H tambm o projeto
de exemplo no formato Windows Form compactado no arquivo
vncsharpexample-csharp-1.0-src.zip. Veremos como compilar o
projeto de exemplo e iniciar conexes remotas para testar a biblio-
teca e o componente Windows Form disponibilizados.
Aps o download e extrao dos arquivos contidos em
vncsharpexample-csharp-1.0-src.zip, abra a soluo disponi-
bilizada no arquivo VncSharpExampleCS.sln no Visual Studio
(a partir da verso 2005) e compile o projeto. O leitor deve
notar atravs da lista de referncias (References) que a nica
dependncia externa deste projeto o assembly VncSharp.dll
que contm as classes, componentes e outros recursos organi-
zados no namespace VncSharp.
O projeto de exemplo contm um Form chamado VncSharp-
ExampleForm, que composto de menus e de um controle
especial da classe VncSharp.RemoteDesktop chamado rd. Este
controle est dentro do assembly VncSharp.dll e ele respon-
svel pela apresentao da tela e captura/envio de eventos do
mouse e teclado. Existem outros detalhes importantes deste
exemplo, porm fica a cargo do leitor explorar o projeto para
compreend-lo melhor.
Aps compilar e executar este projeto, podemos clicar no menu
File e escolher a opo Connect. Em seguida devemos informar
o endereo IP ou nome do servidor VNC e a senha. Por padro,
este cliente assume que o servidor est utilizando a porta 5900,
mas caso seja empregada uma porta diferente, basta indicar no
nome do servidor o nmero da porta precedido do caractere :
(dois pontos), como 10.0.0.100:5901 para indicar que o computador
10.0.0.100 possui um servidor VNC na porta 5901.
Criando uma aplicao para conexes remotas Criando uma aplicao para conexes remotas
Edio 110 .Net Magazine 61
A Figura 1 mostra a conexo remota com um servidor executan-
do o Windows XP (note que o cone do VNC no canto esquerdo
da barra de tarefas do Windows mudou de cor para indicar a
conexo), enquanto a Figura 2 mostra uma conexo remota com
um computador executando o Mac OS Lion, que possui um ser-
vidor VNC nativo, isto , disponibilizado junto com o sistema
operacional. J a Figura 3 mostra um exemplo de conexo com um
dispositivo celular rodando o sistema operacional Android 4.0.4
(Ice Cream Sandwich) com um servidor VNC. Qualquer sistema
operacional que possua um servidor VNC que siga o padro do
protocolo RFB pode receber uma conexo do VncSharp, inclusive
sistemas operacionais das plataformas mveis (iOS, Android e
Windows 8).
Uma vez que o teste de conexo tenha sido realizado com su-
cesso, preciso utilizar a opo Disconnect do menu File para
finalizar a conexo e liberar os recursos utilizados do lado do
cliente.
Figura 1. Cliente VncSharpExampleForm conectado a um servidor VNC no Windows XP
Figura 2. Cliente VncSharpExampleForm conectado a um servidor VNC no Mac OS Lion
Figura 3. Cliente VncSharpExampleForm conectado a um servidor VNC no Android 4.0.4 (Ice
Cream Sandwich)
Enviando caracteres
Para auxiliar o leitor a compreender como trabalhar com a bi-
blioteca do projeto VNCSharp, este artigo apresentar um projeto
do tipo Console Application escrito em C# que utiliza apenas as
classes bsicas do VNCSharp. O objetivo mostrar como possvel
abrir uma conexo com um servidor VNC remoto, enviar uma
sequncia de caracteres como se fosse algo digitado pelo usurio
e fechar a conexo. Apesar de este exemplo ser simples, ele ilustra
bem como possvel utilizar o C# para se conectar a um servidor
VNC independente da plataforma e sistema operacional na qual
este servidor esteja sendo executado.
Apesar do exemplo apresentado neste artigo utilizar o tipo de
projeto Console Application, as classes do VNCSharp podem
ser utilizadas em qualquer tipo de aplicao .NET. H, inclusive,
a possibilidade de criar um cliente VNC inteiro em HTML5 e
ASP.NET para que o usurio possa acessar remotamente outros
computadores diretamente pelo browser sem a necessidade de
instalao de nenhum software adicional.
Um cliente VNC basicamente faz trs tarefas principais: ele con-
trola a conexo (abrir/fechar), recebe a atualizao de telas e envia
teclas ou eventos do mouse. Tambm possvel realizar tarefas
mais complexas, como copiar o contedo do que foi colocado na
rea de transferncia do servidor remoto com o comando cpia
(ou Control+C) e colar (Control+V) este contedo no computador
que executa o cliente. Porm, como foi explicado na primeira
sesso deste artigo, veremos um exemplo que detalhar como
Criando uma aplicao para conexes remotas Criando uma aplicao para conexes remotas
62 .Net Magazine Edio 110
abrir a conexo, enviar caracteres, enviar eventos do mouse e
fechar a conexo. O leitor que se interessar por recursos avana-
dos proporcionados pela tecnologia VNC pode analisar o cdigo
fonte do projeto VNCSharp, pois ele possui diversas classes que
implementam o protocolo RFB, interagem com os dados enviados
e recebidos, compactam e descompactam os dados e permitem a
utilizao de recursos avanados.
Vamos comear o exemplo abrindo o Visual Studio e criando um
novo projeto do tipo Console Application chamado ConsoleVNC.
Em seguida preciso fazer a referncia ao assembly VncSharp
.dll que disponibilizado no arquivo vncsharp-1.0-bin.zip do
projeto VNCSharp.
Para fazer a referncia corretamente preciso clicar com o
boto direito do mouse sobre o item References na janela Solu-
tion Explorer e escolher a opo Add References. Em seguida
escolha a aba Browser e navegue para a pasta onde o arquivo
VncSharp.dll est armazenado, selecione o arquivo e clique
no boto OK. Agora que a referncia est completa e podemos
comear a utilizar as classes do VNCSharp. O cdigo fonte
comentado deste exemplo apresentado na Listagem 1 que
contm apenas o mtodo Main().
Para este exemplo utilizaremos um objeto da classe VncClient
chamado v. O primeiro passo abrir a conexo e faremos isso com
o mtodo Connect(), que recebe o endereo do servidor, o nmero
da tela (screen) e a porta. Neste exemplo utilizaremos o endereo
10.0.0.100 e a porta 5900. O valor numrico da tela deve ser 0, uma
vez que no vamos trabalhar com mltiplas telas neste exemplo.
Um servidor VNC pode ser configurado para permitir conexes
de usurio sem que haja a necessidade de senha. Contudo, tal op-
o no recomendada por motivos de segurana. Na Listagem 1
o mtodo Connect() retorna um valor booleano indicando se
necessrio ou no fornecer uma senha para se conectar neste
servidor. Caso seja necessrio, a varivel needPassword receber
o valor verdadeiro (true) e devemos chamar o mtodo Authen-
ticate(). Caso no seja necessrio fornecer uma senha, podemos
chamar o mtodo Initialize(). Para fornecer a senha chamamos
o mtodo Authenticate() passando como parmetro a senha, que
no exemplo da Listagem 1 abc123. Caso o retorno de Authenti-
cate() seja verdadeiro, prosseguimos com conexo e chamamos
o mtodo Initialize().
O ltimo mtodo necessrio para abrir corretamente a conexo
o mtodo StartUpdates(), pois ele sinaliza para o servidor que
01 using System;
02 using VncSharp;
03 using System.Windows;
04 using System.Drawing;
05 using System.Threading;
06
07 namespace ConsoleVNC
08 {
09 class ConsoleVNC
10 {
11 // Esta varivel representa o cliente VNC
12 static VncClient v = new VncClient();
13
14 static void Main(string[] args)
15 {
16 // Armzena se precisa ou no enviar a senha
17 bool needPassword;
18
19 try
20 {
21 // Abre a conexo como servidor 10.0.0.100
22 // na porta 5900 e na tela 0
23 needPassword = v.Connect(10.0.0.100, 0, 5900);
24 if (needPassword)
25 {
26 // Envia a senha abc123
27 if (v.Authenticate(abc123))
28 {
29 // Realiza as inicializaes necessrias
30 v.Initialize();
31 }
32 else
33 {
34 // Problema: informar usurio e finalizar
35 Console.WriteLine(Autentication problem!);
36 return;
37 }
38 }
39 else
40 // Realiza as inicializaes necessrias
41 v.Initialize();
42
43 // Indicando o mtodo que vai receber o
// evento de desconexo
44 v.ConnectionLost +=
new EventHandler(ConsoleVNC.ClientConnectionLost);
45
46 // Comea a receber as atualizaes de tela
47 v.StartUpdates();
48 }
49 catch (Exception e)
50 {
51 // Problemas na conexo: informar usurio e finalizar
52 Console.WriteLine(Connection error: + e.Message);
53 return;
54 }
55
56 // Mostra informaes do host
57 Console.WriteLine(Connection OK!);
58 Console.WriteLine(Host Name: + v.HostName);
59 Console.WriteLine(Screen Size: +
v.Framebuffer.Width.ToString() + x
+ v.Framebuffer.Height.ToString() );
60
61 // Envia a frase Hello World with VNC para o host
62 ConsoleVNC.SendString(Hello World with VNC);
63
64 // Disconecta e libera os recursos
65 v.Disconnect();
66
67 Console.WriteLine(Disconnected!
Presse any key to terminate);
68 Console.ReadLine();
69 }
70 }
71 }
Listagem 1. Exemplo de conexo com o projeto VncSharp
Criando uma aplicao para conexes remotas Criando uma aplicao para conexes remotas
Edio 110 .Net Magazine 63
estamos prontos para receber as atualizaes de tela. Neste exem-
plo no iremos trabalhar com a atualizao de tela, pois apenas
vamos enviar um conjunto de caracteres para o servidor VNC.
Um ponto importante que toda a sequncia de conexo est
protegida por um bloco try/catch e as devidas mensagens de erro
so apresentadas, caso ocorra algum problema.
Aps a conexo entre o cliente e o servidor ser estabelecida,
possvel que, por algum motivo, o servidor encerre esta conexo.
Por exemplo: o computador que contm o servio VNC foi reinicia-
lizado. Devido a esta possibilidade a biblioteca VNCSharp possui
um evento que ser disparado no cliente caso o servidor encerre a
conexo. Para indicar um mtodo que ser chamado nesta situao
devemos preencher a propriedade ConnectionLost com um objeto
da classe EventHandler, que permite o acesso a um mtodo que
tratar este evento. No cdigo da Listagem 2 o mtodo esttico
ClientConectionLost() utilizado como evento para a propriedade
ConnectionLost do objeto v, que da classe VncClient.
O mtodo ClientConectionLost() segue a assinatura de um even-
to, ou seja, ele retorna void e possui dois parmetros: um objeto
da classe Object e um objeto da classe EventArgs. A utilizao
do evento ocorre quando o servidor finaliza a conexo e ela ser
simples, pois somente vamos chamar o mtodo Disconnect() da
classe VncClient para liberar os recursos alocados. Contudo, o
leitor pode codificar outras funcionalidades neste evento, como
notificar o usurio de alguma forma na interface grfica que o
servidor finalizou a conexo.
Uma vez que o primeiro passo esteja completo, ou seja, abrir
a conexo, podem mostrar algumas caractersticas do host.
A propriedade HostName da classe VncClient retorna o nome do
host e as propriedades Framebuffer.Width e Framebuffer.Height
retornam valores numricos com a largura e altura da tela do host,
respectivamente. O exemplo mostra estes valores para o usurio
e segue seu fluxo para enviar uma frase pelo VNC.
O envio da frase Hello World with VNC realizado atravs do
mtodo SendString(), que mostrado na Listagem 3. Este mtodo
basicamente recebe uma String como parmetro e faz um loop
para pegar cada caractere individual deste String, uma vez que
esta operao necessria, pois o mtodo WriteKeyboardEvent()
da classe VncCliente requer a converso de cada caractere enviado
para UInt32. Tambm necessrio passar o segundo parmetro
de WriteKeyboardEvent() como verdadeiro para simular que o
usurio realmente digitou algo.
No exemplo do cdigo apresentado na Listagem 3 um texto foi
enviado por meio da converso de cada um dos caracteres para
um valor numrico do tipo UInt32. Caso seja necessrio enviar
teclas especiais como Enter, Tab, SHIFT ou ALT, preciso enviar
um cdigo numrico do tipo UInt32 especial para cada tecla. Este
cdigo definido no protocolo RFB, porm a Tabela 1 apresenta
algumas das teclas especiais mais utilizadas e tambm o respec-
tivo valor no tipo de dados UInt32 representados por um valor
hexadecimal.
Listagem 3. Mtodo para envio de caracteres com o VncSharp
01 static void SendString(String s)
02 {
03 // Envia um caracter por vez
04 foreach (Char c in s.ToCharArray())
05 {
06 // preciso converter o caracter para UInt32
07 // O segundo parmetro verdadeiro para simular que o
08 // usurio pressionou as teclas
09 v.WriteKeyboardEvent((UInt32) c, true);
10 }
11 }
Listagem 2. Mtodo para tratar desconexo do servidor
01 // Evento gerado caso o servidor desconecte o cliente
02 static void ClientConnectionLost(object sender, EventArgs e)
03 {
04 // Liberando os recursos da conexo do cliente
05 ConsoleVNC.v.Disconnect();
06 }
O envio de teclas deve ser realizado de forma individual, ou seja,
uma tecla por vez. preciso lembrar que certas teclas iniciam e
finalizam um modo, por exemplo, a tecla Shift que inicia/termina
o modo de letras maisculas.
Por fim, o ltimo passo do programa de exemplo chamar o
mtodo Disconnect() da classe VncClient para finalizar a cone-
xo e liberar os recursos. Para testar o exemplo preciso instalar
corretamente um servidor VNC e abrir algum tipo de aplicao
que aceite caracteres, como o editor Notepad do Windows.
Se tudo estiver configurado corretamente (servidor VNC, firewall,
Tecla Valor numrico
(UInt32)
Tecla Valor numrico (UInt32)
Tab 0x0000FF09 F1 0x0000FFBE
Enter 0x0000FF0D F2 0x0000FFBF
Esc 0x0000FF1B F3 0x0000FFC0
Home 0x0000FF50 F4 0x0000FFC1
Seta para esquerda 0x0000FF51 F5 0x0000FFC2
Seta para cima 0x0000FF52 F6 0x0000FFC3
Seta para direita 0x0000FF53 F7 0x0000FFC4
Seta para baixo 0x0000FF54 F8 0x0000FFC5
PageUp 0x0000FF55 F9 0x0000FFC6
PageDown 0x0000FF56 F10 0x0000FFC7
End 0x0000FF57 F11 0x0000FFC8
Insert 0x0000FF63 F12 0x0000FFC9
Shift 0x0000FFE1
Alt 0x0000FFE9
Ctrl 0x0000FFE3
Delete 0x0000FFFF
Tabela 1. Teclas especiais e seus respectivos valores UInt32
Criando uma aplicao para conexes remotas Criando uma aplicao para conexes remotas
64 .Net Magazine Edio 110
senha, etc.), ao rodar a aplicao o usurio remoto ver a frase
Hello World with VNC sendo escrita na aplicao que estiver
com foco do cursor do mouse.
Enviando eventos do mouse
Agora que j vimos como se conectar a um servidor VNC
remoto e enviar um conjunto de teclas como se fosse o usurio
digitando algo no teclado, veremos como enviar eventos do
mouse. Este tipo de funcionalidade muito til quando preci-
samos acessar algum cone ou elemento visual da interface do
usurio que requer o posicionamento e o clique do mouse.
Um cenrio comum para este tipo de situao no suporte
a usurios. Vamos supor que um usurio est com dificul-
dade para acessar uma opo no menu de uma aplicao.
O atendente de suporte que recebeu uma ligao deste usu-
rio pode acionar um comando da sua interface e posicionar
automaticamente o cursor do mouse do usurio sem que o
atendente de suporte tenha acesso remoto completo ao sis-
tema operacional do usurio. Neste cenrio a possibilidade
do atendente de suporte ter acesso a arquivos e contedos
da mquina do usurio reduzida, evitando uma possvel
violao da privacidade.
Antes de enviar os eventos do mouse preciso levar em con-
siderao que a resoluo do computador remoto (o host com o
servidor VNC) pode ser diferente da resoluo do computador
com o cliente VNC. Portanto, preciso fazer um mapeamento e
converso de coordenadas locais para as coordenadas remotas
do ponteiro para que o uso do mouse parea natural e adequado.
O controle disponibilizado pelo VncSharp implementa um
algoritmo que faz este tipo de mapeamento de coordenadas de
tela, porm veremos um exemplo simples de movimentao do
cursor em um conjunto de coordenadas da tela pr-definido.
Para enviar eventos do mouse utilizando a classe VncClient
preciso utilizar o mtodo WritePointerEvent(), que requer dois
parmetros: um valor numrico para indicar qual boto do mouse
foi pressionado e um objeto da classe System.Drawing.Point com
as coordenadas de onde o cursor do mouse ser posicionado.
No primeiro exemplo veremos como enviar um comando
para simular a movimentao do mouse. Para isso vamos
criar um novo mtodo chamado SendMouseMove(), que vai
enviar comandos de movimentao do mouse para seguir o
formato de um quadrado com 100 pixels de lado.
O quadrado ter seus vrticies nos pontos (100,100), (200,100),
(200,200) e (100,200) da interface do usurio e ser desenhado ponto
a ponto. A movimentao do cursor ser feita atravs de quatro
loops que utilizam o contador do loop para variar as coordenadas
de um objeto da classe System.Drawing.Point, que ser enviado
como segundo parmetro do mtodo WritePointerEvent(). Para
visualizarmos o caminho do cursor do mouse utilizaremos um
intervalo de 10 milisegundos entre cada movimentao do cursor
atravs da chamada do mtodo Thread.Sleep().
O primeiro parmetro do mtodo WritePointerEvent() requer
um valor numrico para indicar qual o boto do mouse que
est sendo pressionado. Neste primeiro exemplo vamos apenas
movimentar o curso do mouse e, por isso, passaremos o valor 0
como primeiro parmetro para o mtodo WritePointerEvent().
A Listagem 4 mostra o contedo completo do mtodo Sen-
dMouse-Move() que pode ser chamado logo aps o mtodo
SendString() da Listagem 1.
O prximo exemplo que veremos envia o clique do mouse
remotamente. Para enviar o clique do mouse tambm utili-
zaremos o mtodo WritePointEnvent() da classe VncClient,
porm desta vez precisamos indicar no primeiro parmetro
qual boto do mouse ser pressionado. A Tabela 2 mostra a
correspondncia de valores nmeros para o valor do primeiro
parmetro do mtoro WritePointEvent() e os respectivos bo-
tes do mouse. Tambm so mostrados na Tabela 2 os valores
correspondentes movimentao da roda do mouse (scroll)
para frente e para trs.
Listagem 4. Mtodo SendMouseMove() que envia comandos para movimentar o
cursor do mouse
01 static void SendMouseMove()
02 {
03 // Topo do quadrado
04 for (int i = 100; i <= 200; i++)
05 {
06 Thread.Sleep(10);
07 v.WritePointerEvent(0, new System.Drawing.Point(i, 100));
08 }
09 // Lado direito do quadrado
10 for (int i = 100; i <= 200; i++)
11 {
12 Thread.Sleep(10);
13 v.WritePointerEvent(0, new System.Drawing.Point(200, i));
14 }
15 // Base do quadrado
16 for (int i = 200; i >= 100; i--)
17 {
18 Thread.Sleep(10);
19 v.WritePointerEvent(0, new System.Drawing.Point(i, 200));
20 }
21
22 // Lado esquerdo do quadrado
23 for (int i = 200; i >= 100; i--)
24 {
25 Thread.Sleep(10);
26 v.WritePointerEvent(0, new System.Drawing.Point(100, i));
27 }
28 }
Valor do parmetro Boto do mouse
0 Nenhum boto pressionado
1 Esquerdo
2 Meio
4 Direito
8 Roda do mouse movimentada para frente
16 Roda do mouse movimentada para trs
Tabela 2. Valores numricos do primeiro parmetro de WritePointEvent() e botes do mouse
Criando uma aplicao para conexes remotas Criando uma aplicao para conexes remotas
Edio 110 .Net Magazine 65
possvel simular a situao onde mais de um boto foi pressio-
nando adicionando os valores numricos. Por exemplo, se desejar-
mos indicar que os botes direito e esquerdo foram pressionados
juntos utilizaremos o valor 5, pois 1+4 = 5.
Devemos tomar cuidado com um ltimo detalhe antes de enviar
um evento de clique do mouse com o mtodo WritePointEvent():
nos sistemas operacionais que seguem o modelo de interface
WIMP (BOX 1) um clique do mouse geralmente representado
por dois eventos: MouseDown e MouseUp. Isto quer dizer que
precisamos fazer duas chamadas aos mtodos WritePointEvent()
para simular um clique do mouse, sendo que a primeira delas deve
indicar qual foi o boto utilizado e a segunda chamada indica o
valor 0 (ausncia de boto).
WIMP um acrnimo usado para descrever todos os elementos de sistemas operacionais que
definem o modo como interagimos com os computadores cuja GUI (Graphical User Interface
Interface Grfica de usurio) seja baseada em janelas.W significa Windows (janelas), I significa Icons
(cones), M significa Menus e P significa Pointers (ponteiros).
Em 1973 a Xerox desenvolveu o primeiro sistema operacional com um paradigma WIMP para o Xerox
Alto. Desde aquela poca at recentemente as GUI baseadas em WIMP foram as lderes da interao
entre humanos e computadores. Sistemas operacionais como o Windows, Mac OS, OS/2 e o Linux
adotaram os conceitos WIMP em suas interfaces, o que facilitou a interao para os usurios que
utilizam mouse e teclado.
Com as novas tecnologias e recursos para desenvolvimento de pginas Web, muitos dos conceitos
WIMP vem sendo desafiados, como a ausncia de menus tradicionais. Alm disso, os sistema
operacionais mveis como iOS, Android e Windows 8 abandonaram muitos dos conceitos WIMP ao
adotarem interfaces baseadas em toques e gestos realizados diretamente no dispositivo sensvel a
toque que apresenta as informaes.
BOX 1. Interfaces WIMP
Se entre a primeira chamada (equivalente ao MouseDown) e a
segunda chamada (equivalente ao MouseUp) no houver uma
diferena nas coordenadas, ou seja, o valor do segundo parme-
tro de WritePointEvent() for igual, temos o evento do clique do
mouse. Porm, caso haja uma diferena de coordenadas entre
a primeira chamada de WritePointEvent() e a segunda temos a
representao do clicar, arrastar e soltar, tambm conhecido como
drag-and-drop. Por fim, se desejarmos simular o evento de clique
duplo basta fazer duas vezes as duas chamadas necessrias para
um clique normal.
Para mostrar como simular o envio de um evento de clique do
mouse pelo VNC, a Listagem 5 mostra o mtodo SendMouse-
Click(), que recebe como parmetro um valor numrico corres-
pondente ao boto do mouse como apresentado na Tabela 2.
O contedo deste mtodo simples: ele cria uma varivel chamada
mask para indicar qual o boto do mouse que est sendo acio-
nado e simula um clique no centro da tela, utilizando o mtodo
WritePonterEvent. Para testar este exemplo leitor deve realizar a
chamada de SendMouseClick() duas vezes, sendo que na primeira
vez deve-se indicar o valor do boto do mouse (1, 2 ou 4) e na
segunda vez deve-se indicar o valor 0 para que um clique seja
enviado para o servidor VNC remoto.
Concluso
A utilizao de tecnologias de compartilhamento de tela e con-
trole remoto representa uma oportunidade para a realizao de
tarefas que necessita do acesso completo local a um computador.
Apesar e ser possvel realizar diversas operaes com ferramen-
tas de acesso remoto ao shell, tais como ferramentas de SSH ou
mesmo servidores de FTP/SFTP, o acesso direto ao desktop de um
computador pode fornecer diversas oportunidades para automa-
o de tarefas, treinamento de usurio, resoluo de problemas
de suporte, deploy de aplicaes, verificao de configuraes e
outras.
As principais ferramentas de compartilhamento de telas livres,
agrupadas sob a sigla VNC, permitem o acesso remoto completo
de um servidor, porm elas representam potenciais problemas de
segurana e violao de privacidade. Por exemplo, atravs do aces-
so por VNC um usurio com ms intenes pode acessar arquivos
pessoais de usurios ou mesmo observar a digitao de senhas
e outras informaes sigilosas. Neste contexto, permitir o acesso
remoto por meio do VNC se torna uma atitude arriscada.
Contudo, possvel criar uma aplicao na plataforma .NET que
encapsula o acesso remoto a um servidor VNC. Esta aplicao
pode se conectar a um host remoto e enviar determinadas teclas
ou eventos do mouse e realizar certas tarefas sem nem ao menos
mostrar para quem iniciou este cliente VNC a tela do desktop
remoto. Desta maneira evitam-se possveis problemas de violao
de privacidade.
Apesar da tecnologia envolvida nos servidores VNC ser bsica,
ou seja, permite apenas o envio de teclas e eventos do mouse e
recebe do host a atualizao de telas, existem vrias possibilidades
para incluir novas funcionalidades. Criptografia das informa-
es, ferramentas de chat com texto e VoIP, envio/transferncia
de arquivos e acesso por meio da Web so apenas algumas das
funcionalidades adicionais que no so contempladas pelo proto-
colo RFB e que podem ser agregadas em uma soluo que utilize
tecnologias de compartilhamento de tela.
Listagem 5. Mtodo SendMouseClick() que envia comandos para simular o clique
de um boto do mouse no centro da tela.
01 static void SendMouseClick(byte botao)
02 {
03 // Mandando o cursor do mouse para o centro da tela
04
05 byte mask;
06
07 // 1 = boto da esquerda
08 // 2 = boto do centro
09 // 4 = boto da direita
10 mask = botao;
11
12 v.WritePointerEvent(
13 mask,
14 new System.Drawing.Point
(v.Framebuffer.Width/2,v.Framebuffer.Height/2 )
15 );
16 }
Criando uma aplicao para conexes remotas Criando uma aplicao para conexes remotas
66 .Net Magazine Edio 110
Outro cenrio de uso para esta tecnologia envolve o treina-
mento. Em uma situao onde no h recursos para treinamento
adequados (projetores, sala de treinamento, etc) possvel treinar
usurios de forma automatizada diretamente nas suas interfa-
ces, sem a necessidade de locomoo do usurio. Este tipo de
treinamento com demonstraes fornece a sensao de presena
remota e o usurio que est sendo treinado pode acompanhar as
aes sendo realizadas como se o instrutor estivesse trabalhando
junto com ele.
Outra forma para utilizar o compartilhamento de contedo ou
apresentao so seminrios Web ou webinars. Em um webinar
um apresentador envia um convite por e-mail a um grupo de par-
ticipantes que inclui um link e um cdigo de acesso. Quando os
participantes clicarem no link e digitarem seus cdigos de acesso
eles esto registrados na apresentao virtual. Neste cenrio s
pode haver um apresentador de cada vez que pode compartilhar
seu desktop, suas apresentaes com programas como o Power-
Point, ou partes de outras aplicaes e software no computador
host. Com o software de webinar, que baseado em tecnologias
de compartilhamento de tela, cada apresentador pode compar-
tilhar o seu prprio ambiente de trabalho e arquivos. Talvez o
exemplo mais claro deste tipo de tecnologia seja representado
pelos servios da empresa WebEx (parte do grupo da Cisco) que
fornece aplicativos de demanda, reunio online, web conferncia
e aplicaes de vdeo conferncia.
Com a utilizao de um servidor VNC tambm possvel criar
um servio de monitorao constante do desktop de um com-
putador remoto. Tal ferramenta pode ser til para revisar aes
realizadas ou medir o tempo gasto em determinada aplicao.
Por exemplo: um gerente de projeto deseja saber quanto tempo
um programador passou como a interface do Visual Studio aberto
e quanto tempo ele passou navegando na internet. Ao invs de
programar um servio especfico para este tipo de monitorao,
possvel instalar um servidor VNC no computador do desenvol-
vedor e criar um cliente VNC em C# que periodicamente l a tela
do desenvolvedor e grava a tela em uma sequncia de imagens
ou em um banco de dados. Posteriormente o gerente de projeto
pode revisar as imagens e verificar exatamente quanto tempo o
desenvolvedor gastou na interface do Visual Studio ou no nave-
gador. Alm disso, o gerente de projeto tambm pode identificar
como o programador utilizou o IDE ou mesmo qual tipo de site
foi visitado pelo programador. Novamente, este uso da tecnologia
VNC possui implicaes no campo da privacidade e segurana
que devem ser consideradas com cautela por quem emprega este
tipo de tecnologia para fins de monitoria.
O leitor que desejar automatizar tarefas remotas que exigem
acesso direto ao servidor em diversas mquinas pode se beneficiar
do contedo apresentado neste artigo, uma vez que ele mostrou
como possvel desenvolver uma aplicao .NET na linguagem
C# que age como um cliente de um servidor VNC atravs do uso
das classes fornecidas pelo projeto VNCSharp.
Mauro Pichiliani
mauro@pichiliani.com.br http://pichiliani.com.br
bacharel em Cincia da Computao, mestre e doutorando
pelo ITA (Instituto Tecnolgico de Aeronutica) e MCP, MCDBA e
MCTS. Trabalha h mais de 10 anos utilizando diversos bancos de dados
SQL e NoSQL. colunista de SQL Server do web site iMasters (http://www.
imasters.com.br) e mantenedor do DatabaseCast (@databasecast), o podcast brasileiro
sobre banco de dados.
Autor
Links:
Projeto VNC-Client for .NET
http://sourceforge.net/projects/dnvnccl/
Projeto.NET VNC Viewer
http://sourceforge.net/projects/dotnetvnc/
Projeto VNCSharp
http://cdot.senecac.on.ca/projects/vncsharp
Servidor e cliente VNC gratuito RealVNC para Windows, Mac OS e Linux
https://www.realvnc.com
Servidor e cliente VNC gratuito TightVNC para Windows, Mac OS e Linux
http://www.tightvnc.com/
OnLive Games
http://games.onlive.com/
D seu voto em www.devmedia.com.br/netmagazine/feedback
Ajude-nos a manter a qualidade da revista!
Voc gostou deste artigo?
Criando uma aplicao para conexes remotas Criando uma aplicao para conexes remotas
Edio 110 .Net Magazine 67
C
M
Y
CM
MY
CY
CMY
K
Porta80_AnINst.pdf 1 18/09/2011 14:58:37
Criando uma aplicao para conexes remotas
68 .Net Magazine Edio 110