Escolar Documentos
Profissional Documentos
Cultura Documentos
k19-k32 - Desenvolvimento Web Com ASP - NET MVC 4 PDF
k19-k32 - Desenvolvimento Web Com ASP - NET MVC 4 PDF
Desenvolvimento Web
com ASP.NET MVC 4
Desenvolvimento Web com ASP.NET MVC 4
30 de agosto de 2013
Sumrio i
Sobre a K19 1
Seguro Treinamento 2
Termo de Uso 3
Cursos 4
1 Banco de Dados 1
1.1 Sistemas Gerenciadores de Banco de Dados . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 SQL Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Bases de Dados (Databases) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.4 Tabelas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.5 CRUD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.6 Chaves Primria e Estrangeira . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.7 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2 ADO.NET 23
2.1 Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.2 ODBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.3 ODBC Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.4 Criando uma conexo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.5 Inserindo registros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.6 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.7 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.8 SQL Injection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.9 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.10 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.11 Listando registros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.12 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.13 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.14 Connection Factory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
www.facebook.com/k19treinamentos i
S UMRIO ii
3 Entity Framework 37
3.1 Mltiplas sintaxes da linguagem SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.2 Orientao a Objetos VS Modelo Relacional . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.3 Ferramentas ORM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.4 Instalando o Entity Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.5 Configurao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
3.6 Convenes de Mapeamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.7 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.8 Data Annotations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
3.9 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.10 Gerenciamento de entidades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.11 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
3.12 Repositrios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
6 Camada de Apresentao 93
6.1 Razor e ASPX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
6.2 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
6.3 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
6.4 ViewBag e Strogly Typed Views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
6.5 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
6.6 HTML Helpers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
6.7 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
6.8 Layouts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
6.9 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
6.10 Partial views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
ii www.k19.com.br
iii S UMRIO
8 Validao 143
8.1 Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
8.2 View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
8.3 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
8.4 Anotaes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
8.5 Validao no lado do Cliente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
8.6 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
9 Sesso 153
9.1 Identificando os navegadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
9.2 Sesses no ASP.NET MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
9.3 Session Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
9.4 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
10 Filtros 161
10.1 Tipos de Filtros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
10.2 Filtro de Autorizao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
10.3 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
10.4 Filtro de Ao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
10.5 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
10.6 Filtro de Resultado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
10.7 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
10.8 Filtro de Exceo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
10.9 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
www.facebook.com/k19treinamentos iii
S UMRIO iv
B Projeto 197
B.1 Modelo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
B.2 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
B.3 Persistncia - Mapeamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
B.4 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
B.5 Persistncia - Configurao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
B.6 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
B.7 Persistncia - Repositrios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
B.8 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
B.9 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
B.10 Apresentao - Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
B.11 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
B.12 Cadastrando e Listando Selees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
B.13 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
B.14 Removendo Selees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
B.15 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
B.16 Cadastrando, Listando e Removendo Jogadores . . . . . . . . . . . . . . . . . . . . . . . 210
B.17 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
B.18 Removendo Jogadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
B.19 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
B.20 Membership e Autorizao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
B.21 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
B.22 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
B.23 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
B.24 Controle de Erro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
B.25 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
B.26 Enviando email . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
B.27 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
C Respostas 231
iv www.k19.com.br
1 S UMRIO
Sobre a K19
A K19 uma empresa especializada na capacitao de desenvolvedores de software. Sua equipe
composta por profissionais formados em Cincia da Computao pela Universidade de So Paulo
(USP) e que possuem vasta experincia em treinamento de profissionais para rea de TI.
Visando a mxima qualidade, a K19 mantm as suas apostilas em constante renovao e melho-
ria, oferece instalaes fsicas apropriadas para o ensino e seus instrutores esto sempre atualizados
didtica e tecnicamente.
www.facebook.com/k19treinamentos 1
S UMRIO 2
Seguro Treinamento
Na K19 o aluno faz o curso quantas vezes quiser!
Comprometida com o aprendizado e com a satisfao dos seus alunos, a K19 a nica que pos-
sui o Seguro Treinamento. Ao contratar um curso, o aluno poder refaz-lo quantas vezes desejar
mediante a disponibilidade de vagas e pagamento da franquia do Seguro Treinamento.
As vagas no preenchidas at um dia antes do incio de uma turma da K19 sero destinadas ao
alunos que desejam utilizar o Seguro Treinamento. O valor da franquia para utilizar o Seguro Treina-
mento 10% do valor total do curso.
2 www.k19.com.br
3 S UMRIO
Termo de Uso
Termo de Uso
Todo o contedo desta apostila propriedade da K19 Treinamentos. A apostila pode ser utilizada
livremente para estudo pessoal . Alm disso, este material didtico pode ser utilizado como material
de apoio em cursos de ensino superior desde que a instituio correspondente seja reconhecida pelo
MEC (Ministrio da Educao) e que a K19 seja citada explicitamente como proprietria do material.
proibida qualquer utilizao desse material que no se enquadre nas condies acima sem
o prvio consentimento formal, por escrito, da K19 Treinamentos. O uso indevido est sujeito s
medidas legais cabveis.
www.facebook.com/k19treinamentos 3
S UMRIO 4
TR
EIN
AM
EN
TR
TO
EIN
S
TREINAMENTOS
AM
EN
TO
S
Conhea os nossos cursos
www.k19.com.br/cursos
4 www.k19.com.br
CAPTULO
B ANCO DE D ADOS
1
Em geral, as aplicaes necessitam armazenar dados de forma persistente para consult-los pos-
teriormente. Por exemplo, a aplicao de uma livraria precisa armazenar os dados dos livros e dos
autores de forma persistente.
Suponha que esses dados sejam armazenados em arquivos do sistema operacional. Vrios fato-
res importantes nos levam a descartar tal opo. A seguir, apresentamos as principais dificuldades a
serem consideradas na persistncia de dados.
Integridade: Restries relacionadas aos dados armazenados devem ser respeitadas para que as in-
formaes estejam sempre consistentes.
Consulta: O tempo gasto para realizar as consultas aos dados armazenados deve ser o menor poss-
vel.
Considerando todos esses aspectos, conclumos que um sistema complexo seria necessrio para
persistir as informaes de uma aplicao de maneira adequada. Felizmente, tal tipo de sistema j
existe e conhecido como Sistema Gerenciador de Banco de Dados (SGBD).
Oracle Database
SQL Server
www.facebook.com/k19treinamentos 1
B ANCO DE D ADOS 2
MySQL Server
PostgreSQL
SQL Server
Neste treinamento, utilizaremos o SQL Server Express, que mantido pela Microsoft. O SQL Server
Express pode ser obtido a partir do site:
http://www.microsoft.com/express/Database/.
Para interagir com o SQL Server Express, utilizaremos um cliente com interface grfica chamado
de Microsoft SQL Server Management Studio Express.
Suponha que os dados fossem mantidos sem nenhuma separao lgica. Implementar regras
de segurana especficas seria extremamente complexo. Tais regras criam restries quanto ao con-
tedo que pode ser acessado por cada usurio. Por exemplo, determinado usurio poderia ter per-
misso de acesso aos dados dos clientes do banco, mas no s informaes dos produtos da loja
virtual, ou dos livros da livraria.
Para criar uma base de dados no SQL Server Express, utilizamos o comando CREATE DATABASE.
2 www.k19.com.br
3 B ANCO DE D ADOS
www.facebook.com/k19treinamentos 3
B ANCO DE D ADOS 4
Repare que alm da base de dados livraria h outras bases. Essas bases foram criadas automati-
camente pelo prprio SQL Server Express para teste ou para guardar algumas configuraes.
Quando uma base de dados no mais necessria, ela pode ser removida atravs do comando
DROP DATABASE.
Tabelas
Um servidor de banco de dados dividido em bases de dados com o intuito de separar as informa-
es de domnios diferentes. Nessa mesma linha de raciocnio, podemos dividir os dados de uma
base a fim de agrup-los segundo as suas correlaes. Essa separao feita atravs de tabelas. Por
exemplo, no sistema de um banco, interessante separar o saldo e o limite de uma conta, do nome e
CPF de um cliente. Ento, poderamos criar uma tabela para os dados relacionados s contas e outra
para os dados relacionados aos clientes.
Cliente Conta
nome idade cpf numero saldo limite
Jos 27 31875638735 1 1000 500
Maria 32 30045667856 2 2000 700
Tabela 1.1: Tabelas para armazenar os dados relacionados aos clientes e s contas
Uma tabela formada por registros (linhas) e os registros so formados por campos (colunas).
Por exemplo, considere uma tabela para armazenar as informaes dos clientes de um banco. Cada
registro dessa tabela armazena em seus campos os dados de um determinado cliente.
As tabelas no SQL Server Express so criadas atravs do comando CREATE TABLE. Na criao de
uma tabela necessrio definir quais so os nomes e os tipos das colunas.
4 www.k19.com.br
5 B ANCO DE D ADOS
www.facebook.com/k19treinamentos 5
B ANCO DE D ADOS 6
No SQL Server os nomes das tabelas so precedidas pelo ID do usurio que possui a tabela. No
caso do usurio sa, o ID dbo. Portanto o nome da tabela Livros fica dbo.Livros.
Se uma tabela no for mais desejada ela pode ser removida atravs do comando DROP TABLE.
CRUD
As operaes bsicas para manipular os dados persistidos so: inserir, ler, alterar e remover.
Essas operaes so realizadas atravs de uma linguagem de consulta denominada SQL (Structu-
red Query Language). Essa linguagem oferece quatro comandos bsicos: INSERT, SELECT, UPDATE
6 www.k19.com.br
7 B ANCO DE D ADOS
e DELETE. Esses comandos so utilizados para inserir, ler, alterar e remover registros, respectiva-
mente.
www.facebook.com/k19treinamentos 7
B ANCO DE D ADOS 8
8 www.k19.com.br
9 B ANCO DE D ADOS
Nesse momento, teramos duas tabelas (Livro e Editora). Constantemente, a aplicao da livraria
dever descobrir qual a editora de um determinado livro ou quais so os livros de uma determinada
editora. Para isso, os registros da tabela Editora devem estar relacionados aos da tabela Livro.
Na tabela Livro, poderamos adicionar uma coluna para armazenar o nome da editora dos livros.
Dessa forma, se algum quiser recuperar as informaes da editora de um determinado livro, deve
www.facebook.com/k19treinamentos 9
B ANCO DE D ADOS 10
consultar a tabela Livro para obter o nome da editora correspondente. Depois, com esse nome, deve
consultar a tabela Editora para obter as informaes da editora.
Porm, h um problema nessa abordagem. A tabela Editora aceita duas editoras com o mesmo
nome. Dessa forma, eventualmente, no conseguiramos descobrir os dados corretos da editora de
um determinado livro. Para resolver esse problema, deveramos criar uma restrio na tabela Editora
que proba a insero de editoras com o mesmo nome.
Para resolver esse problema no SQL Server Express, poderamos adicionar a propriedade UNI-
QUE no campo nome da tabela Editora. Porm, ainda teramos mais um problema. Na tabela Li-
vro, poderamos adicionar registros vinculados a editoras inexistentes, pois no h nenhuma relao
explcita entre as tabelas. Para solucionar esses problemas, devemos utilizar o conceito de chave
primria e chave estrangeira.
Toda tabela pode ter uma chave primria, que um conjunto de um ou mais campos que de-
vem ser nicos para cada registro. Normalmente, um campo numrico escolhido para ser a chave
primria de uma tabela, pois as consultas podem ser realizadas com melhor desempenho.
Ento, poderamos adicionar um campo numrico na tabela Editora e torn-lo chave primria.
Vamos chamar esse campo de id. Na tabela Livro, podemos adicionar um campo numrico chamado
editora_id que deve ser utilizado para guardar o valor da chave primria da editora correspondente
ao livro. Alm disso, o campo editora_id deve estar explicitamente vinculado com o campo id da
tabela Editora. Para estabelecer esse vnculo, o campo editora_id da tabela Livro deve ser uma chave
estrangeira associada chave primria da tabela Editora.
Uma chave estrangeira um conjunto de uma ou mais colunas de uma tabela que possuem va-
lores iguais aos da chave primria de outra tabela.
Com a definio da chave estrangeira, um livro no pode ser inserido com o valor do campo
editora_id invlido. Caso tentssemos fazer isso, obteramos uma mensagem de erro.
Exerccios de Fixao
10 www.k19.com.br
11 B ANCO DE D ADOS
2 Caso exista uma base de dados chamada Livraria, remova-a conforme a figura abaixo:
www.facebook.com/k19treinamentos 11
B ANCO DE D ADOS 12
3 Crie uma nova base de dados chamada livraria, conforme mostrado na figura abaixo. Voc vai
utilizar esta base nos exerccios seguintes.
12 www.k19.com.br
13 B ANCO DE D ADOS
www.facebook.com/k19treinamentos 13
B ANCO DE D ADOS 14
Altere os campos para torn-los obrigatrios, NO permitindo que eles fiquem em branco NU LL.
14 www.k19.com.br
15 B ANCO DE D ADOS
O campo Id dever ser incrementado automaticamente. Defina ele com a propriedade Identity
segundo a figura abaixo:
www.facebook.com/k19treinamentos 15
B ANCO DE D ADOS 16
Lembrando de NO marcar a opo ALLOW NULL. Alm disso o campo Id deve ser uma chave
primria e automaticamente incrementada.
Voc precisa tornar o campo EditoraId uma chave estrangeira. Clique com o boto direito sobre
a coluna EditoraId e selecione a opo Relantioships..., conforme a figura abaixo:
16 www.k19.com.br
17 B ANCO DE D ADOS
Devemos informar qual a chave primria que a coluna EditoraId da tabela Livros faz referncia.
www.facebook.com/k19treinamentos 17
B ANCO DE D ADOS 18
Para isto, informe a tabela Editoras como Primary Key Table e indique a coluna Id como a chave
primria referenciada. Selecione a coluna EditoraId como a coluna que ir fazer referncia a chave
primria da tabela Editoras.
18 www.k19.com.br
19 B ANCO DE D ADOS
7 Consulte os registros da tabela Editoras, e em seguida consulte a tabela Livros. Veja exemplos
logo abaixo:
www.facebook.com/k19treinamentos 19
B ANCO DE D ADOS 20
20 www.k19.com.br
21 B ANCO DE D ADOS
11 Remova alguns registros da tabela Editoras. Preste ateno para no remover uma editora que
tenha algum livro relacionado j adicionado no banco. Veja o exemplo abaixo:
www.facebook.com/k19treinamentos 21
B ANCO DE D ADOS 22
12 Faa uma consulta para buscar todos os livros de uma determinada editora. Veja um exemplo
na figura abaixo:
22 www.k19.com.br
CAPTULO
ADO.NET
2
No captulo anterior, aprendemos que utilizar bancos de dados uma tima alternativa para
armazenar os dados de uma aplicao. Entretanto, voc deve ter percebido que as interfaces dispo-
nveis para interagir com o SQL Server Express no podem ser utilizadas por qualquer pessoa. Para
utiliz-las, necessrio conhecer a linguagem SQL e os conceitos do modelo relacional. Em geral, as
interfaces dos outros SGDBs exigem os mesmos conhecimentos.
Figura 2.1: Usurios comuns no possuem conhecimento sobre SQL ou sobre o modelo relacional
Para resolver esse problema, podemos desenvolver aplicaes com interfaces que no exijam co-
nhecimentos tcnicos de SQL ou do modelo relacional para serem utilizadas. Dessa forma, usurios
comuns poderiam manipular as informaes do banco de dados atravs dessas aplicaes. Nessa
abordagem, os usurios interagem com as aplicaes e as aplicaes interagem com os SGDBs.
www.k19.com.br
Cadastro de Funcionrios
Nome:
Cdigo:
Salrio:
www.facebook.com/k19treinamentos 23
ADO.NET 24
Driver
As aplicaes interagem com os SGDBs atravs de troca de mensagens. Os SGDBs definem o formato
das mensagens. Para no sobrecarregar o canal de comunicao entre as aplicaes e os SGDBs, as
mensagens trocadas devem ocupar o menor espao possvel. Geralmente, protocolos binrios so
mais apropriados para reduzir o tamanho das mensagens e consequentemente diminuir a carga do
canal de comunicao. Por isso, os SGDBs utilizam protocolos binrios.
rollback
find
getReference
persist begin
getTransaction
commit
10110
111000
10010
Figura 2.3: Diminuindo o tamanho das mensagens para no sobrecarregar o meio de comunicao
Mensagens binrias so facilmente interpretadas por computadores. Por outro lado, so com-
plexas para um ser humano compreender. Dessa forma, o trabalho dos desenvolvedores seria muito
complexo, aumentando o custo para o desenvolvimento e manuteno das aplicaes.
10 010 11 110 01
1011010111
11 1 1 0
0010110011
0
0010110001
01 00 01
1101011101
10 111 10 110 11
01 01
1010111101
1
1
0101101001
0 01 01 00
0 01 0 1
11
0111011100 0111011100
01 101 11
0101101001
1
1010111101
1 010
1101011101 0010110001
0
0010110011
1
1011010111
Para resolver esse problema e facilitar o desenvolvimento das aplicaes, as empresas propriet-
24 www.k19.com.br
25 ADO.NET
rias dos SGDBs, normalmente, desenvolvem e distribuem drivers de conexo. Um driver de conexo
atua como um intermedirio entre as aplicaes e os SGDBs.
Mais Sobre
Em alguns casos, o protocolo binrio de um determinado SGDB fechado. Consequen-
temente, a nica maneira de se comunicar com ele atravs de um driver de conexo
oferecido pelo fabricante desse SGDB.
ODBC
Suponha que os proprietrios dos bancos de dados desenvolvessem os drivers de maneira total-
mente independente. Consequentemente, cada driver teria sua prpria interface, ou seja, seu pr-
prio conjunto de instrues. Dessa maneira, o desenvolvedor da aplicao precisa conhecer as ins-
trues de cada um dos drivers dos respectivos bancos que ele for utilizar.
ODBC Manager
Para que drivers ODBC possam ser instalados em uma mquina e as aplicaes consigam utiliz-los
necessrio ter o ODBC Manager, que j vem instalado no Windows.
O driver de conexo ODBC j est disponvel para utilizao, podemos consultar o ODBC Mana-
ger do Windows. O ODBC Manager pode ser executado atravs do item Ferramentas Administrati-
vas do Painel de Controle.
www.facebook.com/k19treinamentos 25
ADO.NET 26
Inserindo registros
Estabelecida a conexo com o banco de dados, j podemos executar comandos. Por exemplo, pos-
svel inserir registros nas tabelas. O primeiro passo para executar um comando defini-lo em lin-
guagem SQL de acordo com a sintaxe do SGDB utilizado.
26 www.k19.com.br
27 ADO.NET
Mais Sobre
O caractere @ antes de um valor literal do tipo string indica que os caracteres dentro
da string no devem ser processados como caracteres especiais.
Por fim, o comando pode ser executado atravs do mtodo ExecuteNonQuery(). A conexo deve
ser aberta antes de executar o comando.
1 conexao . Open () ;
2 comando . ExecuteNonQuery () ;
Importante
A mesma conexo pode ser reaproveitada para executar vrias operaes. Quando no
houver mais operaes a serem executadas, devemos finalizar a conexo ODBC atravs
do mtodo Close(). Finalizar as conexes ODBC que no so mais necessrias importante
pois libera recursos no SGBD.
1 conexao . close () ;
Mais Sobre
Em C#, para evitar que o uma conexo no seja fechada aps a sua utilizao, podemos
aplicar um bloco using.
No cdigo acima, quando o bloco using que est associado conexo ODBC terminar, automa-
ticamente, essa conexo ser fechada.
Exerccios de Fixao
www.facebook.com/k19treinamentos 27
ADO.NET 28
2 Crie uma classe chamada InsereEditora no projeto ODBC para inserir registros na tabela Edi-
toras.
Exerccios Complementares
1 Crie uma classe chamada InsereLivro no projeto ODBC para inserir registros na tabela Livros.
SQL Injection
A implementao da insero de registros feita anteriormente possui uma falha grave. Os dados ob-
tidos do usurio atravs do teclado no so tratados antes de serem enviados para o SGDB.
Esses dados podem conter caracteres especiais. Se esses caracteres no so tratados, o compor-
tamento esperado da operao afetado. Eventualmente, registros no so inseridos como deveriam
ou brechas de segurana podem se abrir.
28 www.k19.com.br
29 ADO.NET
Observe que o caractere aspas simples aparece cinco vezes no cdigo SQL acima. O SGDB no
saberia dizer onde de fato termina o nome da editora. Ao tentar executar esse cdigo, um erro de
sintaxe lanado pelo SQL Server. Para resolver esse problema manualmente, devemos adicionar
dois caracteres seguidos.
Os valores recebidos dos usurios devem ser analisados e os caracteres especiais contidos nesses
valores devem ser tratados. Esse processo extremamente trabalhoso, pois o conjunto de caracteres
especiais e a forma de trat-los diferente em cada SGDB.
A responsabilidade do tratamento dos caracteres especiais contidos nos valores de entrada dos
usurios pode ser repassada para os drivers ODBC. Dessa forma, o cdigo das aplicaes se torna
independente das particularidades desse processo para cada SGDB.
Mais Sobre
O processo de tratamento dos caracteres especiais das entradas dos usurios denomi-
nado sanitize.
Observe que a sentena SQL foi definida com parmetros atravs do caractere ?. Antes de exe-
cutar o comando, necessrio atribuir valores aos parmetros. Isso feito com o mtodo AddWith-
Value(). Esse mtodo realiza a tarefa de sanitizar os valores enviados pelo usurio.
Exerccios de Fixao
3 Tente causar um erro de SQL Injection ao inserir editoras com a classe InsereEditora. (Dica:
tente entradas com aspas simples)
www.facebook.com/k19treinamentos 29
ADO.NET 30
4 Altere o cdigo da classe InsereEditora para eliminar o problema do SQL Injection. Observe o
cdigo abaixo:
5 Agora tente causar novamente o problema de SQL Injection ao inserir novas editoras.
Exerccios Complementares
2 Provoque um erro de SQL Injection na classe InsereLivro. (Dica: tente entradas com aspas
simples.)
4 Agora tente causar novamente o problema de SQL Injection ao inserir novos livros.
Listando registros
Depois de inserir alguns registros, interessante consultar os dados das tabelas para conferir se a in-
sero foi realizada com sucesso.
30 www.k19.com.br
31 ADO.NET
A diferena que para executar um comando de consulta necessrio utilizar o mtodo Execu-
teReader() ao invs do ExecuteNonQuery(). Esse mtodo devolve um objeto da classe System.Da-
ta.Odbc.OdbcDataReader.
Os dados contidos no OdbcDataReader podem ser acessados atravs dos nomes das colunas.
O cdigo acima mostra como os campos do primeiro registro do resultado da consulta so recu-
perados. Agora, para recuperar os outros registros necessrio avanar o OdbcDataReader atravs
do mtodo Read().
O prprio mtodo Read() devolve um valor booleano para indicar se o reader conseguiu avanar
para o prximo registro. Quando esse mtodo devolver false significa que no h mais registros
para serem recuperados.
Exerccios de Fixao
www.facebook.com/k19treinamentos 31
ADO.NET 32
6 Insira algumas editoras utilizando a classe InsereEditora que voc criou nos exerccios anteri-
ores.
7 Adicione uma nova classe ao projeto ODBC chamada ListaEditora. O objetivo listar as edi-
toras que foram salvas no banco. Veja o cdigo dessa classe.
Exerccios Complementares
Connection Factory
Voc deve ter percebido que para cada ao executada no banco de dados, ns precisamos criar
uma conexo. Isso gera um problema relacionado string de conexo ficar armazenada em diversos
locais. Imagine que o driver do banco foi atualizado e mudamos a sua verso. Isso implicaria fa-
zer diversas alteraes no cdigo em cada ocorrncia da string de conexo, tornando o cdigo mais
suscetvel a erros e dificultando a sua manuteno.
Para resolver esta situao, ns poderamos criar uma classe responsvel pela criao e distri-
buio de conexes, mantendo assim uma nica referncia para a string de conexo, e qualquer
alterao no modo em que nos conectamos base de dados, s implica mudanas nesta classe.
32 www.k19.com.br
33 ADO.NET
Exerccios de Fixao
1 using System ;
2 using System . Data . Odbc ;
3 using System . Text ;
4
5 namespace Odbc
6 {
7 static class ConnectionFactory
8 {
9 public static OdbcConnection CreateConnection ()
10 {
11 string driver = @ " SQL Server " ;
12 string servidor = @ " MARCELO - PC \ SQLEXPRESS " ;
13 string baseDeDados = @ " livraria " ;
14 string usuario = @ " sa " ;
15 string senha = @ " sa " ;
16
17 StringBuilder connectionString = new StringBuilder () ;
18 connectionString . Append ( " driver = " ) ;
19 connectionString . Append ( driver ) ;
20 connectionString . Append ( " ; server = " ) ;
21 connectionString . Append ( servidor ) ;
22 connectionString . Append ( " ; database = " ) ;
23 connectionString . Append ( baseDeDados ) ;
24 connectionString . Append ( " ; uid = " ) ;
25 connectionString . Append ( usuario ) ;
26 connectionString . Append ( " ; pwd = " ) ;
www.facebook.com/k19treinamentos 33
ADO.NET 34
9 Altere as classes InsereEditora e ListaEditora para que elas utilizem a fbrica de conexo.
Execute-as novamente.
34 www.k19.com.br
35 ADO.NET
22 }
23 }
24 }
25 }
26 }
Exerccios Complementares
6 Altere as classes InsereLivro e ListaLivro para que elas utilizem a fbrica de conexo. Execute-
as novamente.
Desafios
www.facebook.com/k19treinamentos 35
ADO.NET 36
36 www.k19.com.br
CAPTULO
E NTITY F RAMEWORK
3
Mltiplas sintaxes da linguagem SQL
No captulo anterior, utilizamos conexes ODBC para fazer uma aplicao C# interagir com os
SGDBs. Nessa interao, as consultas so definidas com a linguagem SQL. A sintaxe dessa linguagem
diferente em cada SGDB. Dessa forma, a complexidade do trabalho dos desenvolvedores aumenta.
Para resolver esse problema, as consultas deveriam ser definidas atravs de um mecanismo indepen-
dente da linguagem SQL.
SELECT * FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY autor ASC) AS rownumber,
id, titulo, autor
FROM livros
) WHERE rownumber <= 100
Driver Oracle
ODBC
www.facebook.com/k19treinamentos 37
E NTITY F RAMEWORK 38
tbl_editoras
Livro id nome
id = 1 1 Cultura
titulo = Os Lusadas
2 FTDA
autor = Lus Vaz de
Cames 3 Globo
editora = 1
4 Scipione
Editora
id = 1
nome = Livraria Cultura
tbl_livros
Livro
id = 2 id titulo autor editora_id
titulo = Vidas Secas 1 Os Lusadas Lus Vaz de Cames 1
autor = Graciliano
Ramos 2 Vidas Secas Graciliano Ramos 1
editora = 1 3 Dom Casmurro Machado de Assis 3
4 O Cortio Alusio Azevedo 2
Ferramentas ORM
Para facilitar a comunicao entre aplicaes C# que seguem o modelo orientado a objetos e os
SGDBs que seguem o modelo relacional, podemos utilizar ferramentas que automatizam a transio
de dados entre as aplicaes e os SGDBs. Essas ferramentas so conhecidas como ferramentas ORM
(Object Relational Mapper).
38 www.k19.com.br
39 E NTITY F RAMEWORK
tbl_livros
Figura 3.3: Transformao dos dados do Modelo Relacional para o Modelo Orientado a Objetos
tbl_livros
Livro Livro id titulo autor editora_id
id = 1 id = 2 FERRAMENTA
1 Os Lusadas Lus Vaz de Cames 1
titulo = Os Lusadas
autor = Lus Vaz de
titulo = Vidas Secas
autor = Graciliano
ORM
2 Vidas Secas Graciliano Ramos 1
Figura 3.4: Transformao dos dados do Modelo Orientado a Objetos para o Modelo Relacional
A instalao do Entity Framework em um projeto do Visual Studio 2012 pode ser facilmente
realizada atravs do Package Manager Console. Veja o comando de instalao a seguir.
Mais Sobre
O Entity Framework tambm pode ser instalado atravs do Manage NuGet Packa-
ges. Basicamente, o Manage NuGet Packages a alternativa visual ao Package Manager
Console.
www.facebook.com/k19treinamentos 39
E NTITY F RAMEWORK 40
Configurao
40 www.k19.com.br
41 E NTITY F RAMEWORK
aplicao.
Para alterar as configuraes de conexo com o banco de dados, podemos defini-las no arquivo
de configurao da aplicao. Para aplicaes web, devemos alterar o arquivo Web.config. Por outro
lado, para aplicaes desktop, devemos alterar o arquivo App.config. Veja o exemplo abaixo.
Convenes de Mapeamento
Por padro, no Entity Framework, o mapeamento das entidades segue as regras do Code First.
Considere as entidades Livro e Editora definidas abaixo.
As entidades devem ser registradas em um DbContext. Para registrar uma entidade, basta de-
finir uma propriedade do tipo DbSet. Veja o exemplo abaixo.
1 public namespace EF
2 {
3 public class K19Context : DbContext
www.facebook.com/k19treinamentos 41
E NTITY F RAMEWORK 42
4 {
5 public DbSet < Editora > Editoras { get ; set ; }
6 public DbSet < Livro > Livros { get ; set ; }
7 }
8 }
De acordo com as convenes do Code First, as entidades Editora e Livro sero mapeadas
para tabelas chamadas Editoras e Livroes respectivamente. Observe que os nomes das entidades
foram pluralizados seguindo as regras da lngua inglesa para definir os nomes das tabelas.
Alm disso, por padro, essas tabelas sero criadas em uma base de dados chamada EF.K19Context.
Esse nome corresponde ao full qualified name da classe K19Context.
Mais Sobre
Para desabilitar a pluralizao aplicada no nome das tabelas, necessrio sobrescrever
o mtodo OnModelCreating() da classe DbContext.
Mais Sobre
Nas prximas verses do Entity Framework, as regras de pluralizao podero ser perso-
nalizadas. Dessa forma, ser possvel, por exemplo, substituir as regras da lngua inglesa
pelas regras da lngua portuguesa.
Mais Sobre
Podemos modificar o nome da base de dados escolhido por padro. Para isso, basta
adicionar um construtor na classe que define o DbContext semelhante ao mostrado
no cdigo abaixo.
42 www.k19.com.br
43 E NTITY F RAMEWORK
Primary Key
O Entity Framework assumir como identificador de uma entidade, a propriedade cujo nome
seja ID ou EntidadeID escrito com letras maisculas e/ou minsculas. Essa propriedade ser mape-
ada para uma coluna definida no banco de dados como chave primria da tabela correspondente a
entidade. Veja os exemplos abaixo.
Se o tipo da propriedade utilizada como identificador de uma entidade for numrico, os valores
da coluna correspondente a essa propriedade sero gerados pelo banco de dados. Isso significa que,
no SQL Server, a coluna ser definida com a opo Identity.
Complex Types
Considere a seguinte entidade.
Do ponto de vista da modelagem orientada a objetos, deveramos refatorar essa classe separando
as propriedades relacionadas aos endereos de um contato.
www.facebook.com/k19treinamentos 43
E NTITY F RAMEWORK 44
Como nenhuma propriedade da classe Endereco se enquadra nas convenes de Primary Key e
supondo que nenhuma propriedade tenha sido mapeada explicitamente para uma coluna definida
como chave primria, o Entity Framework assumir que essa classe um Complex Type. Alm disso,
um Complex Type no pode referenciar uma entidade atravs de uma propriedade.
As classes Contato e Endereco sero mapeadas para uma nica tabela chamada Contatoes. Essa
tabela possuir a estrutura mostrada na imagem a seguir.
Essas duas entidades sero mapeadas para as tabelas Livroes e Editoras. Na tabela Livroes,
ser adicionada uma chave estrangeira chamada Editora_EditoraID referenciado a chave primria
da tabela Editora. Observe na imagem abaixo a estrutura das tabelas.
44 www.k19.com.br
45 E NTITY F RAMEWORK
Por outro lado, se na entidade Livro uma coleo de editoras for definida como propriedade e
de forma anloga uma coleo de livros for definida como propriedade na entidade Editora ento
uma terceira tabela ser criada no banco de dados para representar esse relacionamento muitos
para muitos (many to many).
www.facebook.com/k19treinamentos 45
E NTITY F RAMEWORK 46
Type Discovery
Quando duas entidades esto relacionadas, no necessrio que ambas sejam registradas no
DbContext. Apenas a entidade principal necessita ser registrada. Por exemplo, considere as seguin-
tes entidades.
46 www.k19.com.br
47 E NTITY F RAMEWORK
4 }
Se as duas entidades forem registradas, tanto os livros quanto as editoras podem ser obtidos di-
retamente pelo DbContext. Agora, se apenas a entidade Editora for registrada, somente as editoras
podem ser obtidas diretamente pelo DbContext e os livros seriam obtidos somente atravs das edi-
toras.
Exerccios de Fixao
1 Abra o Visual Studio Express 2012 for Desktop; Crie um projeto do tipo Console Application em
C# chamado K19EntityFramework.
www.facebook.com/k19treinamentos 47
E NTITY F RAMEWORK 48
1 namespace K19EntityFramework
2 {
3 // complex type
4 public class Endereco
5 {
6 public string Logradouro { get ; set ; }
7
8 public int Numero { get ; set ; }
9
10 public string CEP { get ; set ; }
11 }
12 }
1 namespace K19EntityFramework
2 {
3 public class Aluno
4 {
5 public int AlunoID { get ; set ; }
6
7 public string Nome { get ; set ; }
8
9 public Endereco Endereco { get ; set ; }
10 }
11 }
48 www.k19.com.br
49 E NTITY F RAMEWORK
1 namespace K19EntityFramework
2 {
3 public class Professor
4 {
5 public int ProfessorID { get ; set ; }
6
7 public string Nome { get ; set ; }
8
9 public Endereco Endereco { get ; set ; }
10 }
11 }
1 namespace K19EntityFramework
2 {
3 public class Turma
4 {
5 public int TurmaId { get ; set ; }
6
7 public int Vagas { get ; set ; }
8
9 public Professor Professor { get ; set ; }
10
11 public ICollection < Aluno > Alunos { get ; set ; }
12 }
13 }
1 namespace K19EntityFramework
2 {
3 public class K19Context : DbContext
4 {
5 public DbSet < Turma > Turmas { get ; set ; }
6
7 public DbSet < Aluno > Alunos { get ; set ; }
8
9 public DbSet < Professor > Professores { get ; set ; }
10 }
11 }
1 namespace K19EntityFramework
2 {
3 public class Teste
4 {
5 static void Main ( string [] args )
6 {
7 using ( var ctx = new K19Context () )
8 {
9 Aluno a1 = new Aluno
www.facebook.com/k19treinamentos 49
E NTITY F RAMEWORK 50
10 {
11 Nome = " Amanda Guerra " ,
12 Endereco = new Endereco
13 {
14 Logradouro = " Rua Amalera " ,
15 Numero = 1789 ,
16 CEP = " 00157 -001 "
17 }
18 };
19
20 Aluno a2 = new Aluno
21 {
22 Nome = " Marcelo Martins " ,
23 Endereco = new Endereco
24 {
25 Logradouro = " Rua Zaul " ,
26 Numero = 2907 ,
27 CEP = " 09147 -001 "
28 }
29 };
30
31 Professor p = new Professor
32 {
33 Nome = " Jonas Hirata " ,
34 Endereco = new Endereco
35 {
36 Logradouro = " Rua Mervelha " ,
37 Numero = 8367 ,
38 CEP = " 00876 -100 "
39 }
40 };
41
42 Turma t = new Turma
43 {
44 Vagas = 10 ,
45 Alunos = new List < Aluno >()
46 };
47
48 t . Professor = p ;
49 t . Alunos . Add ( a1 ) ;
50 t . Alunos . Add ( a2 ) ;
51
52 ctx . Turmas . Add ( t ) ;
53 ctx . SaveChanges () ;
54 }
55 }
56 }
57 }
Data Annotations
50 www.k19.com.br
51 E NTITY F RAMEWORK
Table e Column
No Entity Framework, os nomes das tabelas e das colunas so definidos por conveno. Contudo,
podemos personaliz-los de acordo com a necessidade atravs das anotaes Table e Column.
DatabaseGenerated
Por padro, quando a propriedade correspondente chave primria de uma tabela numrica,
os valores dessa chave sero gerados pelo banco de dados. Podemos alterar esse comportamento
atravs da anotao DatabaseGenerated.
www.facebook.com/k19treinamentos 51
E NTITY F RAMEWORK 52
Key
Considere a seguinte classe.
Required
Uma propriedade pode ser definida explicitamente como obrigatria atravs da anotao Requi-
red. No banco de dados, as colunas correspondentes s propriedades obrigatrias sero definidas
com a opo not null.
MaxLength e MinLength
52 www.k19.com.br
53 E NTITY F RAMEWORK
NotMapped
Considere a seguinte classe.
Observe que a propriedade Idade pode ser calculada a partir da propriedade DataDeNascimento.
Portanto, no necessrio armazenar o valor da idade no banco de dados. Nesses casos, podemos
utilizar a anotao NotMapped e indicar quais propriedades no devem ser mapeadas nas tabelas.
InverseProperty
Considere as seguintes entidades.
www.facebook.com/k19treinamentos 53
E NTITY F RAMEWORK 54
Nesse caso, como o Entity Framework no consegue combinar as propriedades das duas entida-
des para estabelecer dois relacionamentos bidirecionais, ele criar no banco de dados quatro chaves
estrangeiras, uma para cada propriedade de navegao das entidades Pessoa e Livro.
Para agrupar as propriedades de navegao das entidades Pessoa e Livro, devemos utilizar a
anotao InverseProperty. Observe o cdigo a seguir.
54 www.k19.com.br
55 E NTITY F RAMEWORK
2 {
3 public int LivroID { get ; set ; }
4
5 public string Titulo { get ; set ; }
6
7 public Pessoa Autor { get ; set ; }
8
9 public Pessoa Revisor { get ; set ; }
10 }
Exerccios de Fixao
1 namespace K19EntityFramework
2 {
3 [ Table ( " tbl_alunos " ) ]
4 public class Aluno
5 {
6 public int AlunoID { get ; set ; }
7
8 [ Required ]
9 public string Nome { get ; set ; }
10
11 public Endereco Endereco { get ; set ; }
12 }
13 }
serve as modificaes na estrutura da tabela Alunoes que passar a se chamar tbl_alunos. Observe
que agora a coluna Nome no pode possuir valores nulos.
Gerenciamento de entidades
As instncias das entidades de uma aplicao que utiliza o Entity Framework so administradas
por objetos do tipo DbContext. Esses objetos so responsveis pelas operaes de insero, remoo,
alterao e consulta. A seguir, mostraremos o funcionamento bsico de um DbContext.
www.facebook.com/k19treinamentos 55
E NTITY F RAMEWORK 56
A primeira regra bsica sobre os DbContexts sempre utiliz-los dentro de um bloco using para
evitar que os recursos utilizados por eles no sejam devidamente fechados.
Persistindo
Para indicar que determinado objeto deve ser persistido no banco de dados, devemos utilizar
o mtodo System.Data.Entity.DbSet.Add(), passando o objeto em questo como parmetro. O
mtodo Add() adiciona o objeto ao contexto com o estado Added.
1 Editora editora = new Editora { Nome = " K19 " , Email = " contato@k19 . com . br " };
2
3 // Adiciona a editora criada ao contexto com estado Added
4 context . Editoras . Add ( editora ) ;
5
6 // Sincroniza o contexto com o banco de dados
7 context . SaveChanges () ;
Buscando
Para obter um objeto que contenha informaes do banco de dados, basta utilizar o mtodo
Find() do DbSet. Devemos passar o identificador do objeto que desejamos recuperar como par-
metro para esse mtodo.
Removendo
Para indicar que determinado objeto deve ser removido, basta utilizar o mtodo System.Da-
ta.Entity.DbSet.Remove(). Esse mtodo marca o objeto para ser removido do banco de dados,
colocando-o no estado Deleted.
56 www.k19.com.br
57 E NTITY F RAMEWORK
Atualizando
Para alterar os dados do registro correspondente a um objeto, basta modificar as suas proprieda-
des. Quando as propriedades de um objeto do contexto so alteradas, o estado Modified associado
a este objeto. Objetos no estado Modified so atualizados no banco de dados quando o mtodo
SaveChanges() chamado.
Listando
Para obter uma listagem com todos os objetos referentes aos registros de uma tabela, podemos
utilizar a Language Integrated Query (LINQ), que nos permite escrever consultas dentro do cdigo
C#.
Exerccios de Fixao
1 namespace K19EntityFramework
2 {
3 public class InsereAluno
4 {
5 static void Main ( string [] args )
6 {
7 using ( var ctx = new K19Context () )
8 {
9 Console . WriteLine ( " Digite o nome do aluno " ) ;
10 string nome = Console . ReadLine () ;
11
12 Console . WriteLine ( " Digite o logradouro do endereo do aluno " ) ;
13 string logradouro = Console . ReadLine () ;
14
www.facebook.com/k19treinamentos 57
E NTITY F RAMEWORK 58
58 www.k19.com.br
59 E NTITY F RAMEWORK
1 namespace K19EntityFramework
2 {
3 public class AlteraAluno
4 {
5 static void Main ( string [] args )
6 {
7 using ( var ctx = new K19Context () )
8 {
9 Aluno a = ctx . Alunos . Find (1) ;
10 a . Nome = a . Nome + " ALTERADO " ;
11
12 ctx . SaveChanges () ;
13 }
14 }
15 }
16 }
1 namespace K19EntityFramework
2 {
3 public class RemoveAluno
4 {
5 static void Main ( string [] args )
6 {
7 using ( var ctx = new K19Context () )
8 {
9 Aluno a = ctx . Alunos . Find (1) ;
10
11 ctx . Alunos . Remove ( a ) ;
12
13 ctx . SaveChanges () ;
14 }
15 }
16 }
17 }
Repositrios
As classes DbContext e DbSet do Entity Framework oferecem recursos suficientes para que os
objetos do domnio sejam persistidos, recuperados, alterados e removidos do banco de dados. Po-
rm, em aplicaes com alta complexidade e grande quantidade de cdigo, espalhar as chamadas
aos mtodos do DbContext e DbSet pode gerar dificuldades na manuteno e no entendimento do
sistema.
Para melhorar a organizao das nossas aplicaes, diminuindo o custo de manuteno e au-
mentando a legibilidade do cdigo, podemos aplicar o padro Repository do DDD (Domain Driven
www.facebook.com/k19treinamentos 59
E NTITY F RAMEWORK 60
Design).
Os repositrios podem trabalhar com objetos prontos na memria ou reconstru-los com dados
obtidos de um banco de dados. O acesso ao banco de dados pode ser realizado atravs de uma
ferramenta ORM como o Entity Framework.
1 using System ;
2 using System . Collections . Generic ;
3 using System . Linq ;
4 using System . Data . Entity ;
5
6 namespace K19
7 {
8 public class EditoraRepository
9 {
10 DbContext context ;
11
12 public EditoraRepository ( DbContext context )
13 {
14 this . context = context ;
15 }
16
17 public void Adiciona ( Editora e )
18 {
19 context . Set < Editora >() . Add ( e ) ;
20 context . SaveChanges () ;
21 }
22
23 public Editora Busca ( int id )
24 {
25 return context . Set < Editora >() . Find ( id ) ;
26 }
27
28 public List < Editora > BuscaTodas ()
29 {
30 var consulta = from e in context . Set < Editora >()
31 select e ;
32 return consulta . ToList () ;
33 }
34 }
35 }
60 www.k19.com.br
CAPTULO
C ODE F IRST M IGRATIONS
4
Code First Migrations
O Entity Framework Code First da Microsoft tem uma funcionalidade que permite controlar as
mudanas no banco de dados que sero realizadas de acordo com as alteraes na camada de mo-
delo da aplicao. Essa funcionalidade chamada de Code First Migrations.
O Code First Migrations foi adicionado na verso 4.3.1 do Entity Framework. Neste captulo uti-
lizaremos o Entity Framework 5.0.
Passo a Passo
Para testar o funcionamento do Code First Migrations, criaremos um projeto no Visual Studio.
Agora, devemos instalar o Entity Framework 5.0. Para isso, utilizaremos o gerenciador de pacotes
Nuget do Visual Studio.
www.facebook.com/k19treinamentos 61
C ODE F IRST M IGRATIONS 62
O Nuget permite que bibliotecas e ferramentas sejam instaladas no Visual Studio. Ao instalar
pacotes no seu projeto, ele adiciona as bibliotecas, referncias e faz as alteraes necessrias nos ar-
quivos de configurao. Mais informaes sobre o Nuget e os pacotes disponveis, acesse o endereo
http://nuget.org/packages
Para instalar o Entity Framework 5.0, basta selecionar o pacote Entity Framework e clicar em
Install.
62 www.k19.com.br
63 C ODE F IRST M IGRATIONS
Aps a instalao do Entity Framework 5.0, adicionaremos uma classe de modelo chamada Editora.
Essa entidade ser mapeada atravs de uma classe chamada K19Context. Para testar, criaremos uma
classe com o mtodo Main(). Observe o cdigo dessas trs classes.
1 namespace EFMigrations
2 {
3 public class Editora
4 {
5 public int Id { get ; set ; }
6 public string Nome { get ; set ; }
7 public string Email { get ; set ; }
8 }
9 }
1 namespace EFMigrations
2 {
3 public class K19Context : DbContext
4 {
5 public DbSet < Editora > Editoras { get ; set ; }
6 }
7 }
1 namespace EFMigrations
2 {
3 class Program
4 {
5 static void Main ( string [] args )
6 {
7 using ( var context = new K19Context () )
www.facebook.com/k19treinamentos 63
C ODE F IRST M IGRATIONS 64
8 {
9 Editora e = new Editora { Nome = " K19 " ,
10 Email = " contato@k19 . com . br " };
11 context . Editoras . Add ( e ) ;
12 context . SaveChanges () ;
13 }
14 }
15 }
16 }
1 namespace EFMigrations
2 {
3 public class Editora
4 {
5 public int Id { get ; set ; }
6 public string Nome { get ; set ; }
7 public string Email { get ; set ; }
8
9 public string Telefone { get ; set ; }
10 }
11 }
64 www.k19.com.br
65 C ODE F IRST M IGRATIONS
Para resolver esse problema, o banco de dados precisa ser atualizado. Para fazer essa atualizao,
o Entity Framework recomenda a utilizao da ferramenta Code First Migrations.
O primeiro passo para utilizar Code First Migrations habilit-lo e adicion-lo ao projeto atravs
do Package Manager Console.
O comando Enable-Migrations adiciona uma pasta chamada Migrations no projeto. Esta pasta
contm dois arquivos.
A classe parcial InitialCreate define a primeira verso das tabelas do banco de dados.
www.facebook.com/k19treinamentos 65
C ODE F IRST M IGRATIONS 66
Add-Migration que gera o cdigo necessrio para atualizar o banco de dados de acordo com
as alteraes nas classes de modelo.
Aps adicionarmos a propriedade Telefone classe Editora, devemos adicionar uma Migration
ao projeto para atualizar o banco de dados e adicionar uma nova coluna tabela Editoras. Para
adicionar uma Migration, devemos utilizar o comando Add-Migration. Para atualizar o banco de
dados com as alteraes definidas na Migration, devemos utilizar o comando Update-Database.
Para utilizar o comando Add-Migration necessrio definir o nome da Migration a ser adicio-
nada.
66 www.k19.com.br
67 C ODE F IRST M IGRATIONS
Para atualizar o banco de dados com as alteraes definidas na Migration, devemos executar o
comando Update-Database.
Exerccios de Fixao
www.facebook.com/k19treinamentos 67
C ODE F IRST M IGRATIONS 68
4 Crie uma classe K19Context e adicione a propriedade DbSet para mapear a entidade Editora.
1 using System ;
2 using System . Collections . Generic ;
3 using System . Linq ;
4 using System . Text ;
5 using System . Threading . Tasks ;
6
7 namespace CodeFirstMigrations
8 {
9 class Program
10 {
11 static void Main ( string [] args )
12 {
13 using ( var context = new K19Context () )
14 {
15 Console . WriteLine ( " Digite o nome da Editora : " ) ;
16 string nome = Console . ReadLine () ;
17 Console . WriteLine ( " Digite o email da Editora : " ) ;
18 string email = Console . ReadLine () ;
19 Editora e = new Editora { Nome = nome , Email = email };
20 context . Editoras . Add ( e ) ;
21 context . SaveChanges () ;
22 }
23
24 }
25 }
26 }
68 www.k19.com.br
69 C ODE F IRST M IGRATIONS
8 Para corrigir o problema visto no exerccio anterior, devemos habilitar o Code First Migrations.
Para isso, execute o seguinte comando atravs do Package Manager Console.
Enable-Migrations.
www.facebook.com/k19treinamentos 69
C ODE F IRST M IGRATIONS 70
Verifique que uma pasta chamada Migrations com dois arquivos: <DATA>_InitialCreate.cs e Con-
figuration.cs foi gerada no projeto CodeFirstMigrations.
70 www.k19.com.br
71 C ODE F IRST M IGRATIONS
7 {
8 public override void Up ()
9 {
10 AddColumn ( " dbo . Editoras " , " Telefone " , c = > c . String () ) ;
11 }
12
13 public override void Down ()
14 {
15 DropColumn ( " dbo . Editoras " , " Telefone " ) ;
16 }
17 }
18 }
10 Para atualizar a tabela Editoras no banco de dados, utilize o comando Update-Database que
executado atravs do Package Manager Console.
1 namespace EFMigrations
2 {
3 public class Livro
4 {
5 public int Id { get ; set ; }
6 public string Titulo { get ; set ; }
7 public decimal Preco { get ; set ; }
8 public int EditoraId { get ; set ; }
9 public Editora Editora { get ; set ; }
10 }
11 }
Para estabelecer o relacionamento entre as entidades Editora e Livro, a classe Editora dever
ser alterada.
1 namespace EFMigrations
2 {
www.facebook.com/k19treinamentos 71
C ODE F IRST M IGRATIONS 72
1 namespace EFMigrations
2 {
3 public class K19Context : DbContext
4 {
5 public DbSet < Editora > Editoras { get ; set ; }
6 public DbSet < Livro > Livros { get ; set ; }
7 }
8 }
Aps a criao da classe que define a entidade Livro e a alterao das classes Editora e K19Context,
devemos criar uma Migration que atualizar o banco de dados criando uma nova tabela para o qual
a classe Livro ser mapeada.
Add-Migration CreateLivro
Para atualizar o banco de dados e criar a nova tabela, devemos utilizar o comando Update-Database.
72 www.k19.com.br
73 C ODE F IRST M IGRATIONS
Aps executar o comando Update-Database, verifique que a tabela para o qual a classe Livro foi
mapeada foi criada no banco de dados.
Exerccios de Fixao
1 namespace CodeFirstMigrations
2 {
3 class Livro
4 {
5 public int Id { get ; set ; }
6 public string Titulo { get ; set ; }
7 public decimal Preco { get ; set ; }
8 public int EditoraId { get ; set ; }
9 public Editora Editora { get ; set ; }
10 }
11 }
12 Altere a classe K19Context para mapear a classe Livro para uma tabela no banco de dados.
www.facebook.com/k19treinamentos 73
C ODE F IRST M IGRATIONS 74
6 {
7 public DbSet < Editora > Editoras { get ; set ; }
8 public DbSet < Livro > Livros { get ; set ; }
9 }
10 }
13 Para gerar a tabela Livros no banco de dados, devemos criar uma migrao. Crie uma migrao
chamada CreateLivro atravs do comando Add-Migration.
14 Execute o comando Update-Database atravs do Package Manager Console para gerar a tabela
Verifique que a tabela referente a classe Livro foi gerada no banco de dados.
O Code First Migrations cria automaticamente as Migrations de acordo com as alteraes rea-
lizadas nas classes que representam as entidades. Porm, as Migrations podem ser alteradas para
realizar outras operaes, como executar scripts SQL ou adicionar um indce, por exemplo. Segue
abaixo uma relao das operaes que podem ser executadas durante uma Migration:
74 www.k19.com.br
75 C ODE F IRST M IGRATIONS
Operaes Descrio
AddColumn Adiciona uma coluna a uma tabela existente
AddForeignKey Cria uma chave estrangeira
AddPrimaryKey Cria uma chave primria
AlterColumn Altera a definio de uma coluna existente
CreateIndex Cria um ndice para uma coluna existente
CreateTable Cria uma nova tabela no banco de dados
DropColumn Remove uma coluna existente
DropForeignKey Remove uma chave estrangeira existente
DropIndex Remove um ndice existente
DropPrimaryKey Remove uma chave primria existente
DropTable Remove uma tabela existente
MoveTable Move a tabela para um novo schema de banco de dados
RenameColumn Renomeia uma coluna existente
RenameTable Renomeia uma tabela existente
Sql Executa um comando SQL
Exerccios de Fixao
1 namespace CustomizandoCodeFirstMigrations
2 {
3 public class Pessoa
4 {
5 public int Id { get ; set ; }
6 public string Nome { get ; set ; }
7 public string Email { get ; set ; }
8 public string TelefoneFixo { get ; set ; }
9 public string Celular { get ; set ; }
10 }
11 }
18 Crie uma classe K19Context para mapear a entidade Pessoa para o banco de dados.
1 namespace CustomizandoCodeFirstMigrations
2 {
3 public class K19Context : DbContext
4 {
5 public DbSet < Pessoa > Pessoas { get ; set ; }
6 }
7 }
www.facebook.com/k19treinamentos 75
C ODE F IRST M IGRATIONS 76
19 Crie uma classe de teste que persiste um objeto da classe Pessoa no banco de dados.
1 namespace CustomizandoCodeFirstMigrations
2 {
3 class Program
4 {
5 static void Main ( string [] args )
6 {
7 using ( var db = new K19Context () )
8 {
9 Pessoa p = new Pessoa { Nome = " K19 " , Email = " contato@k19 . com . br " ,
10 Celular = " (11) 2387 -3791 " , TelefoneFixo = " (11) 2387 -3792 " };
11 db . Pessoas . Add ( p ) ;
12 db . SaveChanges () ;
13 }
14 }
15 }
16 }
20 Altere a classe Pessoa para tornar obrigatrio a propriedade TelefoneFixo. Renomeie tambm a
propriedade Celular para TelefoneCelular.
1 namespace CustomizandoCodeFirstMigrations
2 {
3 public class Pessoa
4 {
5 public int Id { get ; set ; }
6 public string Nome { get ; set ; }
7 public string Email { get ; set ; }
8 [ Required ]
9 public string TelefoneFixo { get ; set ; }
10 public string TelefoneCelular { get ; set ; }
11 }
12 }
21 Para que as alteraes sejam refletidas no banco de dados, necessrio habilitar o Code First Mi-
grations no projeto. Execute o comando Enable-Migrations atravs do Package Manager Console.
22 Aps habilitar o Code First Migrations no projeto, crie uma Migration que efetuar as operaes
de alterao no banco de dados. Execute o comando Add-Migration AlteraTelefoneFixoERenomei-
aCelularDePessoa
76 www.k19.com.br
77 C ODE F IRST M IGRATIONS
2 {
3 using System ;
4 using System . Data . Entity . Migrations ;
5
6 public partial class AlteraTelefoneFixoERenomeiaCelularDePessoa : DbMigration
7 {
8 public override void Up ()
9 {
10 AddColumn ( " dbo . Pessoas " , " TelefoneCelular " , c = > c . String () ) ;
11 AlterColumn ( " dbo . Pessoas " , " TelefoneFixo " , c = > c . String ( nullable : false ) ) ;
12 DropColumn ( " dbo . Pessoas " , " Celular " ) ;
13 }
14
15 public override void Down ()
16 {
17 AddColumn ( " dbo . Pessoas " , " Celular " , c = > c . String () ) ;
18 AlterColumn ( " dbo . Pessoas " , " TelefoneFixo " , c = > c . String () ) ;
19 DropColumn ( " dbo . Pessoas " , " TelefoneCelular " ) ;
20 }
21 }
22 }
O Code First Migrations permite ao desenvolvedor fazer a migrao para uma verso espe-
cfica. possvel, por exemplo, desfazer as alteraes e voltar para uma verso anterior atravs do
comando Update-Database. Basta definir o nome da verso atravs do parmetro -TargetMigration:
Update-Database -TargetMigration:{NomeDaMigrationAnterior}
www.facebook.com/k19treinamentos 77
C ODE F IRST M IGRATIONS 78
possvel tambm voltar para o estado inicial do banco de dados, executando o comando Update-
Database -TargetMigration:$InitialDatabase.
Atravs do comando Update-Database possvel definir o estado inicial e a verso final para que
o script SQL contenha todas as alteraes necessrias para atualizar o banco de dados.
78 www.k19.com.br
CAPTULO
V ISO G ERAL DO ASP.NET MVC
5
Necessidades de uma aplicao web
HTTP
Os usurios de uma aplicao web utilizam navegadores (browsers) para interagir com essa apli-
cao. A comunicao entre navegadores e uma aplicao web realizada atravs de requisies e
respostas definidas pelo protocolo HTTP. Dessa forma, os desenvolvedores de aplicaes web devem
estar preparados para trabalhar com o protocolo HTTP.
Acesso simultneo
Alm disso, na grande maioria dos casos, as aplicaes web devem ser acessadas por diversos
usurios ao mesmo tempo. Consequentemente, os desenvolvedores web devem criar ou utilizar
algum mecanismo eficiente que permita esse tipo de acesso.
Contedo dinmico
As pginas de uma aplicao web devem ser geradas dinamicamente. Por exemplo, quando um
usurio de uma aplicao de email acessa a sua caixa de entrada, ele deseja ver todos os emails
enviados at aquele momento. A pgina contendo a lista de emails deve ser gerada novamente toda
vez que essa pgina for requisitada. Consequentemente, os desenvolvedores web devem criar ou
utilizar algum mecanismo eficiente que permita que o contedo das pginas das aplicaes web seja
gerado dinamicamente.
www.facebook.com/k19treinamentos 79
V ISO G ERAL DO ASP.NET MVC 80
Aplicao
Web
TP
Re
HT
sp
Requisio HTTP
Resposta HTTP
o
o
st
isi
HT
qu
TP
Re
TP
Re
HT
sp
o
o
st
aH
isi
qu
TT
Re
P
www.k19.com.br www.k19.com.br www.k19.com.br
Soluo
Resolver os trs problemas apresentados tomaria boa parte do tempo de desenvolvimento, alm
de exigir conhecimentos tcnicos extremamente especficos por parte dos desenvolvedores. Para
facilitar o desenvolvimento de aplicaes web, a plataforma .NET soluciona esses problemas funda-
mentais.
Acesso simultneo das aplicaes por vrios usurios de uma maneira eficiente.
ASP.NET MVC
O MVC (model-view-controller) um padro de arquitetura que tem por objetivo isolar a lgica
de negcio da lgica de apresentao de uma aplicao.
Esse padro (ou alguma variao) amplamente adotado nas principais plataformas de desen-
volvimento atuais. Em particular, ele bastante utilizado no desenvolvimento de aplicaes web.
80 www.k19.com.br
81 V ISO G ERAL DO ASP.NET MVC
O padro MVC divide uma aplicao em trs tipos de componentes: modelo, viso e controlador.
Para mais detalhes sobre o padro MVC, uma boa referncia o livro Pattern-Oriented Software
Architecture Volume 1: A System of Patterns (editora Wiley, 1996) dos autores Frank Buschmann, Re-
gine Meunier, Hans Rohnert, Peter Sommerlad, Michael Stal e Michael Stal.
No padro Front Controller, todas as requisies do usurio so recebidas pelo mesmo compo-
nente. Dessa forma, tarefas que devem ser realizadas em todas as requisies podem ser implemen-
tadas por esse componente. Isso evita a repetio de cdigo e facilita a manuteno do sistema.
Para mais informaes sobre esse padro, consulte, por exemplo, o livro Professional ASP.NET
Design Patterns (editora Wrox, 720) de Scott Millett.
Visual Studio
O primeiro passo para construir uma aplicao web utilizando o framework ASP.NET MVC 4
criar um projeto no Visual Studio a partir do modelo adequado. No nosso caso, o modelo de projeto
que deve ser utilizado o ASP.NET MVC 4 Web Application.
www.facebook.com/k19treinamentos 81
V ISO G ERAL DO ASP.NET MVC 82
O projeto criado j vem com diversas pastas e arquivos. Ao longo dos prximos captulos, a fun-
o de cada pasta e de cada arquivo ser discutida.
Testando a aplicao
Para verificar o funcionamento do projeto, basta execut-lo atravs do menu: Debug -> Start
Debugging. Um servidor ser inicializado na mquina e a aplicao implantada nesse servidor.
Alm disso, uma janela do navegador padro do sistema aberta na url principal da aplicao.
Veremos a seguir um exemplo de uma simples aplicao web em ASP.NET MVC 4. Essa aplicao
possuir uma pgina principal que dever exibir o seu nmero de visualizao.
82 www.k19.com.br
83 V ISO G ERAL DO ASP.NET MVC
dos controladores devem terminar com a palavra Controller. Alm disso, eles devem ser definidos
na pasta Controllers da aplicao. Considere a classe K19Controller definida abaixo.
Cada vez que o mtodo Index() chamado, o valor da propriedade NumeroDeAcessos incre-
mentado. Alm disso, o valor atualizado dessa propriedade colocado na ViewBag para que possa
ser acessado na camada de apresentao.
Para indicar que o fluxo de execuo deve seguir para a camada de apresentao, o mtodo
Index() invoca o mtodo View() e devolve a resposta obtida. Por padro, o fluxo ser direcionado
para um arquivo chamado Index.cshtml que deve estar localizado na pasta Views\K19\.
Na camada de apresentao, vamos adicionar a pgina associada ao mtodo Index(). Para isso,
criaremos um arquivo chamado Index.cshtml na pasta Views\K19\ da aplicao com o contedo
abaixo.
1 @{
2 ViewBag . Title = " Index " ;
3 }
4 < h2 > Acessos : @ViewBag . Acessos </ h2 >
Exerccios de Fixao
1 Crie um projeto do tipo ASP.NET MVC 4 Web Application chamado K19 no Visual Studio 2012
Express for Web. Utilize o template Basic Project.
www.facebook.com/k19treinamentos 83
V ISO G ERAL DO ASP.NET MVC 84
84 www.k19.com.br
85 V ISO G ERAL DO ASP.NET MVC
2 Crie um controlador chamado K19 no projeto K19. Siga os passos apresentados nas imagens
abaixo.
1 using System ;
2 using System . Web . Mvc ;
3
4 namespace K19 . Controllers
5 {
6 public class K19Controller : Controller
7 {
8 public ActionResult Index ()
9 {
www.facebook.com/k19treinamentos 85
V ISO G ERAL DO ASP.NET MVC 86
4 Crie uma pgina na aplicao, adicionando um arquivo chamado Index.cshtml dentro da pasta
Views\K19\.
86 www.k19.com.br
87 V ISO G ERAL DO ASP.NET MVC
www.facebook.com/k19treinamentos 87
V ISO G ERAL DO ASP.NET MVC 88
1 @{
2 ViewBag . Title = " Index " ;
3 }
4 < h2 > Ol ! O seu nmero da sorte @ViewBag . NumeroDaSorte </ h2 >
5 Para visualizar a pgina, basta executar o projeto no Visual Studio e acessar o endereo
http://localhost:<PORTA_APP>/K19/Index
As configuraes padres do Entity Framework podem ser alteradas atravs do arquivo Web.config.
Scaffold
O Visual Studio 2012 capaz de gerar telas e controladores para as operaes de insero, leitura,
alterao e remoo (CRUD) a partir de uma entidade de um projeto ASP.NET MVC 4. Os controla-
dores gerados podem utilizar as funcionalidades do Entity Framework para interagir com o banco de
dados.
88 www.k19.com.br
89 V ISO G ERAL DO ASP.NET MVC
Exerccios de Fixao
6 Vamos gerar o nosso primeiro scaffold. Para isto, defina as classes Editora e K19Context na
pasta Models do projeto K19.
8 Aps o build do projeto, podemos gerar o scaffold. Para isso, crie um controlador chamado
Editora seguindo os passos apresentados nas imagens a seguir.
www.facebook.com/k19treinamentos 89
V ISO G ERAL DO ASP.NET MVC 90
90 www.k19.com.br
91 V ISO G ERAL DO ASP.NET MVC
www.facebook.com/k19treinamentos 91
V ISO G ERAL DO ASP.NET MVC 92
12 Faa novamente o build do projeto. Depois, gere o scaffold da entidade Livro. Crie um contro-
lador chamado Livro seguindo os passos apresentados nas imagens a seguir.
92 www.k19.com.br
CAPTULO
C AMADA DE A PRESENTAO
6
A camada de apresentao responsvel por gerar as pginas de uma aplicao web. Os dados
apresentados em uma pgina web so definidos na camada de modelo. A camada de controle re-
cupera os dados da camada de modelo e os envia para a camada de apresentao. Basicamente, a
camada de apresentao definir como esses dados sero apresentados para os usurios da aplica-
o.
O fluxo inverso tambm ocorre. Ou seja, a camada de apresentao obtm dados inseridos pelos
usurios e os envia para a camada de controle que, por sua vez, usa esses dados para alterar a camada
de modelo.
Neste captulo, mostraremos como a camada de apresentao de uma aplicao web cons-
truda com a utilizao de recursos do ASP.NET MVC como Inline Code, HTML Helper, Layout e Par-
tial Views.
Razor e ASPX
At a segunda verso do ASP.NET MVC, as telas (ou pginas) de uma aplicao web eram de-
senvolvidas em ASPX. A partir da terceira verso desse framework, podemos usar a linguagem Razor
para construir essas telas. A principal caracterstica da Razor ser concisa e simples, diminuindo o
nmero de caracteres e as tradicionais tags de scripts do ASP.NET MVC (<% %>).
Criando Variveis
Toda expresso em Razor comea com o caractere @. Para criarmos variveis, precisamos declar-
las dentro de um bloco Razor:
1 @{
2 string nome = " K19 " ;
3 string telefoneDaK19 = " 2387 -3791 " ;
4 string enderecoDaK19 = " Av . Brigadeiro Faria Lima " ;
5 int numeroDaK19 = 1571;
6 }
1 <%
2 string nome = " K19 " ;
3 string telefoneDaK19 = " 2387 -3791 " ;
4 string enderecoDaK19 = " Av . Brigadeiro Faria Lima " ;
5 int numeroDaK19 = 1571;
6 %>
www.facebook.com/k19treinamentos 93
C AMADA DE A PRESENTAO 94
Acessando variveis
As variveis podem ser facilmente acessadas.
1 <%
2 if ( numero == numeroDaK19 )
3 {
4 %>
5 <p > Chegou na K19 ! </ p >
6 <%
7 }
8 else
9 {
10 %>
11 <p > Continue andando . </ p >
12 <%
13 }
14 %>
Laos
Podemos criar laos utilizando o comando for.
94 www.k19.com.br
95 C AMADA DE A PRESENTAO
1 <%
2 for ( int i = 0; i < 5; i ++)
3 {
4 %>
5 <p >i = < %= i % > </ p >
6 <%
7 }
8 %>
Texto e cdigo
1 @if ( x == " nome " )
2 {
3 @ : O nome da editora @editora . Nome
4 }
1 <%
2 if ( x == " nome " )
3 {
4 %>
5 O nome da editora < %= editora . Nome % >
6 <%
7 }
8 %>
Comentrios
Podemos adicionar comentrios nas pginas.
1 @ * Comentrio * @
Exerccios de Fixao
www.facebook.com/k19treinamentos 95
C AMADA DE A PRESENTAO 96
1 @{
2 ViewBag . Title = " Index " ;
3 }
4
5 @for ( int i = 0; i < 10; i ++)
6 {
7 < h2 > Ol ! O seu nmero da sorte @ViewBag . NumeroDaSorte </ h2 >
8 }
4 Altere o arquivo Index.cshtml do exerccio anterior para imprimir uma mensagem a partir de
uma varivel.
1 @{
2 ViewBag . Title = " Index " ;
3 string mensagem = " Ol ! O seu nmero da sorte " + @ViewBag . NumeroDaSorte ;
4 }
5
6 @for ( int i = 0; i < 10; i ++)
7 {
8 < h2 > @mensagem </ h2 >
9 }
Exerccios Complementares
96 www.k19.com.br
97 C AMADA DE A PRESENTAO
A ViewBag utilizada para transmitir dados da camada de controle para a camada de apresenta-
o. Para adicionar um item propriedade ViewBag, devemos definir uma chave para esse item. Veja
o cdigo abaixo.
No cdigo acima, criamos uma chave chamada HoraDoServidor e atribumos um valor a essa
chave.
A ViewBag oferece uma forma simples de transmitir dados da camada de controle para a camada
de apresentao, mas apresenta algumas desvantagens. Por exemplo, como as chaves so adicio-
nadas dinamicamente, no possvel garantir a existncia dessas chaves em tempo de compilao.
Considere o cdigo abaixo.
www.facebook.com/k19treinamentos 97
C AMADA DE A PRESENTAO 98
No cdigo acima, o tipo do objeto associado chave X depende do valor da varivel numero,
que gerado aleatoriamente. Quando o valor gerado for menor do que 0.5, o tipo desse objeto ser
string. Caso contrrio, o tipo desse objeto ser int. Suponha que a chave X seja utilizada na camada
de apresentao.
O cdigo acima no produz erros de compilao. Contudo, na execuo, um erro poder ocorrer.
O problema que esse cdigo supe que o objeto associado chave X possui o mtodo Lower(). No
entanto, se a ao for acionada um nmero suficiente de vezes, em algum momento isso no ser
verdade, e um erro de execuo ocorrer.
Alm disso, recursos do Visual Studio como IntelliSense (recurso para completar cdigo) ou refa-
torao no podem ser aplicados com o uso da ViewBag.
Uma alternativa utilizao da ViewBag o recurso strongly typed views. Com esse recurso
podemos fixar, em tempo de compilao, o tipo do objeto que ser transferido da camada de controle
para a camada de apresentao. Uma vez que o tipo desse objeto foi fixado, o compilador capaz
de verificar a validade do cdigo, evitando eventuais erros de execuo. Alm disso, o Visual Studio
pode auxiliar o desenvolvimento da aplicao com os recursos de IntelliSense e de refatorao.
Para utilizar strongly type views, o primeiro passo , na camada de controle, passar como par-
metro para o mtodo View() um objeto do tipo esperado pela camada de apresentao.
Para definir o tipo do objeto esperado na camada de apresentao, podemos utilizar a sintaxe da
Razor. Veja o cdigo abaixo.
Podemos tambm utilizar o comando using para evitar a escrita dos nomes completos das clas-
ses.
98 www.k19.com.br
99 C AMADA DE A PRESENTAO
Para acessar o objeto transmitido da camada de controle para a camada de apresentao, deve-
mos utilizar a propriedade Model. Observe o cdigo a seguir.
Observe que apenas um objeto pode ser transmitido da camada de controle para a camada de
apresentao atravs do recurso strongly type views. J com a utilizao de ViewBag, diversos objetos
podem ser transmitidos. Note tambm que os dois recursos podem ser utilizados ao mesmo tempo.
Exerccios de Fixao
www.facebook.com/k19treinamentos 99
C AMADA DE A PRESENTAO 100
1 @{
2 ViewBag . Title = " Agora " ;
3 }
4
5 < h2 > Agora : @ViewBag . Agora </ h2 >
8 Adicione um controlador chamado Aluno utilizando o template Empty MVC Controller. Nesse
controlador, defina uma ao para transmitir para camada de apresentao um objeto da entidade
Aluno. Utilize strongly type views.
9 Adicione uma tela associada ao Detalhes do controlador Aluno com o seguinte contedo.
100 www.k19.com.br
101 C AMADA DE A PRESENTAO
2
3 @{
4 ViewBag . Title = " Detalhes " ;
5 }
6
7 < h2 > Detalhes </ h2 >
8
9 <p >
10 AlunoID : @Model . AlunoID
11 </ p >
12
13 <p >
14 Nome : @Model . Nome
15 </ p >
16
17 <p >
18 Email : @Model . Email
19 </ p >
1 ...
2 public ActionResult Lista ()
3 {
4 ICollection < Aluno > lista = new List < Aluno >() ;
5
6 for ( int i = 0; i < 5; i ++)
7 {
8 Aluno a = new Aluno {
9 AlunoID = i ,
10 Nome = " Aluno " + i ,
11 Email = " Email " + i
12 };
13 lista . Add ( a ) ;
14 }
15
16 return View ( lista ) ;
17 }
18 ...
11 Adicione uma tela associada ao Lista do controlador Aluno com o seguinte contedo.
www.facebook.com/k19treinamentos 101
C AMADA DE A PRESENTAO 102
17 {
18 < tr >
19 < td > @a . AlunoID </ td >
20 < td > @a . Nome </ td >
21 < td > @a . Email </ td >
22 </ tr >
23 }
24 </ table >
HTML Helpers
A funo das pginas CSHTML gerar hipertexto XHTML para enviar aos navegadores dos usu-
rios. Os arquivos .cshtml misturam tags XHTML com scripts de servidor escritos em C# (ou outra
linguagem de programao suportada pelo .NET). Essa mistura pode prejudicar a legibilidade do
cdigo em alguns casos. Alm disso, a manuteno da aplicao pode se tornar mais complexa.
1 <a href = " / Editora / Index / " > Lista de editoras </ a >
Se o formato da url para acessar a ao Index do controlador Editora for alterado, o cdigo acima
dever ser modificado. Veremos como o formato das urls pode ser configurado no Captulo ??.
Para facilitar a manuteno do cdigo das pginas CSHTML, o ASP.NET MVC oferece os chama-
dos HTML Helpers. A funo de um HTML Helper encapsular um cdigo XHTML. Por exemplo,
para adicionar um link, podemos usar o mtodo ActionLink do objeto Html, ao invs de usar a tag
<a> do HTML diretamente. No cdigo abaixo, criamos um link para a ao responsvel por listar as
editoras.
1 @Html . ActionLink ( " Lista de editoras " , " Index " , " Editora " )
Agora, se o formato da url para acessar a ao Index do controlador Editora for alterado, o c-
digo acima no precisa ser alterado.
ActionLink Helper
O helper ActionLink utilizado para gerar os links das pginas de uma aplicao web. Esse
helper pode ser utilizado de diversas maneiras. A forma mais simples de utiliz-lo passar a ele
dois parmetros: o texto e a ao associados ao link desejado. Nesse caso, o link gerado pelo helper
ActionLink estar associado ao controlador correspondente a pgina na qual o link foi inserido.
1 @Html . ActionLink ( " TEXTO PARA O USURIO " , " ACTION " )
102 www.k19.com.br
103 C AMADA DE A PRESENTAO
Podemos definir o controlador desejado explicitamente. Para isso, necessrio passar um ter-
ceiro parmetro para o mtodo ActionLink.
1 @Html . ActionLink ( " TEXTO PARA O USURIO " , " ACTION " , " CONTROLADOR " )
O helper ActionLink permite que parmetros sejam adicionados nos links gerados. Para isso,
necessrio passar um array como parmetro.
1 @Html . ActionLink ( " TEXTO PARA O USURIO " , " ACTION " , new { Inicio = 0 , Final = 10 })
Para criar um formulrio, utilizamos o helper BeginForm. Para terminar um formulrio, utiliza-
mos o helper EndForm. Veja o exemplo a seguir.
1 @ { Html . BeginForm () ;}
2
3 <! -- elementos do formulrio -- >
4
5 @ { Html . EndForm () ;}
Tambm podemos utilizar o comando using para garantir que os formulrios sejam fechados.
Nesse caso, no necessrio adicionar o helper EndForm. Observe o formulrio abaixo.
Por padro, um formulrio criado com o helper BeginForm enviar requisies ao associada
url atual. Contudo, podemos definir explicitamente uma outra ao para receber essas requisies.
Veja um exemplo no cdigo abaixo.
Por padro, os formulrios gerados pelo helper BeginForm fazem requisies do tipo POST. Nesse
caso, as aes associadas a esses formulrios devem ser anotadas com HttpPost para indicar o tipo
de requisio HTTP esperado.
www.facebook.com/k19treinamentos 103
C AMADA DE A PRESENTAO 104
CheckBox
Podemos adicionar um checkbox em um formulrio atravs do helper CheckBox.
1 < input id = " Aceito " name = " Aceito " type = " checkbox " value = " true " / >
2 < input name = " Aceito " type = " hidden " value = " false " / >
Cdigo C# 6.10: Ao
104 www.k19.com.br
105 C AMADA DE A PRESENTAO
TextBox
Uma caixa de texto pode ser adicionada atravs do helper TextBox.
1 @Html . TextBox ( " Nome " , " Digite o seu nome " )
1 < input id = " Nome " name = " Nome " type = " text " value = " Digite o seu nome " / >
TextArea
Uma caixa para textos maiores pode ser adicionada atravs do helper TextArea.
1 @Html . TextArea ( " Mensagem " , " Digite uma mensagem " )
1 < textarea cols = " 20 " id = " Mensagem " name = " Mensagem " rows = " 2 " > Digite uma mensagem </ -
textarea >
RadioButton
Um boto do tipo radio pode ser adicionado atravs do helper RadioButton.
1 < input checked = " checked " id = " CidadeNatal " name = " CidadeNatal " type = " radio " value = " So -
Paulo " / >
2 < input id = " CidadeNatal " name = " CidadeNatal " type = " radio " value = " Natal " / >
3 < input id = " CidadeNatal " name = " CidadeNatal " type = " radio " value = " Piracicaba " / >
www.facebook.com/k19treinamentos 105
C AMADA DE A PRESENTAO 106
Hidden
Um campo escondido pode ser adicionado atravs do helper Hidden.
1 < input id = " Id " name = " Id " type = " hidden " value = " 1 " / >
Password
Uma caixa para senha pode ser adicionada atravs do helper Password.
1 < input id = " Password " name = " Password " type = " password " value = " senha " / >
Mais Sobre
Os dados preenchidos nos elementos de um formulrio so recuperados da ViewBag.
Considere o cdigo abaixo:
Caso exista uma chave chamada Nome na ViewBag, ento o valor associado a essa chave ser
o valor inicial da caixa de texto. Podemos alterar esse comportamento, passando um segundo
parmetro para o helper TextBox, que ser o valor inicial da caixa de texto. Observe o cdigo a
seguir.
106 www.k19.com.br
107 C AMADA DE A PRESENTAO
O cdigo anterior supe que o objeto recebido como parmetro pela ao associada ao formul-
rio onde o checkbox foi inserido possua uma propriedade chamada Aceito. Essa propriedade pode
no existir. Contudo, nenhum erro de compilao seria gerado nesse caso.
Para evitar esse tipo de problema, podemos utilizar a seguinte sintaxe em telas fortemente tipa-
das:
Com essa sintaxe, o compilador tem condies de verificar a existncia das propriedades. Sendo
assim, ele produzir um erro de compilao se uma propriedade inexistente for utilizada.
TextBoxFor
1 @model K19 . Models . Empresa
2 ...
3 @Html . TextBoxFor ( x = > x . Nome )
4 ...
1 < input id = " Nome " name = " Nome " type = " text " value = " K19 Treinamentos " / >
TextAreaFor
1 @model K19 . Models . Empresa
2 ...
3 @Html . TextAreaFor ( x = > x . Descricao )
4 ...
1 < textarea cols = " 20 " id = " Descricao " name = " Descricao " rows = " 2 " >
2 K19 Treinamentos em Java e . NET
3 </ textarea >
RadioButtonFor
www.facebook.com/k19treinamentos 107
C AMADA DE A PRESENTAO 108
1 < input checked = " checked " id = " CidadeNatal " name = " CidadeNatal " type = " radio " value = " So -
Paulo " / >
2 < input id = " CidadeNatal " name = " CidadeNatal " type = " radio " value = " Natal " / >
3 < input id = " CidadeNatal " name = " CidadeNatal " type = " radio " value = " Piracicaba " / >
HiddenFor
1 @model K19 . Models . Empresa
2 ...
3 @Html . HiddenFor ( e = > e . Id )
4 ...
1 < input id = " Id " name = " Id " type = " hidden " value = " 1 " / >
PasswordFor
1 @model K19 . Models . Usuario
2 ...
3 @Html . PasswordFor ( x = > x . Senha )
4 ...
1 < input id = " Senha " name = " Senha " type = " password " / >
Mais Sobre
Os dados preenchidos nos elementos de um formulrio de uma tela fortemente tipada
so recuperados da propriedade Model. Considere o cdigo abaixo:
108 www.k19.com.br
109 C AMADA DE A PRESENTAO
Caso exista a propriedade Model.Nome, o valor inicial dessa caixa de texto ser o valor dessa
propriedade.
DropDownList Helper
Considere uma aplicao para cadastrar livros de uma biblioteca. Quando um livro cadastro,
o usurio podem escolher a editora desse livro. A editora pode ser selecionada atravs de um drop
down list. Para criar um drop down list, podemos utilizar o HTML Helper DropDownList.cshtml
O primeiro passo para utilizar o helper DropDownList criar uma SelectList na camada de
controle com as opes que o usurio poder selecionar.
EditorFor
Considere a seguinte entidade.
Para editar os dados de uma editora, temos uma pgina conforme o exemplo abaixo:
www.facebook.com/k19treinamentos 109
C AMADA DE A PRESENTAO 110
Para cada propriedade da entidade Editora, utilizamos um helper para gerar o cdigo HTML
necessrio para a entrada de dados. Por exemplo, no caso das propriedades Nome e Email, utilizamos
o Helper TextBox. Para a propriedade booleana IsAtivo, utilizamos o helper CheckBox.
Observe que a escolha do helper depende basicamente do tipo da propriedade associada a ele.
Podemos deixar essa escolha a cargo do helper EditorFor. Para propriedades de tipo booleano,
esse helper utilizar o CheckBox. Para propriedades do tipo string, esse helper utilizar o TextBox.
Observe a utilizao do helper EditorFor no cdigo abaixo.
110 www.k19.com.br
111 C AMADA DE A PRESENTAO
30 < input type = " submit " value = " Salvar " / >
31 }
EditorForModel
Tambm temos o helper EditorForModel para construir um formulrio completo com base nas
propriedades de uma entidade. Esse helper seguir a mesma abordagem do EditorFor. Ou seja,
para cada propriedade do Model, ele utilizar o helper apropriado.
Exerccios de Fixao
www.facebook.com/k19treinamentos 111
C AMADA DE A PRESENTAO 112
1 ...
2 public ActionResult Editar ()
3 {
4 Aluno aluno = new Aluno
5 {
6 AlunoID = 1 ,
7 Nome = " Jonas Hirata " ,
8 Email = " jonas@k19 . com . br "
9 };
10 return View ( aluno ) ;
11 }
12 ...
112 www.k19.com.br
113 C AMADA DE A PRESENTAO
17 Altere a entidade Aluno para indicar que a propriedade AlunoID no deve ser exibida nos for-
mulrios que utilizarem o HTML Helper EditorFor e EditorForModel.
www.facebook.com/k19treinamentos 113
C AMADA DE A PRESENTAO 114
19 Adicione uma nova entidade chamada Usuario na pasta Models do projeto CamadaDeApresen-
tacao.
114 www.k19.com.br
115 C AMADA DE A PRESENTAO
Layouts
comum que as pginas de uma aplicao web possuam contedo em comum (por exemplo, um
cabealho ou um rodap). O contedo em comum pode ser replicado em todas as pginas atravs
do CTRL+C e CTRL+V. Porm, essa no uma boa abordagem, pois quando alguma alterao precisa
ser realizada, todos os arquivos devem ser modificados. Tambm comum que as pginas de uma
aplicao web possuam um certo padro visual. Da surge o conceito de Layouts.
Contedo comum
Tudo que comum a todas as pginas de um determinado grupo pode ser definido em um
Layout. Dessa forma, qualquer alterao facilmente realizada modificando-se apenas um arquivo.
Por exemplo, suponha que toda pgina de uma aplicao web deva ter o mesmo ttulo e a mesma
formatao. Podemos criar um Layout com o ttulo desejado e com a referncia ao arquivo CSS que
define a formatao padro.
www.facebook.com/k19treinamentos 115
C AMADA DE A PRESENTAO 116
No layout definido no cdigo acima, utilizamos o mtodo Render() das propriedades Styles e
Scripts para adicionar contedo CSS e JavaScript. Na tag <title>, acrescentamos @ViewBag.Title,
para que cada pgina possa definir o seu prprio ttulo. Por fim, o mtodo RenderBody() indica onde
o contedo definido em cada pgina ser adicionado.
recomendado que os arquivos que definam layouts sejam colocados na pasta Views\Share.
Mais Sobre
Suponha que devemos adicionar diversos arquivos CSS uma pgina de uma aplicao
ASP.NET MVC. Se esses arquivos forem adicionados um a um da maneira tradicional
(com a tag <link>), o nmero de requisies que os navegadores tero de realizar para carre-
gar essa pgina ser alto, afetando o desempenho. Para contornar esse problema, poderamos
agrupar o cdigo CSS de todos os arquivos em apenas um. Contudo, essa abordagem dificultaria
a manuteno do cdigo CSS. Dessa forma, o ASP.NET MVC 4 possui um mecanismo capaz de
agrupar o contedo CSS de diversos arquivos dinamicamente. Para usar esse mecanismo, basta
invocar o mtodo Render() da propriedade Styles.
1 @Styles . Render ( " ~/ Content / Arquivo1 . css " , " ~/ Content / Arquivo2 . css " , " ~/ Content / -
Arquivo3 . css " )
Cdigo CSHTML 6.51: Utilizando o mtodo Render para adicionar contedo CSS
Analogamente, a propriedade Scripts possui o mtodo Render(), que tambm tem por obje-
tivo agrupar o cdigo JavaScript de diversos arquivos.
Com o layout definido, o prximo passo indicar quais pginas utilizaro esse layout. Por exem-
plo, podemos atualizar a pgina de edio de editoras para utilizar K19Layout.cshtml como layout.
116 www.k19.com.br
117 C AMADA DE A PRESENTAO
Para definir o layout de Edit.cshtml, foi necessrio armazenar o caminho completo do arquivo
que define o layout na propriedade Layout. Este procedimento no muito prtico, pois em cada
pgina que deseja utilizar esse layout necessrio definir esta propriedade.
A partir da terceira verso do ASP.NET MVC, temos uma nova funcionalidade que permite definir
um layout padro para todas as pginas, no havendo necessidade de definir a propriedade Layout
em cada pgina. Para isso, basta acrescentarmos o arquivo _ViewStart.cshtml pasta View:
O _ViewStart.cshtml permite definirmos um cdigo que ser executado antes de cada pgina
ser renderizada. Nesse arquivo podemos definir, por exemplo, a propriedade Layout:
1 @{
2 Layout = " ~/ Views / Shared / K19Layout . cshtml " ;
3 }
www.facebook.com/k19treinamentos 117
C AMADA DE A PRESENTAO 118
Como este cdigo processado antes dos arquivos especficos de cada pgina, no h mais ne-
cessidade de definir a propriedade Layout em cada arquivo especfico.
Lacunas
Tambm podemos criar sees em um layout para serem preenchidas com contedos especficos
definidos nas pginas. Considere o seguinte layout.
No cdigo acima, utilizamos o mtodo @RenderSection() para criar uma seo no layout. O
primeiro parmetro (Sidebar) o nome da seo e o segundo um booleano que indica se o pre-
enchimento dessa seo obrigatrio ou no.
Para definir o contedo de uma seo, devemos utilizar o cdigo @section. Observe o cdigo de
uma pgina que utiliza o layout criado anteriormente e define a seo Sidebar.
Exerccios de Fixao
118 www.k19.com.br
119 C AMADA DE A PRESENTAO
22 Crie um arquivo chamado K19Layout.cshtml dentro da pasta Shared que fica na pasta Views do
projeto CamadaDeApresentacao. Este arquivo servir de modelo para as pginas da nossa aplicao.
23 Altere a pgina Lista.cshtml da pasta Views/Aluno para que ela utilize o layout definido no
exerccio anterior.
www.facebook.com/k19treinamentos 119
C AMADA DE A PRESENTAO 120
24 Defina a pgina K19Layout.cshtml como layout padro para todas as telas. Altere o arquivo
_ViewStart.cshtml da pasta Views.
1 @{
2 Layout = " ~/ Views / Shared / K19Layout . cshtml " ;
3 }
http://localhost:<PORTA_APP>/Home/Index
http://localhost:<PORTA_APP>/Aluno/Detalhes
http://localhost:<PORTA_APP>/Aluno/Editar
http://localhost:<PORTA_APP>/Aluno/Lista
http://localhost:<PORTA_APP>/Usuario/Editar
http://localhost:<PORTA_APP>/Relogio/Agora
25 Altere o arquivo Site.css da pasta Content para aplicar algumas regras de formatao s nossas
pginas.
1 ...
2 header ,
3 # main ,
4 footer {
5 width : 980 px ;
6 margin : 0 auto ;
7 }
8
9 header {
10 border - bottom : 1 px solid #666666;
11 padding : 0 0 10 px 0;
12 }
13
14 header span {
15 font - size : 20 px ;
16 vertical - align : middle ;
17 }
18
19 header img {
20 height : 80 px ;
21 margin : 0 20 px 0 0;
22 vertical - align : middle ;
23 }
24
25 footer {
26 border - top : 1 px solid #666666;
27 padding : 10 px 0 0 0;
28 margin - top : 20 px ;
29 text - align : center ;
30 font - size : 10 px ;
31 }
32
33 # toolbar {
34 background : #999999;
35 width : 970 px ;
36 margin : 1 px auto ;
37 padding : 3 px 5 px ;
38 }
39
120 www.k19.com.br
121 C AMADA DE A PRESENTAO
40 # toolbar * {
41 margin : 3 px 5 px ;
42 }
Teste acessando as pginas da aplicao (Dica: utilize o comando CTRL+F5 para garantir que o
navegador solicite o novo contedo do arquivo Site.css).
http://localhost:<PORTA_APP>/Home/Index
http://localhost:<PORTA_APP>/Aluno/Detalhes
http://localhost:<PORTA_APP>/Aluno/Editar
http://localhost:<PORTA_APP>/Aluno/Lista
http://localhost:<PORTA_APP>/Usuario/Editar
http://localhost:<PORTA_APP>/Relogio/Agora
www.facebook.com/k19treinamentos 121
C AMADA DE A PRESENTAO 122
8 }
9
10 < h2 > Editar </ h2 >
11
12 @using ( Html . BeginForm () )
13 {
14 @Html . EditorForModel ()
15 < input type = " submit " value = " Enviar " / >
16 }
122 www.k19.com.br
123 C AMADA DE A PRESENTAO
http://localhost:<PORTA_APP>/Home/Index
http://localhost:<PORTA_APP>/Aluno/Detalhes
http://localhost:<PORTA_APP>/Aluno/Editar
http://localhost:<PORTA_APP>/Aluno/Lista
http://localhost:<PORTA_APP>/Usuario/Editar
http://localhost:<PORTA_APP>/Relogio/Agora
http://localhost:<PORTA_APP>/Home/Index
http://localhost:<PORTA_APP>/Aluno/Detalhes
www.facebook.com/k19treinamentos 123
C AMADA DE A PRESENTAO 124
http://localhost:<PORTA_APP>/Aluno/Editar
http://localhost:<PORTA_APP>/Aluno/Lista
http://localhost:<PORTA_APP>/Usuario/Editar
http://localhost:<PORTA_APP>/Relogio/Agora
Partial views
Quanto mais elaborada uma pgina de uma aplicao web, mais extenso o seu cdigo. Cdi-
gos muito extensos prejudicam a legibilidade e a manuteno da aplicao. Para organizar melhor o
cdigo, podemos dividir o contedo de uma pgina web em vrios arquivos.
Suponha que desejamos dividir o contedo de uma pgina em duas partes. Devemos criar um
arquivo para cada parte.
Mais Sobre
Por conveno, o nome dos arquivos que definem as telas parciais de uma aplicao
ASP.NET MVC devem iniciar com o caractere _.
Por fim, devemos criar um arquivo principal para agrupar essas partes. Utilizaremos o mtodo
Partial() para inserir o contedo dos arquivos secundrios no arquivo principal.
O recurso de pginas parciais permite a criao de contedo reutilizvel de forma mais clara e
concisa. Informaes podem ser compartilhadas entre as pginas principais e as pginas parciais
124 www.k19.com.br
125 C AMADA DE A PRESENTAO
atravs da propriedade ViewBag. Por exemplo, podemos definir duas pginas principais, uma para
criar e outra para editar editoras. Nessas duas pginas podemos acrescentar uma pgina parcial com
o formulrio que pode ser utilizado para cadastrar novas editoras ou editar editoras existentes.
Veja abaixo o exemplo da pgina parcial que contm o formulrio de cadastro ou edio de edi-
toras.
Veja abaixo o exemplo das pginas principais que utilizam a pgina parcial definida no cdigo
acima.
www.facebook.com/k19treinamentos 125
C AMADA DE A PRESENTAO 126
Exerccios de Fixao
30 Adicione um novo controlador chamado Post utilizando o template Empty MVC Controller.
126 www.k19.com.br
127 C AMADA DE A PRESENTAO
32 Adicione uma partial para exibir as informaes de um Post. Crie um arquivo chamado _Post.cshtml
na pasta Views/Post
www.facebook.com/k19treinamentos 127
C AMADA DE A PRESENTAO 128
128 www.k19.com.br
CAPTULO
C AMADA DE C ONTROLE
7
No ASP.NET MVC as urls so mapeadas para mtodos (aes) em classes que definem os chama-
das controladores. As requisies enviadas pelos navegadores so processadas pelos controlado-
res. O processamento realizado por um controlador para tratar uma requisio consiste basicamente
em:
Acionar a camada de apresentao para construir a pgina HTML que deve ser enviada para o
usurio como resposta sua requisio.
Para que uma classe seja considerada um controlador, ela deve seguir algumas regras.
Raramente, voc definir uma classe para criar um controlador implementando a interface ICon-
troller. Comumente as classes que definem controladores derivam de Controller. Diversas pro-
priedade e mtodos so herdados da classe Controller. Essas propriedades facilitam o processa-
mento das requisies e a utilizao dos recursos do ASP.NET MVC.
Actions
Quando um usurio faz uma requisio HTTP atravs de um navegador, o ASP.NET MVC verifica
na tabela de rotas o controlador e a ao associados url da requisio realizada. Essa tabela
definida no arquivo RouteConfig.cs e inicializada no arquivo Global.asax.
Por padro, quando criamos um projeto ASP.NET MVC no Visual Studio, uma rota com o formato
{controller}/{action}/{id} adicionada na tabela de rotas. Com essa rota, se uma requisio for
www.facebook.com/k19treinamentos 129
C AMADA DE C ONTROLE 130
ActionResult
Considerando uma aplicao ASP.NET MVC 4 em C# e Razor, o mtodo View(), ao ser cha-
mado sem parmetros, executar o seguinte processo para determinar qual arquivo deve ser
utilizado para construir a pgina de resposta.
Por outro lado, podemos especificar o nome do arquivo que define a pgina de resposta. Veja
o exemplo abaixo.
Alm disso, podemos passar um objeto para a camada de apresentao. Esse objeto ser utili-
zado nas pginas fortemente tipadas como vimos no Captulo 6.
Tambm possvel especificar o nome do arquivo que define a pgina de resposta e o objeto
que deve ser transmitido para a camada de apresentao ao mesmo tempo.
130 www.k19.com.br
131 C AMADA DE C ONTROLE
1 return PartialView () ;
1 return File ( @ " c :\ relatorio . pdf " , " application \ pdf " ) ;
Parmetros
Os parmetros enviados pelos usurios atravs de formulrios HTML podem ser recuperados por
meio da propriedade Request.
Esses parmetros tambm podem ser recuperados atravs dos parmetros da ao responsvel
pelo processamento da requisio HTTP realizada. Para isso, basta definir um parmetro C# para
cada parmetro HTTP com o mesmo nome. Veja o exemplo abaixo:
www.facebook.com/k19treinamentos 131
C AMADA DE C ONTROLE 132
No cdigo acima, criamos um formulrio HTML com os parmetros nome e email. Esses par-
metros sero recuperados na ao Salva definida no cdigo abaixo.
1 ...
2 [ HttpPost ]
3 public ActionResult Salva ( string nome , string email )
4 {
5 Editora editora = new Editora { Nome = nome , Email = email };
6 db . Editoras . Add ( editora ) ;
7 return View () ;
8 }
9 ...
O ASP.NET MVC tambm capaz de montar objetos com os valores dos parmetros HTTP envi-
ados pelo usurio e pass-los como argumento para as aes dos controladores.
1 [ HttpPost ]
2 public ActionResult Salva ( Editora editora )
3 {
4 db . Editoras . Add ( editora ) ;
5 return View () ;
6 }
As propriedades dos objetos recebidos como argumentos nas aes dos controladores precisam
ter os mesmos nomes dos parmetros HTTP ignorando-se letras maisculas ou minsculas.
Exerccios de Fixao
132 www.k19.com.br
133 C AMADA DE C ONTROLE
3 Adicione um DbContext para registrar a entidade Produto e utilizar os recursos do Entity Fra-
mework. Crie uma classe chamada K19Context na pasta Models.
www.facebook.com/k19treinamentos 133
C AMADA DE C ONTROLE 134
33 }
34 }
5 Adicione uma tela associada ao Lista do controlador Produto com o seguinte contedo.
6 Adicione uma tela associada ao Cadastra do controlador Produto com o seguinte contedo.
134 www.k19.com.br
135 C AMADA DE C ONTROLE
TempData
Ao efetuar um redirecionamento, uma nova requisio realizada pelo navegador. Nesta nova
requisio, no temos mais acesso aos dados e objetos da requisio anterior ao redirecionamento.
Caso haja a necessidade de preservar dados ao longo do redirecionamento, podemos utilizar a pro-
priedade TempData.
Por exemplo, ao cadastrar uma editora, podemos efetuar um redirecionamento para a tela de
listagem de editoras. Na propriedade TempData, podemos acrescentar uma mensagem indicando o
eventual sucesso da operao. Veja o exemplo abaixo.
1 ...
2 [ HttpPost ]
3 public ActionResult Salva ( Editora editora )
4 {
5 db . Editoras . Add ( editora ) ;
6 db . SaveChanges () ;
7 TempData [ " Mensagem " ] = " Editora cadastrada com sucesso ! " ;
8 return RedirectToAction ( " Index " ) ;
9 }
10 ...
www.facebook.com/k19treinamentos 135
C AMADA DE C ONTROLE 136
Exerccios de Fixao
1 ...
2 public ActionResult Cadastra ( Produto p )
3 {
4 K19Context ctx = new K19Context () ;
5 ctx . Produtos . Add ( p ) ;
6 ctx . SaveChanges () ;
7
8 ViewBag . Mensagem = " Produto cadastrado com sucesso ! " ;
9
10 return RedirectToAction ( " Lista " ) ;
11 }
12 ...
136 www.k19.com.br
137 C AMADA DE C ONTROLE
1 ...
2 public ActionResult Cadastra ( Produto p )
3 {
4 K19Context ctx = new K19Context () ;
5 ctx . Produtos . Add ( p ) ;
6 ctx . SaveChanges () ;
7
8 TempData [ " Mensagem " ] = " Produto cadastrado com sucesso ! " ;
9
10 return RedirectToAction ( " Lista " ) ;
11 }
12 ...
Rotas
www.facebook.com/k19treinamentos 137
C AMADA DE C ONTROLE 138
Para acessar uma determinada ao da nossa aplicao, os usurios devem realizar uma requi-
sio HTTP utilizando a url correspondente ao. Por exemplo, para acessar a listagem de edito-
ras, necessrio digitar na barra de endereo do navegador a url http://localhost:<PORTA_APP>
/Editora/Index. Perceba que o o nome do controlador e o nome da ao desejados fazem parte da
url. O formato dessas urls definido por rotas criadas no arquivo RouteConfig.cs e carregadas no
arquivo Global.asax. O cdigo abaixo mostra a rota padro inserida nos projetos ASP.NET MVC 4.
1 routes . MapRoute (
2 name : " Default " ,
3 url : " { controller }/{ action }/{ id } " ,
4 defaults : new { controller = " Home " , action = " Index " , id = UrlParameter . Optional }
5 );
O primeiro argumento do mtodo MapRoute o nome da rota, o segundo a expresso que define
o formato da rota e o terceiro o conjunto de valores padro dos parmetros da rota.
A expresso que determina o formato da rota Default utiliza trs parmetros: controller, action
e id. Dessa forma, se o usurio realizar uma requisio HTTP utilizando url http://localhost:
<PORTA_APP>/Editora/Remove/1, o ASP.NET MVC criar uma instncia do controlador Editora e
executar o mtodo Remove() passando o valor 1 como argumento.
Basicamente, as rotas associam urls e aes. Veja alguns exemplos de como as urls sero proces-
sadas de acordo com as regras de rotas.
1 ...
2 routes . MapRoute (
3 name : " Nova Rota " ,
4 url : " Catalogo " ,
5 defaults : new { controller = " Editora " , action = " Index " }
6 );
7 ...
Importante
As rotas so processadas na ordem em que foram inseridas. Portanto, importante
definir as rotas mais especficas antes das rotas mais genricas.
138 www.k19.com.br
139 C AMADA DE C ONTROLE
1 routes . MapRoute (
2 name : " Nova Rota " ,
3 url : " Catalogo /{ maximo } " ,
4 defaults : new { controller = " Editora " , action = " Index " }
5 );
Por padro, os parmetros adicionados a uma rota so obrigatrios. Dessa forma, no exemplo
acima, a listagem de editoras s poder ser acessada se o valor do parmetro maximo for definido na
url da requisio. Por exemplo, http://localhost:<PORTA_APP>/Catalogo/20. Se uma requisio
for realizada para a url http://localhost:<PORTA_APP>/Catalogo, um erro ocorrer. Para mudar
esse comportamento, podemos tornar o parmetro maximo opcional. Veja o cdigo a seguir.
1 ...
2 routes . MapRoute (
3 name : " Nova Rota " ,
4 url : " Catalogo /{ maximo } " ,
5 defaults : new { controller = " Editora " , action = " Index " ,
6 maximo = UrlParameter . Optional }
7 );
8 ...
Os parmetros das rotas podem ser recuperados nas aes. Observe o exemplo abaixo.
1 ...
2 public ActionResult Index ( int ? maximo )
3 {
4 // implementao
5 }
6 ...
Ao definir parmetros opcionais, devemos utilizar parmetros do tipo nullable type nas aes,
pois quando o parmetro no estiver definido na url de uma requisio, o valor null ser atribudo
ao parmetro da ao. Por exemplo, para os tipos int e double, devemos utilizar int? e double?,
respectivamente.
Exerccios de Fixao
12 Altere a rota padro do projeto CamadaDeControle. Para isso, modifique o arquivo RouteCon-
fig.cs da pasta App_Start.
1 ...
2 routes . MapRoute (
3 name : " Default " ,
www.facebook.com/k19treinamentos 139
C AMADA DE C ONTROLE 140
13 Adicione uma rota no projeto CamadaDeControle. Para isso, modifique o arquivo RouteCon-
fig.cs da pasta App_Start.
1 ...
2 routes . MapRoute (
3 name : " ProdutoListaPorPreco " ,
4 url : " Produto / Lista /{ PrecoMinimo }/{ PrecoMaximo } " ,
5 defaults : new { controller = " Produto " , action = " Lista " }
6 );
7 ...
1 ...
2 public ActionResult Lista ( double ? precoMinimo , double ? precoMaximo )
3 {
4 K19Context ctx = new K19Context () ;
5 var produtos = ctx . Produtos . AsEnumerable () ;
6
7 if ( precoMinimo != null && precoMaximo != null )
8 {
9 produtos = from p in produtos
10 where p . Preco >= precoMinimo & p . Preco <= precoMaximo
11 select p ;
12 }
13
14 return View ( produtos ) ;
15 }
16 ...
1 ...
2 public ActionResult Editar ( int id = 0)
3 {
4 K19Context ctx = new K19Context () ;
5 Produto p = ctx . Produtos . Find ( id ) ;
140 www.k19.com.br
141 C AMADA DE C ONTROLE
6
7 if ( p == null )
8 {
9 return HttpNotFound () ;
10 }
11
12 return View ( p ) ;
13 }
14
15 [ HttpPost ]
16 public ActionResult Editar ( Produto p )
17 {
18 K19Context ctx = new K19Context () ;
19 ctx . Entry ( p ) . State = System . Data . EntityState . Modified ;
20
21 ctx . SaveChanges () ;
22
23 return RedirectToAction ( " Lista " ) ;
24 }
25 ...
16 Modifique a pgina de listagem de produtos. Para isso, altere o arquivo Lista.cshtml da pasta
Views/Produto.
www.facebook.com/k19treinamentos 141
C AMADA DE C ONTROLE 142
3 @{
4 ViewBag . Title = " Editar " ;
5 }
6
7 <h2 > Editar </ h2 >
8
9 @using ( Html . BeginForm () )
10 {
11 @Html . EditorFor ( m = > m . ProdutoID )
12 <div > @Html . LabelFor ( m = > m . Nome ) </ div >
13 @Html . EditorFor ( m = > m . Nome )
14 <div > @Html . LabelFor ( m = > m . Descricao ) </ div >
15 @Html . EditorFor ( m = > m . Descricao )
16 <div > @Html . LabelFor ( m = > m . Preco ) </ div >
17 @Html . EditorFor ( m = > m . Preco )
18
19 <div > < input type = " submit " value = " Editar " / > </ div >
20 }
142 www.k19.com.br
CAPTULO
VALIDAO
8
Os usurios podem cometer erros ao preencher um formulrio. Por exemplo, esquecer de preen-
cher um campo que obrigatrio. Os parmetros enviados pelos usurios devem ser validados pela
aplicao com o intuito de no permitir o armazenamento de informaes erradas.
Controller
O primeiro passo para implementar a validao dos parmetros enviados atravs de formulrios
HTML definir a lgica de validao na camada de controle.
O segundo passo definir mensagens informativas para enviar aos usurios. O ASP.NET MVC
possui um objeto especializado no armazenamento de mensagens de erros de validao. Esse objeto
pode ser acessado atravs da propriedade ModelState.
O cdigo de validao pode ser colocado nos controladores, mais especificamente nas aes. Se
algum erro for encontrado, o fluxo de execuo pode ser redirecionado para uma pgina que mostre
as mensagens informativas aos usurios. Normalmente, essa pgina a mesma do formulrio que
foi preenchido incorretamente. O ModelState possui uma propriedade que indica se erros foram
adicionados ou no. Essa propriedade chama-se IsValid.
1 [ HttpPost ]
2 public ActionResult Salva ( Editora editora )
3 {
4 if ( editora . Nome == null || editora . Nome . Trim () . Length == 0)
5 {
6 ModelState . AddModelError ( " Nome " , " O campo Nome obrigatrio . " ) ;
7 }
8 if ( ModelState . IsValid )
9 {
www.facebook.com/k19treinamentos 143
VALIDAO 144
O ASP.NET MVC tambm pode adicionar mensagens no ModelState antes do controlador ser
chamado. Normalmente, essas mensagens esto relacionadas a erros de converso. Por exemplo,
um campo que espera um nmero preenchido com letras.
View
As mensagens de erros de validao podem ser acrescentadas em uma pgina atravs do mtodo
ValidationSummary() da propriedade Html. importante salientar que esse mtodo adiciona todas
as mensagens de erro.
Para no mostrar erros dos grupos com o ValidationSummary(), devemos passar como parme-
tro o valor true. Nesse caso, apenas os erros que no esto associados a um grupo especfico sero
apresentados pelo ValidationSummary().
144 www.k19.com.br
145 VALIDAO
Exerccios de Fixao
1 Crie um projeto do tipo ASP.NET MVC 4 Web Application chamado Validacao no Visual Studio
2012 Express for Web. Utilize o template Basic Project.
3 Adicione um DbContext para registrar a entidade Jogador e utilizar os recursos do Entity Fra-
mework. Crie uma classe chamada K19Context na pasta Models.
www.facebook.com/k19treinamentos 145
VALIDAO 146
5 Adicione uma tela associada ao Lista do controlador Jogador com o seguinte contedo.
146 www.k19.com.br
147 VALIDAO
6 Adicione uma tela associada ao Cadastra do controlador Jogador com o seguinte contedo.
1 ...
2 [ HttpPost ]
3 public ActionResult Cadastra ( Jogador j )
4 {
5 if ( String . IsNullOrEmpty ( j . Nome ) )
6 {
7 ModelState . AddModelError ( " Nome " ,
8 " O nome do jogador obrigatrio " ) ;
9 }
10 if ( j . Numero == null || j . Numero <= 0 || j . Numero >= 100)
11 {
12 ModelState . AddModelError ( " Numero " ,
13 " O nmero do jogador deve ser maior que 0 e menor que 100 " ) ;
14 }
15 if ( j . Altura == null || j . Altura < 0)
16 {
17 ModelState . AddModelError ( " Altura " ,
18 " A altura do jogador no pode ser negativa " ) ;
19 }
20
21 if ( ModelState . IsValid )
22 {
23 K19Context ctx = new K19Context () ;
24 ctx . Jogadores . Add ( j ) ;
25 ctx . SaveChanges () ;
26 return RedirectToAction ( " Lista " ) ;
27 }
28 else
29 {
30 return View ( " Cadastra " , j ) ;
31 }
32 }
www.facebook.com/k19treinamentos 147
VALIDAO 148
33 ...
Anotaes
As lgicas de validao tambm podem ser definidas atravs de anotaes adicionadas nas clas-
ses de modelo. Dessa forma, essas lgicas no estariam mais nos controladores, o que conceitual-
mente o ideal, pois nos controladores s deveria existir lgica para controlar o fluxo da execuo.
Required
Uma das validaes mais comuns a de campo obrigatrio. Ela pode ser realizada atravs da
anotao Required para propriedades do tipo string.
148 www.k19.com.br
149 VALIDAO
Com essa anotao, a lgica de validao pode ser retirada do controlador Editora.
1 ...
2 [ HttpPost ]
3 public ActionResult Salva ( Editora editora )
4 {
5 if ( ModelState . IsValid )
6 {
7 db . Editoras . Add ( editora ) ;
8 return RedirectToAction ( " Index " ) ;
9 }
10 else
11 {
12 return View ( " Cadastra " , editora ) ;
13 }
14 }
15 ...
Alterando a mensagem
As anotaes de validao possuem mensagens padro que podem ser alteradas atravs do atri-
buto ErrorMessage.
1 ...
2 [ Required ( ErrorMessage = " O campo Nome obrigatrio " ) ]
3 public string Nome { get ; set ; }
4 ...
Outros validadores
H outras anotaes para validao:
Range
ReqularExpression
StringLength
As validaes podem ser realizadas tambm nos navegadores para melhorar a interao com os
usurios.
Antes da terceira verso do ASP.NET MVC, era necessrio habilitar a validao no lado do cliente
atravs do mtodo Html.EnableClientValidation(). A partir da terceira verso do ASP.NET MVC,
a validao no cliente est habilitada por padro.
Para que a validao no lado cliente funcione corretamente, devemos acrescentar as bibliotecas
javascript necessrias. No ASP.NET MVC 4, basta acrescentar a seo de scripts nas pginas.
1 @section Scripts {
2 @Scripts . Render ( " ~/ bundles / jqueryval " )
3 }
www.facebook.com/k19treinamentos 149
VALIDAO 150
Exerccios de Fixao
1 ...
2 [ HttpPost ]
3 public ActionResult Cadastra ( Jogador j )
4 {
5 if ( ModelState . IsValid )
6 {
7 K19Context ctx = new K19Context () ;
8 ctx . Jogadores . Add ( j ) ;
9 ctx . SaveChanges () ;
10 return RedirectToAction ( " Lista " ) ;
11 }
12 else
13 {
14 return View ( " Cadastra " , j ) ;
15 }
16 }
17 ...
11 Para adicionar a validao no lado do cliente, basta alterar a pgina de cadastro de jogadores.
Observe o cdigo abaixo.
150 www.k19.com.br
151 VALIDAO
www.facebook.com/k19treinamentos 151
VALIDAO 152
152 www.k19.com.br
CAPTULO
S ESSO
9
Considere a aplicao de uma loja virtual. Nessa aplicao, os clientes selecionam os produtos
desejados e os adiciona no seu carrinho de compra. Cada cliente deve ter o seu prprio carrinho para
que os seus produtos no se misturem com os produtos selecionados por outros clientes. A aplicao
deve armazenar o carrinho de um cliente at que a compra seja finalizada ou at ela ter certeza que
o cliente no precisa mais do carrinho.
Para resolver esse problema, podemos utilizar o conceito de Sesso. Para cada navegador co-
nectado, o servidor manter uma sesso aberta. Dessa forma, podemos separar os dados de cada
usurio conectado.
Identificando os navegadores
Para aplicar a ideia de Sesso, necessrio ter a capacidade de identificar o navegador que est
requisitando a aplicao a cada requisio. Uma primeira abordagem seria utilizar o endereo IP da
mquinas para identificar os navegadores. Porm, nessa abordagem, dois navegadores executando
na mesma mquina no poderiam ser identificados individualmente.
Outra abordagem deixar a cargo do servidor a criao de um identificador nico para cada
navegador conectado. Quando um navegador faz a primeira requisio para a aplicao, o servi-
dor deve gerar um identificador nico para esse navegador e envi-lo na resposta HTTP. A partir da
segunda requisio, os navegadores devem enviar para a aplicao o identificador recebido na pri-
meira requisio. Desta maneira, a aplicao saber qual o navegador que est realizando uma
requisio. Os navegadores podem enviar os seus respectivos identificadores de diferentes formas.
As mais utilizadas so:
Reescrita de URL Nesta abordagem, os identificadores so embutidos nos links e botes das pginas
da aplicao. Quando os links ou botes so clicados pelo usurio, o identificador enviado
para a aplicao. Uma desvantagem que todas as pginas devem ser geradas dinamicamente
para adicionar o identificador em todos os links e botes.
Cookies Cookies so arquivos contendo informaes. Eles so gerados nos servidores e enviados
para os navegadores. Os navegadores armazenam os cookies localmente na mquina do usu-
rio. Alm disso, os navegadores enviam os cookies de volta para o servidor em todas as requi-
sies. Os servidores podem armazenar os identificadores gerados em cookies. Dessa forma, a
cada requisio, o servidor receber um cookie contendo o identificador.
www.facebook.com/k19treinamentos 153
S ESSO 154
No ASP.NET MVC, o objeto que representa uma sesso um dicionrio. Para armazenar infor-
maes, voc deve adicionar uma chave e um valor na propriedade Session. Considere um objeto
da classe Usuario que agrupa as informaes sobre um determinado usurio. O cdigo a seguir
um exemplo de como podemos guardar esse objeto na sesso aps a realizao da autenticao do
usurio.
Voc pode adicionar qualquer tipo de valor na sesso. De forma anloga, para resgatar as infor-
maes armazenadas, basta acessar a chave correspondente da propriedade Session. Veja o exem-
plo a seguir:
Quando um usurio deslogar, podemos eliminar a informao armazenada em sua sesso. Para
isso, podemos simplesmente remover todas as chaves do dicionrio como no exemplo a seguir.
1 Session . RemoveAll () ;
Contudo, o mtodo RemoveAll() no elimina a sesso. Ele apenas remove os dados contidos na
sesso. Para elimin-la, voc deve utilizar o mtodo Abandon(). Observe o exemplo a seguir.
Session Mode
InProc
154 www.k19.com.br
155 S ESSO
StateServer
SQLServer
Custom
Para selecionar algum dos modos disponveis, basta adicionar a tag <sessionState> dentro da
tag <system.web>, no arquivo Web.Config da raiz de um projeto ASP.NET MVC 4.
Podemos personalizar nossa sesso, modificando alguns atributos da tag <sessionState>. Por
exemplo, podemos determinar o tempo de timeout das sesses. Veja o exemplo abaixo.
1 < sessionState mode = " InProc " timeout = " 30 " / >
Outra possibilidade desabilitar o uso de cookie com o atributo cookieless. Neste caso ser
utilizada a reescrita de URL.
1 < sessionState mode = " InProc " cookieless = " true " / >
Exerccios de Fixao
www.facebook.com/k19treinamentos 155
S ESSO 156
1 Crie um projeto do tipo ASP.NET MVC 4 Web Application chamado Sessao no Visual Studio
2012 Express for Web. Utilize o template Basic Project.
3 Adicione uma classe chamada K19Context na pasta Models para registrar a entidade Produto
e utilizar os recursos do Entity Framework. Lembre-se de fazer com que sua classe herde da classe
DbContext.
156 www.k19.com.br
157 S ESSO
3 @{
4 ViewBag . Title = " Index " ;
5 }
6
7 < h2 > Index </ h2 >
8
9 @if ( TempData [ " Mensagem " ] != null )
10 {
11 < div > @TempData [ " Mensagem " ] </ div >
12 }
13
14 <p >
15 @Html . ActionLink ( " Create New " , " Create " )
16 </ p >
17 < table >
18 < tr >
19 < th >
20 @Html . DisplayNameFor ( model = > model . Nome )
21 </ th >
22 < th >
23 @Html . DisplayNameFor ( model = > model . Preco )
24 </ th >
25 < th > </ th >
26 </ tr >
27
28 @foreach ( var item in Model ) {
29 < tr >
30 < td >
31 @Html . DisplayFor ( modelItem = > item . Nome )
32 </ td >
33 < td >
34 @Html . DisplayFor ( modelItem = > item . Preco )
35 </ td >
36 < td >
37 @Html . ActionLink ( " Edit " , " Edit " , new { id = item . ProdutoID }) |
38 @Html . ActionLink ( " Details " , " Details " , new { id = item . ProdutoID }) |
39 @Html . ActionLink ( " Delete " , " Delete " , new { id = item . ProdutoID }) |
40 @Html . ActionLink ( " Adicionar ao carrinho " , " Adicionar " , " Carrinho " , new { id = -
item . ProdutoID } , null )
41 </ td >
42 </ tr >
43 }
44 </ table >
www.facebook.com/k19treinamentos 157
S ESSO 158
8 Adicione uma tela associada ao Index do controlador Carrinho com o seguinte contedo.
158 www.k19.com.br
159 S ESSO
www.facebook.com/k19treinamentos 159
S ESSO 160
160 www.k19.com.br
CAPTULO
F ILTROS
10
Muitas vezes, queremos restringir o acesso determinadas reas de uma aplicao, seja por ques-
tes de segurana ou por organizao. Em nossa aplicao poderamos, por exemplo, definir que
para poder adicionar, alterar e remover editoras, o usurio deve estar logado no sistema. Caso con-
trrio, o usurio apenas poder listar as editoras.
1 ...
2 public ActionResult Cadastra ()
3 {
4 if ( Session [ " Cliente " ] != null )
5 {
6 return base . View () ;
7 }
8 else
9 {
10 return base . RedirectToAction ( " Index " , " Login " ) ;
11 }
12 }
13 ...
No exemplo acima, caso um usurio tente adicionar uma editora atravs do formulrio de ca-
dastro, a ao Cadastra verificar se o usurio j est logado. Essa verificao realizada atravs
do uso da sesso, como visto no captulo 9. Se o usurio no estiver logado, ele ser redirecionado
para a pgina de Login. Apesar de funcionar, este cdigo apresenta uma inconvenincia. Temos que
adicionar essa lgica em todas as aes que queremos que tenha o mesmo comportamento, ou seja,
que apenas permitam o acesso de usurios logados.
Em outros casos, podemos desejar que algumas aes executem alguma tarefa em comum. Por
exemplo, poderamos adicionar uma mensagem em um arquivo de logging sempre que uma ao
fosse executada. Desse modo, poderamos guardar um histrico sobre o que a aplicao mais execu-
tou, qual foi a pgina mais visitada, etc. Mas novamente, teramos que adicionar a mesma tarefa em
todas as aes da nossa aplicao.
Nesses casos, em que vrias aes possuem um comportamento em comum, podemos utilizar o
conceito de filtros. Um filtro semelhante a um mtodo que executado antes ou depois de uma
ao.
Tipos de Filtros
www.facebook.com/k19treinamentos 161
F ILTROS 162
Autorizao
Filtro utilizado para restringir o acesso a ao do controlador a usurios autenticados e autoriza-
dos. Caso o usurio no tenha permiso, o filtro retorna a resposta 401 HTTP Unauthorized. Se o
filtro for adicionado ao controlador, todas as aes tero o acesso restrito.
Importante
Este filtro executado antes dos outros filtros.
Ao
Este filtro executado antes ou depois da ao ser executada. Este filtro chamado depois do
filtro de autorizao e antes do filtro de resultado.
Resultado
O filtro de resultado executado antes ou depois do resultado da ao ser processado. Este filtro
permite alterarmos a maneira como o resultado da ao gerado.
Exceo
Este filtro utilizado para tratar as excees. Este filtro executado quando ocorre uma exceo
no mtodo ou nos filtros da ao.
Filtro de Autorizao
O mtodo OnAuthorization executado pelo ASP .NET MVC para realizar a autorizao. A classe
AuthorizationContext derivada de ControllerContext, que permite o acesso aos dados do con-
trolador, da rota e da requisio.
O ASP .NET MVC contm uma implementao padro da IAuthorizationFilter que a classe
AuthorizeAttribute. A classe AuthorizeAttribute define a anotao Authorize, que pode ser adi-
cionada a ao ou ao controlador para restringirmos o acesso a usurios autenticados e autorizados.
162 www.k19.com.br
163 F ILTROS
Importante
Ao criar um projeto ASP.NET MVC utilizando o template Basic Project, a aplicao
configurada para utilizar o ASP.NET Forms Authentication automaticamente.
Para o nosso primeiro exemplo, podemos utilizar o filtro de autorizao, onde exigimos que o
usurio esteja logado (autenticado) para acessar determinadas reas da aplicao. Para isso, preci-
samos adicionar o seguinte cdigo no nosso mtodo de login:
1 ...
2 FormsAuthentication . SetAuthCookie ( usuario . Username , false ) ;
3 ...
Isto adiciona um novo cookie utilizado para a autenticao do usurio. Este novo cookie in-
dependente do cookie utilizado para armazenar informaes da sesso. O primeiro parmetro
referente ao nome do usurio (ou algo que o identifique). O segundo parmetro um booleano re-
lativo ao tipo do cookie, se permanente ou no. Caso seja true, ele sempre ir considerar que o
usurio est autenticado aps a primeira autenticao.
Para eliminar o cookie de autenticao, devemos adicionar o seguinte cdigo na aco de logout:
1 ...
2 FormsAuthentication . SignOut () ;
3 ...
As aes que devem utilizar o filtro de autorizao devem ser anotadas com Authorize.
1 ...
2 [ Authorize ]
3 public ActionResult Cadastra ()
4 {
5 return base . View () ;
6 }
7 ...
1 [ Authorize ]
2 public class EditoraController : Controller
3 {
4 ...
5 }
www.facebook.com/k19treinamentos 163
F ILTROS 164
Desse modo, todas as aes presentes no controlador da Editora exigem que o usurio esteja
autenticado.
Quando o filtro de autorizao barra um usurio de acessar uma pgina, podemos redirecion-
lo para a pgina de login. Devemos incluir o seguinte cdigo dentro da tag <system.web> do arquivo
Web.Config.
Atravs da propriedade User, podemos obter o usurio associado a requisio atual. As infor-
maes do usurio podem ser obtidas atravs da propriedade Identity. Por exemplo, podemos
verificar se o usurio associado requisio atual est autenticado, basta utilizar a propriedade
IsAuthenticated da propriedade Identity:
Para obter o nome do usurio autenticado, podemos utilizar a propriedade Name da propriedade
Identity:
A propriedade Name retorna o nome do usurio que passamos como parmetro para o mtodo
SetAuthCookie na autenticao.
Exerccios de Fixao
1 Crie um projeto do tipo ASP.NET MVC 4 Web Application chamado Filtros no Visual Studio
2012 Express for Web. Utilize o template Basic Project.
164 www.k19.com.br
165 F ILTROS
3 Adicione uma classe chamada K19Context na pasta Models para registrar a entidade Produto
e utilizar os recursos do Entity Framework. Lembre-se de fazer com que sua classe herde da classe
DbContext.
1 using System ;
2 using System . Collections . Generic ;
3 using System . Linq ;
4 using System . Web ;
5 using System . Web . Mvc ;
6 using System . Web . Security ;
7 using Filtros . Models ;
8
9 namespace Filtros . Controllers
10 {
11 public class AutenticadorController : Controller
12 {
13
14 public ActionResult Formulario ()
15 {
16 return View () ;
17 }
18
19 public ActionResult Entrar ( Usuario usuario )
20 {
21 if ( usuario . Username != null && usuario . Password != null &&
22 usuario . Username . Equals ( " K19 " ) && usuario . Password . Equals ( " K19 " ) )
23 {
24
25 Session [ " Usuario " ] = usuario ;
26 return RedirectToAction ( " Index " , " Produto " ) ;
27 }
28 else
29 {
30 ViewBag . Mensagem = " usurio ou senha incorretos " ;
31 return View ( " Formulario " ) ;
www.facebook.com/k19treinamentos 165
F ILTROS 166
32 }
33 }
34
35 public ActionResult Sair ()
36 {
37 Session . Abandon () ;
38 return RedirectToAction ( " Formulario " ) ;
39 }
40 }
41 }
166 www.k19.com.br
167 F ILTROS
4 {
5 private K19Context db = new K19Context () ;
6
7 public ActionResult Index ()
8 {
9 return View ( db . Produtos . ToList () ) ;
10 }
11
12 public ActionResult Cadastrar ()
13 {
14 if ( Session [ " Usuario " ] != null )
15 {
16 return View () ;
17 }
18 else
19 {
20 TempData [ " Mensagem " ] = " Acesso no permitido " ;
21 return RedirectToAction ( " Index " ) ;
22 }
23
24 }
25
26 [ HttpPost ]
27 public ActionResult Cadastrar ( Produto produto )
28 {
29 if ( ModelState . IsValid )
30 {
31 db . Produtos . Add ( produto ) ;
32 db . SaveChanges () ;
33 return RedirectToAction ( " Index " ) ;
34 }
35 return View ( produto ) ;
36 }
37
38
39 }
40 }
www.facebook.com/k19treinamentos 167
F ILTROS 168
30 < td >
31 @Html . DisplayFor ( modelItem = > item . Nome )
32 </ td >
33 < td >
34 @Html . DisplayFor ( modelItem = > item . Preco )
35 </ td >
36
37 </ tr >
38 }
39
40 </ table >
168 www.k19.com.br
169 F ILTROS
7 Ao invs de usar sesso, vamos utilizar o filtro de autorizao do ASP.NET MVC. Primeiro, deve-
mos alterar as aes Entrar e Sair do controlador Autenticador.
8 Altere o controlador Produto para que somente usurios logados possam acessar o formulrio
de cadastro.
1 ...
2 [ Authorize ]
3 public ActionResult Cadastra ()
4 {
5 return View () ;
6 }
7 ...
www.facebook.com/k19treinamentos 169
F ILTROS 170
10 Defina a url para a qual os usurios no logados sero redirecionados ao tentarem acessar o
formulrio de cadastro de editoras. Altere o arquivo Web.config da raiz do projeto Filtros.
1 ...
2 < authentication mode = " Forms " >
3 < forms loginUrl = " ~/ Autenticador / Formulario " timeout = " 2880 " / >
4 </ authentication >
5 ...
Filtro de Ao
Atravs do filtro de aes podemos, por exemplo, salvar as informaes das requisies num
arquivo de log. Para isto, basta definirmos uma classe que implementa a interface IActionFilter:
170 www.k19.com.br
171 F ILTROS
Para aplicar o filtro a todos os controladores e todas aes, basta defini-lo como global. Para defi-
nir LoggingFilter como global, basta adicion-lo coleo de filtros globais do mtodo Register-
GlobalFilters da classe FilterConfig.
Exerccios de Fixao
www.facebook.com/k19treinamentos 171
F ILTROS 172
172 www.k19.com.br
173 F ILTROS
13 Defina o filtro de ao criado no exerccio anterior como global, para que ele seja aplicado a
todos os controladores e aes.
1 namespace Filtros
2 {
3 public class FilterConfig
4 {
5 public static void RegisterGlobalFilters ( GlobalFilterCollection filters )
6 {
7 filters . Add ( new HandleErrorAttribute () ) ;
8 filters . Add ( new LoggingFilter () ) ;
9 }
10 }
11 }
http://localhost:<PORTA_APP>/Produto
http://localhost:<PORTA_APP>/Autenticador/Entrar
http://localhost:<PORTA_APP>/Produto/Cadastrar
E verifique, posteriormente, que as informaes das requisies foram salvas no arquivo Requi-
sicoesInfo.log dentro do diretrio Logs.
www.facebook.com/k19treinamentos 173
F ILTROS 174
Filtro de Resultado
Atravs do filtro de resultado, podemos, por exemplo, mensurar o tempo entre a execuo de uma
ao e a gerao do resultado. Para isto, podemos criar uma classe que derivada de ActionFilter-
Attribute.
Importante
A classe ActionFilterAttribute uma implementao padro das interfaces
174 www.k19.com.br
175 F ILTROS
1 ...
2
3 [ ElapsedTime ]
4 public ActionResult Index ()
5 {
6 return View ( db . Produtos . ToList () ) ;
7 }
8
9 ...
www.facebook.com/k19treinamentos 175
F ILTROS 176
Exerccios de Fixao
14 Adicione ao projeto Filtros um filtro para medir o tempo entre a execuo de uma ao e a
gerao do resultado. Dica: Utilize a classe ActionFilterAttribute para criar o filtro.
Filtro de Exceo
Os filtros de exceo so executados quando ocorrem excees nas aes ou nos filtros. Os filtros
de exceo devem implementar a interface IExceptionFilter.
176 www.k19.com.br
177 F ILTROS
O ASP .NET MVC contm a classe HandleErrorAttribute que uma implementao padro
de IExceptionFilter. O filtro HandleErrorAttribute retorna a pgina Error localizada na pasta
Views/Shared quando ocorre uma exceo. Atravs da HandleErrorAttribute podemos alterar a
pgina de erro retornada de acordo com o tipo de exceo.
Exerccios de Fixao
16 Altere o controlador Produto do projeto Filtros. Acrescente uma ao para visualizar um pro-
duto de uma lista atravs de uma posio. A ao dever receber como parmetro a posio, que
ser definida pelo usurio atravs da url.
17 Defina uma pgina para mostrar os dados do produto que foi selecionado de acordo com a
posio.
www.facebook.com/k19treinamentos 177
F ILTROS 178
11
12 < div class = " display - label " >
13 @Html . DisplayNameFor ( model = > model . Nome )
14 </ div >
15 < div class = " display - field " >
16 @Html . DisplayFor ( model = > model . Nome )
17 </ div >
18
19 < div class = " display - label " >
20 @Html . DisplayNameFor ( model = > model . Preco )
21 </ div >
22 < div class = " display - field " >
23 @Html . DisplayFor ( model = > model . Preco )
24 </ div >
25 </ fieldset >
26 <p >
27 @Html . ActionLink ( " Back to List " , " Index " )
28 </ p >
http://localhost:<PORTA_APP>/produto/visualizar?posicao=0
http://localhost:<PORTA_APP>/produto/visualizar?posicao=1
http://localhost:<PORTA_APP>/produto/visualizar?posicao=-1
178 www.k19.com.br
179 F ILTROS
1 @{
2 ViewBag . Title = " Posio Invlida " ;
3 }
4
5 < h2 > Voc acessou uma posio invlida . </ h2 >
http://localhost:<PORTA_APP>/produto/visualizar?posicao=-1
www.facebook.com/k19treinamentos 179
F ILTROS 180
180 www.k19.com.br
CAPTULO
T RATAMENTO DE E RROS
11
Inevitavelmente, as aplicaes esto sujeitas a erros de vrias naturezas. Por exemplo, erros po-
dem ser gerados pelo preenchimento incorreto dos campos de um formulrio. Esse tipo de erro
causado por falhas dos usurios. Nesse caso, importante mostrar mensagens informativas com o
intuito de fazer o prprio usurio corrigir os valores preenchidos incorretamente. Veja o Captulo 8.
Por outro lado, h erros que no so causados por falhas dos usurios. Por exemplo, um erro de
conexo com o banco de dados. Nesses casos, improvvel que os usurios possam fazer algo que
resolva o problema. E mesmo que pudessem, provavelmente, no seria conveniente esperar que eles
o fizessem.
Quando um erro desse tipo ocorre, o ASP.NET MVC cria uma pgina web com informaes so-
bre o erro e a envia aos usurios. Para usurios locais, o ASP.NET MVC envia uma pgina web com
informaes detalhadas do erro ocorrido. Para usurios remotos, a pgina web enviada no contm
informaes detalhadas.
Em geral, no conveniente que os usurios recebam detalhes tcnicos sobre os erros gerados
por falhas da aplicao. A primeira justificativa que esses detalhes podem confundir os usurios.
Figura 11.1: Exemplo de uma pgina web com informaes sobre um erro
www.facebook.com/k19treinamentos 181
T RATAMENTO DE E RROS 182
A segunda justificativa que esses detalhes podem expor alguma falha de segurana da aplicao,
deixando-a mais vulnervel a ataques.
Try-Catch
Os erros de aplicao podem ser identificados atravs do comando try-catch, que pode ser
colocados nos mtodos que definem as aes dos controladores. Ao identificar a ocorrncia de um
erro, os controladores podem devolver uma pgina web com alguma mensagem para o usurio.
1 ...
2 [ HttpPost ]
3 public ActionResult Salva ( Editora editora )
4 {
5 try
6 {
7 db . Editoras . Add ( editora ) ;
8 }
9 catch
10 {
11 return View ( " Error " ) ;
12 }
13
14 return RedirectToAction ( " Index " ) ;
15 }
16 ...
Podemos criar uma pgina Error.cshtml na pasta Views\Shared. Dessa forma, todo controlador
poder devolver essa pgina.
1 @{
2 Layout = null ;
3 }
4
5 <! DOCTYPE html >
6 < html >
7 < head >
8 < title > Erro </ title >
9 </ head >
10 < body >
11 < h2 >
12 Servidor com problemas
13 </ h2 >
14 <p >
15 Houve um problema em nosso servidor . < br / >
16 Por favor tente novamente dentro de alguns instantes .
17 </ p >
18 </ body >
19 </ html >
As pginas de erro que sero mostradas pelos controladores teriam uma mensagem simples in-
formando que houve um erro na aplicao e que no possvel atender a requisio do usurio
naquele momento. Inclusive, seria conveniente padronizar a pgina de erro. Em outras palavras,
todos os controladores teriam que mostrar a mesma pgina.
182 www.k19.com.br
183 T RATAMENTO DE E RROS
Custom Errors
Utilizar o comando try-catch nos controladores para lidar com os erros de aplicao no uma
boa alternativa, pois o cdigo do controlador fica mais complexo. Alm disso, haveria replicao de
cdigo nos controladores, pois provavelmente a pgina de erro seria padronizada.
Para lidar com os erros de aplicao de uma maneira mais prtica e fcil de manter, podemos
configurar o ASP.NET MVC para utilizar pginas de erro padro. O primeiro passo alterar o arquivo
de configurao Web.config, acrescentando a tag <customErrors> dentro da tag <system.web>.
1 ...
2 < customErrors mode = " On " >
3
4 </ customErrors >
5 ...
On: A pgina de erro padro ser enviada para usurios locais e remotos.
Off: A pgina de erro detalhada ser enviada para usurios locais e remotos.
RemoteOnly: A pgina de erro detalhada ser enviada para os usurios locais e a padro para os
remotos.
Por conveno, o ASP.NET MVC mantm uma pgina de erro padro dentro da pasta Views\Shared
com o nome Error.cshtml. Vamos alterar este arquivo. O contedo da pgina de erro basicamente
HTML.
1 @{
2 Layout = null ;
3 }
4
5 <! DOCTYPE html >
6 < html >
7 < head >
8 < title > Erro </ title >
9 </ head >
10 < body >
11 < h2 >
12 Servidor com problemas
13 </ h2 >
14 <p >
15 Houve um problema no nosso servidor . < br / >
16 Por favor tente novamente dentro de alguns instantes .
17 </ p >
18 </ body >
19 </ html >
Http Errors
www.facebook.com/k19treinamentos 183
T RATAMENTO DE E RROS 184
Um dos erros mais conhecidos do HTTP o 404, que ocorre quando o navegador faz uma re-
quisio para uma url que no existe. Basicamente, esse erro gerado por falhas dos usurios ao
tentarem digitar diretamente uma url na barra de endereo dos navegadores ou por links ou botes
quebrados nas pginas da aplicao.
Quando o erro 404 ocorre, o ASP.NET MVC utiliza a pgina padro para erros de aplicao con-
figurada no Web.config atravs da tag <customErrors>. Porm, esse erro no deve ser considerado
um erro de aplicao, pois ele pode ser gerado por falhas do usurio. Ele tambm no deve ser con-
siderado um erro de usurio, pois ele pode ser gerado por falhas da aplicao. Consequentemente,
comum tratar o erro 404 de maneira particular, criando uma pgina de erro especfica para ele.
1 @{
2 Layout = null ;
3 }
4
5 <! DOCTYPE html >
6 < html >
7 < head >
8 < title > Arquivo no encontrado ! </ title >
9 </ head >
10 < body >
11 < h2 >
12 Esse arquivo no foi encontrado . Verifique se a url est correta .
13 </ h2 >
14 </ body >
15 </ html >
No arquivo de configurao, podemos especificar uma pgina web particular para o erro 404 ou
para os outros erros do HTTP.
1 ...
2 < customErrors mode = " On " >
3 < error statusCode = " 404 " redirect = " ~/ ErrorPage / NotFound " / >
4 </ customErrors >
5 ...
De acordo com o cdigo anterior, devemos definir um controlador chamado ErrorPage com
uma ao chamada NotFound. Essa ao ser acionada toda vez que o erro 404 do HTTP ocorrer.
184 www.k19.com.br
185 T RATAMENTO DE E RROS
Exerccios de Fixao
Observao: No Visual Web Developer, quando executamos a aplicao, ele a executa em modo
debug. Dessa forma, toda vez que um erro for gerado no processamento de uma requisio, a exe-
cuo da aplicao suspensa no ponto em que o erro ocorreu e detalhes sobre o problema so
apresentados. Para continuar a execuo da aplicao aps a ocorrncia de um erro, aperte a tecla
F5.
3 Trate o erro do exerccio anterior com o bloco try-catch e redirecione o usurio para uma tela
com a seguinte mensagem Sistema Temporariamente Indisponvel.
1 ...
2 public ActionResult TestaErro ()
3 {
4 try
5 {
6 string [] nomes = new string [] { " Jonas Hirata " , " Rafael Cosentino " };
7 string nome = nomes [2];
8 return View () ;
9 }
10 catch
11 {
12 return View ( " Error " ) ;
13 }
14 }
15 ...
www.facebook.com/k19treinamentos 185
T RATAMENTO DE E RROS 186
1 @{
2 Layout = null ;
3 }
4
5 <! DOCTYPE html >
6 < html >
7 < head >
8 < meta name = " viewport " content = " width = device - width " / >
9 < title > Error </ title >
10 </ head >
11 < body >
12 < h2 >
13 Sistema Temporariamente Indisponvel ...
14 </ h2 >
15 </ body >
16 </ html >
1 ...
2 public ActionResult TestaErro ()
3 {
4 string [] nomes = new string [] { " Jonas Hirata " , " Rafael Cosentino " };
5 string nome = nomes [2];
6 return View () ;
7 }
8 ...
6 Altere o arquivo Web.config para configurar o ASP.NET MVC para utilizar pginas de erro pa-
dro.
1 ...
2 < system . web >
3 < customErrors mode = " On " >
4 </ customErrors >
5 ...
6 < system . web >
7 ...
7 Vamos definir uma pgina para ser exibida quando o erro 404 ocorrer. Primeiramente, crie um
controlador chamado ErrorPage com uma ao chamada NotFound.
186 www.k19.com.br
187 T RATAMENTO DE E RROS
2 {
3 public class ErrorPageController : Controller
4 {
5 public ActionResult NotFound ()
6 {
7 return View () ;
8 }
9
10 }
11 }
1 @{
2 Layout = null ;
3 }
4
5 <! DOCTYPE html >
6 < html >
7 < head >
8 < title > Arquivo no encontrado ! </ title >
9 </ head >
10 < body >
11 < h2 >
12 Esse arquivo no foi encontrado . Verifique se a url est correta .
13 </ h2 >
14 </ body >
15 </ html >
9 Altere o arquivo Web.Config para definir que quando um erro 404 ocorrer, a pgina exibida deve
1 ...
2 < system . web >
3 < customErrors mode = " On " >
4 < error statusCode = " 404 " redirect = " ~/ ErrorPage / NotFound " / >
5 </ customErrors >
6 ...
7 < system . web >
8 ...
Tente acessar pginas da aplicao que no existam. Acesse, por exemplo, o endereo http:
//localhost:<PORTA_APP>/PaginaInexistente.
www.facebook.com/k19treinamentos 187
T RATAMENTO DE E RROS 188
188 www.k19.com.br
APNDICE
ASP.NET W EB API
A
Para permitir a implementao de webservices restful, o ASP.NET Web API foi adicionado quarta
verso do ASP.NET MVC. Webservices restful so baseados no estilo arquitetural REST. Discutiremos,
a seguir, os principais conceitos desse estilo arquitetural.
REST
Resources
No estilo arquitetural REST, toda informao disponvel chamada de resource. Por exemplo,
uma imagem um resource. Uma lista de produtos um resource. O cadastro de uma pessoa um
resource.
URIs
Todo resource possui um identificador nico globalmente. Os identificadores so utililzados para
acessar os respectivos resources. Particularmente, em uma rede HTTP, os resources so identificados
por URIs(Uniform Resource Identifier - http://tools.ietf.org/html/rfc3986). Por exemplo, a
URI www.k19.com.br/cursos identifica na internet a lista de cursos da K19.
Media Types
Um resource pode ser apresentado em diversos formatos. Na arquitetura REST, esses formatos
so chamados de media type. Considere o cadastro de uma pessoa disponvel em uma rede HTTP.
Eventualmente, esse cadastro pode ser apresentado em html, xml ou json.
1 { " nome " : " Rafael Cosentino " , " descricao " : " Lder de treinamentos da K19 " }
www.facebook.com/k19treinamentos 189
ASP.NET W EB API 190
Operaes
Em uma arquitetura REST, um conjunto pequeno e fixo de operaes deve ser definido previa-
mente. As operaes so utilizadas para manipular os recursos de alguma forma.
Por exemplo, em uma rede HTTP, os recursos so manipulados pelos mtodos do protocolo
HTTP. Podemos atribuir uma semntica diferente para cada um desses mtodos.
Resources
No ASP.NET Web API, os resources so definidos por controladores de uma aplicao ASP.NET
MVC que derivam de System.Web.Http.ApiController.
URIs
As URIs dos resources so definidas atravs de rotas do ASP.NET Web API criadas no arquivo
RouteConfig.cs. O Visual Web Developer adiciona a seguinte rota padro do ASP.NET Web API nos
projetos ASP.NET MVC 4:
1 routes . MapHttpRoute (
2 name : " DefaultApi " ,
3 routeTemplate : " api /{ controller }/{ id } " ,
4 defaults : new { id = RouteParameter . Optional }
5 );
De acordo com a rota padro do ASP.NET Web API, a URI do resource correspondente ao contro-
lador Cursos http://localhost:<PORTA_APP>/api/cursos.
Operaes
Podemos associar as operaes HTTP aos mtodos da classe CursosController. Essas associa-
es so estabelecidas automaticamente atravs dos nomes dos mtodos. Por exemplo, a operao
190 www.k19.com.br
191 ASP.NET W EB API
GET do HTTP associada automaticamente a um mtodo cujo nome possui o prefixo Get. Veja o
exemplo abaixo.
Na rota padro do ASP.NET Web API, um parmetro opcional chamado id foi definido. Quando
esse parmetro estiver presente em uma requisio do tipo GET, podemos recuperar o valor dele em
um mtodo cujo nome possua o prefixo Get e tenha um argumento chamado id. Observe o cdigo
abaixo.
Tambm podemos recuperar parmetros de URL. Para isso, basta definir argumentos com os
mesmos nomes desses parmetros nos mtodos associados s operaes do HTTP. Veja o exemplo
abaixo
www.facebook.com/k19treinamentos 191
ASP.NET W EB API 192
10 }
O mtodo PostCurso() ser associado a operao POST do HTTP. Os valores dos parmetros en-
viados dentro de uma requisio do tipo POST url http://localhost:<PORTA_APP>/api/cursos
sero armazenados automaticamente pelo ASP.NET Web API nas propriedades do argumento curso
do mtodo PostCurso() de acordo com o nome dessas propriedades e dos nomes dos parmetros
enviados. Por exemplo, o valor do parmetro Nome ser armazenado dentro da propriedade Nome
caso ambos existam.
Media Type
Por padro, o ASP NET Web API utiliza os headers Content-type e Accept para definir o media
type dos dados de entrada e sada. No exemplo anterior, se uma requisio do tipo GET for realizada
url //POSThttp://localhost:<PORTA_APP>/api/cursos com header Accept: application/json,
o resource correspondente ser apresentado em formato JSON.
Exerccios de Fixao
1 Crie um projeto do tipo ASP.NET MVC 4 Web Application chamado WebApi no Visual Studio
2012 Express for Web. Utilize o template Basic Project.
2 Vamos definir o nosso primeiro webservice utilizando web api. Para isso, adicione uma classe
para modelar cursos na pasta Models.
1 using System ;
192 www.k19.com.br
193 ASP.NET W EB API
4 Para testar o webservice que retorna a lista de cursos, basta acessar o seguinte endereo: http:
//localhost:<PORTA_APP>/api/cursos.
5 Teste o webservice que devolve o curso a partir de uma sigla. Basta acessar o seguinte endereo:
http://localhost:<PORTA_APP>/api/cursos?sigla=K31.
6 Teste o webservice que devolve um curso a partir de um id. Basta acessar o seguinte endereo:
http://localhost:<PORTA_APP>/api/cursos/1.
www.facebook.com/k19treinamentos 193
ASP.NET W EB API 194
7 Defina uma pgina com um formulrio para testar o webservice que adiciona curso. Para isso,
crie um controlador Curso conforme o cdigo abaixo:
8 Para testar o webservice que adiciona curso, devemos definir a pgina Cadastrar.cshtml.
194 www.k19.com.br
195 ASP.NET W EB API
9 Teste o webservice que adiciona curso atravs do formulrio criado no exerccio anterior. Acesse
o formulrio atravs do seguinte endereo: http://localhost:<PORTA_APP>/Curso/Cadastrar.
Para verificar se o curso foi adicionado, acesse http://localhost:<PORTA_APP>/api/cursos/.
www.facebook.com/k19treinamentos 195
ASP.NET W EB API 196
196 www.k19.com.br
APNDICE
P ROJETO
B
Nos captulos anteriores, vimos os recursos do ASP .NET MVC e do Entity Framework. Agora,
vamos solidificar os conhecimentos obtidos e, alm disso, mostraremos alguns padres e conceitos
relacionados ao desenvolvimento de aplicaes web.
Modelo
Por onde comear o desenvolvimento de uma aplicao? Essa uma questo recorrente. Um timo
ponto de partida desenvolver as entidades principais da aplicao. No nosso caso, vamos nos res-
tringir s entidades Selecao e Jogador. Devemos estabelecer um relacionamento entre essas entida-
des j que um jogador atua em uma seleo.
Exerccios de Fixao
1 Crie um projeto do tipo ASP .NET MVC 4 Web Application chamado K19-CopaDoMundo se-
guindo os passos vistos no exerccio do captulo 5.
www.facebook.com/k19treinamentos 197
P ROJETO 198
12 }
13 }
Persistncia - Mapeamento
Exerccios de Fixao
198 www.k19.com.br
199 B.3. P ERSISTNCIA - M APEAMENTO
Persistncia - Configurao
Precisamos definir a nossa string de conexo para que a nossa aplicao utilize a base de dados
k19copadomundo como padro.
Exerccios de Fixao
Persistncia - Repositrios
Vamos deixar os repositrios para acessar as entidades da nossa aplicao preparados. Os reposit-
rios precisam de DbContexts para realizar as operaes de persistncia. Ento, cada repositrio ter
um construtor para receber um DbContext como parmetro.
Exerccios de Fixao
1 using System ;
2 using System . Collections . Generic ;
3
4 namespace K19CopaDoMundo . Models
5 {
6 public class SelecaoRepository : IDisposable
7 {
8 private bool disposed = false ;
www.facebook.com/k19treinamentos 199
P ROJETO 200
9
10 private K19CopaDoMundoContext context ;
11
12 public SelecaoRepository ( K19CopaDoMundoContext context )
13 {
14 this . context = context ;
15 }
16
17 public void Adiciona ( Selecao selecao )
18 {
19 context . Selecoes . Add ( selecao ) ;
20 }
21
22 public List < Selecao > Selecoes
23 {
24 get
25 {
26 return context . Selecoes . ToList () ;
27 }
28 }
29 public void Salva ()
30 {
31 context . SaveChanges () ;
32 }
33
34 protected virtual void Dispose ( bool disposing )
35 {
36 if (! this . disposed )
37 {
38 if ( disposing )
39 {
40 context . Dispose () ;
41 }
42 }
43 this . disposed = true ;
44 }
45
46 public void Dispose ()
47 {
48 Dispose ( true ) ;
49 GC . SuppressFinalize ( this ) ;
50 }
51 }
52 }
1 using System ;
2 using System . Collections . Generic ;
3
4 namespace K19CopaDoMundo . Models
5 {
6 public class JogadorRepository : IDisposable
7 {
8 private bool disposed = false ;
9 private K19CopaDoMundoContext context ;
10
11 public JogadorRepository ( K19CopaDoMundoContext context )
12 {
13 this . context = context ;
14 }
15
16 public void Adiciona ( Jogador jogador )
17 {
18 context . Jogadores . Add ( jogador ) ;
200 www.k19.com.br
201 B.3. P ERSISTNCIA - M APEAMENTO
19 }
20
21 public List < Jogador > Jogadores
22 {
23 get { return context . Jogadores . ToList () ; }
24 }
25
26 public void Salva ()
27 {
28 context . SaveChanges () ;
29 }
30
31 protected virtual void Dispose ( bool disposing )
32 {
33 if (! this . disposed )
34 {
35 if ( disposing )
36 {
37 context . Dispose () ;
38 }
39 }
40 this . disposed = true ;
41 }
42
43 public void Dispose ()
44 {
45 Dispose ( true ) ;
46 GC . SuppressFinalize ( this ) ;
47 }
48 }
49 }
Unit of Work
O nico propsito de criar uma classe UnitOfWork ter certeza que quando temos mltiplos
repositrios eles compartilham o mesmo DbContext. Para isto, devemos apenas criar um mtodo
Salva e uma propriedade para cada repositrio.
Exerccios de Fixao
1 using System ;
2 using System . Collections . Generic ;
3
4 namespace K19CopaDoMundo . Models
5 {
6 public class UnitOfWork : IDisposable
7 {
8 private bool disposed = false ;
9 private K19CopaDoMundoContext context = new K19CopaDoMundoContext () ;
10 private SelecaoRepository selecaoRepository ;
11 private JogadorRepository jogadorRepository ;
12
13
14 public JogadorRepository JogadorRepository
15 {
16 get
17 {
www.facebook.com/k19treinamentos 201
P ROJETO 202
18 if ( jogadorRepository == null )
19 {
20 jogadorRepository = new JogadorRepository ( context ) ;
21 }
22 return jogadorRepository ;
23 }
24 }
25
26 public SelecaoRepository SelecaoRepository
27 {
28 get
29 {
30 if ( selecaoRepository == null )
31 {
32 selecaoRepository = new SelecaoRepository ( context ) ;
33 }
34 return selecaoRepository ;
35 }
36 }
37
38 public void Salva ()
39 {
40 context . SaveChanges () ;
41 }
42
43 protected virtual void Dispose ( bool disposing )
44 {
45 if (! this . disposed )
46 {
47 if ( disposing )
48 {
49 context . Dispose () ;
50 }
51 }
52 this . disposed = true ;
53 }
54
55 public void Dispose ()
56 {
57 Dispose ( true ) ;
58 GC . SuppressFinalize ( this ) ;
59 }
60 }
61 }
Apresentao - Template
Vamos definir um template para as telas da nossa aplicao. Aplicaremos algumas regras CSS para
melhorar a parte visual das telas.
Exerccios de Fixao
1 . logo
2 {
3 vertical - align : middle ;
4 }
5
202 www.k19.com.br
203 B.3. P ERSISTNCIA - M APEAMENTO
6 . botao
7 {
8 background - color : #064 D83 ;
9 margin : 0 0 0 20 px ;
10 color : white ;
11 text - decoration : none ;
12 font - size : 20 px ;
13 line - height : 20 px ;
14 padding : 5 px ;
15 vertical - align : middle ;
16 }
17
18 . botao : hover
19 {
20 background - color : # cccccc ;
21 color : #666666;
22 }
23
24 . formulario fieldset
25 {
26 float : left ;
27 margin : 0 0 20 px 0;
28 border : 1 px solid #333333;
29 }
30
31 . formulario fieldset legend
32 {
33 color : #064 D83 ;
34 font - weight : bold ;
35 }
36
37 . botao - formulario
38 {
39 background - color : #064 D83 ;
40 color : # ffffff ;
41 padding : 5 px ;
42 vertical - align : middle ;
43 border : none ;
44 }
45
46 . titulo
47 {
48 color : #064 D83 ;
49 clear : both ;
50 }
51
52 . tabela
53 {
54 border : 1 px solid #064 D83 ;
55 border - collapse : collapse ;
56 }
57
58 . tabela tr th
59 {
60 background - color : #064 D83 ;
61 color : # ffffff ;
62 }
63
64 . tabela tr th , . tabela tr td
65 {
66 border : 1 px solid #064 D83 ;
67 padding : 2 px 5 px ;
68 }
69
70
71 /* Styles for validation helpers
72 -- ------ ------- ------ ------ ------ ------ ------ ------ ------ -- */
73 . field - validation - error
74 {
75 color : # ff0000 ;
www.facebook.com/k19treinamentos 203
P ROJETO 204
76 }
77
78 . field - validation - valid
79 {
80 display : none ;
81 }
82
83 . input - validation - error
84 {
85 border : 1 px solid # ff0000 ;
86 background - color : # ffeeee ;
87 }
88
89 . validation - summary - errors
90 {
91 font - weight : bold ;
92 color : # ff0000 ;
93 }
94
95 . validation - summary - valid
96 {
97 display : none ;
98 }
10 Copie o arquivo k19-logo.png da pasta K19-Arquivos da sua rea de Trabalho para a pasta
Images.
204 www.k19.com.br
205 B.12. C ADASTRANDO E L ISTANDO S ELEES
Exerccios de Fixao
1 using System ;
2 using System . Collections . Generic ;
3 using System . Data ;
4 using System . Data . Entity ;
5 using System . Linq ;
6 using System . Web ;
7 using System . Web . Mvc ;
8 using K19CopaDoMundo . Models ;
9
10 namespace K19CopaDoMundo . Controllers
11 {
12 public class SelecaoController : Controller
13 {
14 private UnitOfWork unitOfWork = new UnitOfWork () ;
15
16 public ActionResult Create ()
17 {
18 return View () ;
19 }
20
21 protected override void Dispose ( bool disposing )
22 {
23 unitOfWork . Dispose () ;
24 base . Dispose ( disposing ) ;
25 }
26 }
27 }
www.facebook.com/k19treinamentos 205
P ROJETO 206
13 Vamos criar uma tela Create.cshtml para cadastrar as selees. Adicione o arquivo a pasta
Views/Selecoes com o seguinte contedo.
14 O prximo passo definir a action que ir salvar a seleo no nosso banco de dados. Devemos
tambm acrescentar as validaes a nossa entidade.
1 [ HttpPost ]
2 public ActionResult Create ( Selecao selecao )
3 {
4 if ( ModelState . IsValid )
5 {
6 unitOfWork . SelecaoRepository . Adiciona ( selecao ) ;
7 unitOfWork . Salva () ;
8 return RedirectToAction ( " Index " ) ;
206 www.k19.com.br
207 B.12. C ADASTRANDO E L ISTANDO S ELEES
9 }
10 return View ( selecao ) ;
11 }
www.facebook.com/k19treinamentos 207
P ROJETO 208
32 }
33
34 </ table >
16 Vamos definir a tela de listagem de Selees como a pgina principal do nosso site. Altere a rota
padro no arquivo RouteConfig.cs.
1 routes . MapRoute (
2 name : " Default " ,
3 url : " { controller }/{ action }/{ id } " ,
4 defaults : new { controller = " Selecao " , action = " Index " ,
5 id = UrlParameter . Optional } ) ;
Removendo Selees
Vamos acrescentar a funcionalidade de remover selees.
Exerccios de Fixao
17
208 www.k19.com.br
209 B.12. C ADASTRANDO E L ISTANDO S ELEES
31 < td >
32 @Html . ActionLink ( " Remover " ," Delete " , new { id = item . Id })
33 </ td >
34 </ tr >
35 }
36
37 </ table >
18 Defina um mtodo Busca na classe SelecaoRepository que retorna uma entidade seleo a partir
de um parmetro id.
19 Defina uma action Delete que ir mostrar a tela de confirmao de remoo da entidade.
www.facebook.com/k19treinamentos 209
P ROJETO 210
21 Defina um mtodo na classe SelecaoRepository que remove uma entidade seleo a partir de
um parmetro id.
1 [ HttpPost ]
2 [ ActionName ( " Delete " ) ]
3 public ActionResult DeleteConfirmed ( int id )
4 {
5 unitOfWork . SelecaoRepository . Remove ( id ) ;
6 unitOfWork . Salva () ;
7 return RedirectToAction ( " Index " ) ;
8 }
Exerccios de Fixao
1 using System ;
2 using System . Collections . Generic ;
3 using System . Data ;
4 using System . Data . Entity ;
5 using System . Linq ;
6 using System . Web ;
7 using System . Web . Mvc ;
8 using K19CopaDoMundo . Models ;
9
10 namespace K19CopaDoMundo . Controllers
11 {
12 public class JogadorController : Controller
13 {
14 private UnitOfWork unitOfWork = new UnitOfWork () ;
210 www.k19.com.br
211 B.12. C ADASTRANDO E L ISTANDO S ELEES
15
16 public ActionResult Create ()
17 {
18 ViewBag . SelecaoId = new SelectList ( unitOfWork . SelecaoRepository . Selecoes , " Id " , -
" Pais " ) ;
19 return View () ;
20 }
21
22 protected override void Dispose ( bool disposing )
23 {
24 unitOfWork . Dispose () ;
25 base . Dispose ( disposing ) ;
26 }
27 }
28 }
24 Vamos criar uma tela Create.cshtml para cadastrar os jogadores. Adicione o arquivo a pasta
Views/Jogador com o seguinte contedo.
www.facebook.com/k19treinamentos 211
P ROJETO 212
25 O prximo passo definir a action que ir salvar o jogador no nosso banco de dados. Devemos
tambm acrescentar as validaes a nossa entidade.
1 [ HttpPost ]
2 public ActionResult Create ( Jogador jogador )
3 {
4 if ( ModelState . IsValid )
5 {
6 unitOfWork . JogadorRepository . Adiciona ( jogador ) ;
7 unitOfWork . Salva () ;
8 return RedirectToAction ( " Index " ) ;
9 }
10 ViewBag . SelecaoId = new SelectList ( unitOfWork . SelecaoRepository . Selecoes , -
" Id " , " Pais " ) ;
11 return View () ;
12 }
212 www.k19.com.br
213 B.12. C ADASTRANDO E L ISTANDO S ELEES
24 }
25 }
www.facebook.com/k19treinamentos 213
P ROJETO 214
Removendo Jogadores
Vamos acrescentar a funcionalidade de remover jogadores.
Exerccios de Fixao
214 www.k19.com.br
215 B.12. C ADASTRANDO E L ISTANDO S ELEES
51 }
52 </ table >
28 Defina um mtodo Busca na classe JogadorRepository que retorna uma entidade jogador a
partir de um parmetro id.
29 Defina uma action Delete que ir mostrar a tela de confirmao de remoo da entidade.
www.facebook.com/k19treinamentos 215
P ROJETO 216
31 Defina um mtodo na classe JogadorRepository que remove uma entidade jogador a partir de
um parmetro id.
1 [ HttpPost ]
2 [ ActionName ( " Delete " ) ]
3 public ActionResult DeleteConfirmed ( int id )
4 {
5 unitOfWork . JogadorRepository . Remove ( id ) ;
6 unitOfWork . Salva () ;
7 return RedirectToAction ( " Index " ) ;
8 }
Membership e Autorizao
Na maioria dos casos, as aplicaes devem controlar o acesso dos usurios. Vamos implementar um
mecanismo de autenticao na nossa aplicao utilizando filtro e Membership. As requisies feitas
pelos usurios passaro pelo filtro. A funo do filtro verificar se o usurio est logado ou no. Se
estiver logado o filtro autoriza o acesso. Caso contrrio, o filtro redirecionar o usurio para a tela de
login.
Exerccios de Fixao
216 www.k19.com.br
217 B.12. C ADASTRANDO E L ISTANDO S ELEES
1 using System ;
2 using System . Collections . Generic ;
3 using System . Linq ;
4 using System . Web . Mvc ;
5 using System . ComponentModel . DataAnnotations ;
6
7 namespace K19CopaDoMundo . Models
8 {
9
10 public class ChangePasswordModel
11 {
12 [ Required ]
13 [ DataType ( DataType . Password ) ]
14 [ Display ( Name = " Senha " ) ]
15 public string OldPassword { get ; set ; }
16
17 [ Required ]
18 [ StringLength (100 , ErrorMessage = " O {0} deve ter no mnimo {2} caracteres . " , -
MinimumLength = 6) ]
19 [ DataType ( DataType . Password ) ]
20 [ Display ( Name = " Nova senha " ) ]
21 public string NewPassword { get ; set ; }
22
23 [ DataType ( DataType . Password ) ]
24 [ Display ( Name = " Confirmao de senha " ) ]
25 [ Compare ( " NewPassword " , ErrorMessage = " A senha e a confirmao no conferem . -
")]
26 public string ConfirmPassword { get ; set ; }
27 }
28
29 public class LoginModel
30 {
31 [ Required ]
32 [ Display ( Name = " Usurio " ) ]
33 public string UserName { get ; set ; }
34
35 [ Required ]
36 [ DataType ( DataType . Password ) ]
37 [ Display ( Name = " Senha " ) ]
38 public string Password { get ; set ; }
39
40 [ Display ( Name = " Lembrar ? " ) ]
41 public bool RememberMe { get ; set ; }
42 }
43
44 public class RegisterModel
45 {
46 [ Required ]
47 [ Display ( Name = " Usurio " ) ]
48 public string UserName { get ; set ; }
49
50 [ Required ]
51 [ DataType ( DataType . EmailAddress ) ]
52 [ Display ( Name = " Email " ) ]
53 public string Email { get ; set ; }
54
55 [ Required ]
56 [ StringLength (100 , ErrorMessage = " O {0} deve ter no mnimo {2} caracteres . " , -
MinimumLength = 6) ]
57 [ DataType ( DataType . Password ) ]
58 [ Display ( Name = " Senha " ) ]
59 public string Password { get ; set ; }
60
61 [ DataType ( DataType . Password ) ]
62 [ Display ( Name = " Confirmao de senha " ) ]
63 [ Compare ( " Password " , ErrorMessage = " A senha e a confirmao no conferem . " ) ]
64 public string ConfirmPassword { get ; set ; }
65 }
www.facebook.com/k19treinamentos 217
P ROJETO 218
66
67 }
1 using System ;
2 using System . Collections . Generic ;
3 using System . Linq ;
4 using System . Web ;
5 using System . Web . Mvc ;
6 using System . Web . Security ;
7 using K19CopaDoMundo . Models ;
8
9 namespace K19CopaDoMundo . Controllers
10 {
11 public class UsuarioController : Controller
12 {
13 //
14 // GET : / Usuario / Login
15
16 public ActionResult Login ()
17 {
18 return View () ;
19 }
20
21 //
22 // POST : / Usuario / Login
23
24 [ HttpPost ]
25 public ActionResult Login ( LoginModel model , string returnUrl )
26 {
27 if ( ModelState . IsValid )
28 {
29 if ( Membership . ValidateUser ( model . UserName , model . Password ) )
30 {
31 FormsAuthentication . SetAuthCookie ( model . UserName , model . RememberMe ) ;
32 if ( Url . IsLocalUrl ( returnUrl ) && returnUrl . Length > 1 && returnUrl . -
StartsWith ( " / " )
33 && ! returnUrl . StartsWith ( " // " ) && ! returnUrl . StartsWith ( " /\\ " ) )
34 {
35 return Redirect ( returnUrl ) ;
36 }
37 else
38 {
39 return RedirectToAction ( " Index " , " Selecao " ) ;
40 }
41 }
42 else
43 {
44 ModelState . AddModelError ( " " , " O usurio e / ou a senha est incorreto . " ) ;
45 }
46 }
47
48
49 return View ( model ) ;
50 }
51
52 //
53 // GET : / Usuario / LogOff
54
55 public ActionResult LogOff ()
56 {
57 FormsAuthentication . SignOut () ;
58
59 return Redirect ( " / " ) ;
218 www.k19.com.br
219 B.12. C ADASTRANDO E L ISTANDO S ELEES
60 }
61
62 //
63 // GET : / Usuario / Register
64
65 public ActionResult Register ()
66 {
67 return View () ;
68 }
69
70 //
71 // POST : / Usuario / Register
72
73 [ HttpPost ]
74 public ActionResult Register ( RegisterModel model )
75 {
76 if ( ModelState . IsValid )
77 {
78 // Attempt to register the user
79 MembershipCreateStatus createStatus ;
80 Membership . CreateUser ( model . UserName , model . Password , model . Email , null , null -
, true , null , out createStatus ) ;
81
82 if ( createStatus == MembershipCreateStatus . Success )
83 {
84 FormsAuthentication . SetAuthCookie ( model . UserName , false /* -
createPersistentCookie */ ) ;
85 return Redirect ( " / " ) ;
86 }
87 else
88 {
89 ModelState . AddModelError ( " " , ErrorCodeToString ( createStatus ) ) ;
90 }
91 }
92
93
94 return View ( model ) ;
95 }
96
97 //
98 // GET : / Usuario / ChangePassword
99
100 [ Authorize ]
101 public ActionResult ChangePassword ()
102 {
103 return View () ;
104 }
105
106 //
107 // POST : / Usuario / ChangePassword
108
109 [ Authorize ]
110 [ HttpPost ]
111 public ActionResult ChangePassword ( ChangePasswordModel model )
112 {
113 if ( ModelState . IsValid )
114 {
115
116
117 bool changePasswordSucceeded ;
118 try
119 {
120 MembershipUser currentUser = Membership . GetUser ( User . Identity . Name , true /* -
userIsOnline */ ) ;
121 changePasswordSucceeded = currentUser . ChangePassword ( model . OldPassword , -
model . NewPassword ) ;
122 }
123 catch ( Exception )
124 {
125 changePasswordSucceeded = false ;
www.facebook.com/k19treinamentos 219
P ROJETO 220
126 }
127
128 if ( changePasswordSucceeded )
129 {
130 return RedirectToAction ( " ChangePasswordSuccess " ) ;
131 }
132 else
133 {
134 ModelState . AddModelError ( " " , " A senha atual ou a confirmao est incorreta -
.");
135 }
136 }
137
138
139 return View ( model ) ;
140 }
141
142 //
143 // GET : / Usuario / ChangePasswordSuccess
144
145 public ActionResult ChangePasswordSuccess ()
146 {
147 return View () ;
148 }
149
150 private IEnumerable < string > GetErrorsFromModelState ()
151 {
152 return ModelState . SelectMany ( x = > x . Value . Errors . Select ( error = > error . -
ErrorMessage ) ) ;
153 }
154
155 # region Status Codes
156 private static string ErrorCodeToString ( MembershipCreateStatus createStatus )
157 {
158 // See http :// go . microsoft . com / fwlink /? LinkID =177550 for
159 // a full list of status codes .
160 switch ( createStatus )
161 {
162 case MembershipCreateStatus . DuplicateUserName :
163 return " Este nome de usurio j existe . Defina outro usurio . " ;
164
165 case MembershipCreateStatus . DuplicateEmail :
166 return " Este email j foi cadastrado . Defina outro email . " ;
167
168 case MembershipCreateStatus . InvalidPassword :
169 return " Senha incorreta . " ;
170
171 case MembershipCreateStatus . InvalidEmail :
172 return " Email invlido . " ;
173
174 case MembershipCreateStatus . InvalidAnswer :
175 return " Resposta invlida para recuperar a senha . " ;
176
177 case MembershipCreateStatus . InvalidQuestion :
178 return " Questo invlida para recuperar a senha . " ;
179
180 case MembershipCreateStatus . InvalidUserName :
181 return " Usurio invlido . " ;
182
183 case MembershipCreateStatus . ProviderError :
184 return " Ocorreu um erro durante a autenticao . Se o problema persistir , -
contate o administrador . " ;
185
186 case MembershipCreateStatus . UserRejected :
187 return " O cadastro do usurio foi cancelado . Se o problema persistir , -
contate o administrador . " ;
188
189 default :
190 return " Um erro inesperado ocorreu . Se o problema persistir , contate o -
administrador . " ;
220 www.k19.com.br
221 B.12. C ADASTRANDO E L ISTANDO S ELEES
191 }
192 }
193 # endregion
194 }
195
196 }
35 Crie uma pasta Usuario na pasta Views e acrescente os quatro arquivos abaixo.
1 @{
2 ViewBag . Title = " Senha alterada " ;
3 }
4
5 < hgroup class = " title " >
6 < h1 > @ViewBag . Title . </ h1 >
7 < h2 > Sua senha foi alterada com sucesso . </ h2 >
8 </ hgroup >
www.facebook.com/k19treinamentos 221
P ROJETO 222
222 www.k19.com.br
223 B.12. C ADASTRANDO E L ISTANDO S ELEES
25 </ li >
26 < li >
27 @Html . LabelFor ( m = > m . Email )
28 @Html . TextBoxFor ( m = > m . Email )
29 </ li >
30 < li >
31 @Html . LabelFor ( m = > m . Password )
32 @Html . PasswordFor ( m = > m . Password )
33 </ li >
34 < li >
35 @Html . LabelFor ( m = > m . ConfirmPassword )
36 @Html . PasswordFor ( m = > m . ConfirmPassword )
37 </ li >
38 </ ol >
39 < input type = " submit " value = " Cadastrar " / >
40 </ fieldset >
41 }
42
43 @section Scripts {
44 @Scripts . Render ( " ~/ bundles / jqueryval " )
45 }
www.facebook.com/k19treinamentos 223
P ROJETO 224
Antes de definir o filtro Authorize nos controladores de nosso site, vamos criar um usurio com
acesso. A maneira mais fcil de criar o usurio atravs do ASP .NET Configuration.
Exerccios de Fixao
38 Execute o ASP .NET Configuration que fica na aba Solution Explorer do Visual Studio.
39 Isto executar um ambiente de configurao. Abra a aba Security e clique no link Enable
roles.
224 www.k19.com.br
225 B.12. C ADASTRANDO E L ISTANDO S ELEES
Autorizao Role-based
Podemos restringir o acesso as pginas com o filtro Authorize e podemos especificar o role que
o usurio precisa ter para ter acesso a pgina.
Exerccios de Fixao
44 Altere o filtro de autenticao no Web.config para redirecionar o usurio para a action Login do
controlador Usuario.
45 Acrescente a seguinte string de conexo no arquivo Web.config para definir o local que as infor-
maes dos usurios sero armazenadas (No nosso caso, teremos duas strings de conexo).
www.facebook.com/k19treinamentos 225
P ROJETO 226
Controle de Erro
Podemos configurar uma pgina de erro padro para ser utilizada toda vez que um erro ocorrer.
Exerccios de Fixao
47 Acrescente ao arquivo Web.config a tag customErrors para especificar a pgina de erro padro.
A tag customErrors fica dentro da tag system.web.
48 Defina o controlador Erro e as pginas de erros padro. As pginas de erro padro sero criadas
dentro da pasta Views numa subpasta Erro.
1 using System ;
2 using System . Collections . Generic ;
3 using System . Linq ;
4 using System . Web ;
5 using System . Web . Mvc ;
6
7 namespace K19CopaDoMundo . Controllers
8 {
9 public class ErroController : Controller
10 {
11 //
12 // GET : / Erro / Desconhecido
13
14 public ActionResult Desconhecido ()
15 {
16 return View () ;
17 }
18
19 //
20 // GET : / Erro / PaginaNaoEncontrada
21 public ActionResult PaginaNaoEncontrada ()
22 {
23 return View () ;
24 }
25
26 }
27 }
226 www.k19.com.br
227 B.12. C ADASTRANDO E L ISTANDO S ELEES
1 @{
2 Layout = null ;
3 }
4
5 <! DOCTYPE html >
6
7 < html >
8 < head >
9 < meta name = " viewport " content = " width = device - width " / >
10 < title > Problema no servidor </ title >
11 </ head >
12 < body >
13 < h2 > Desculpe , tivemos problema em nosso servidor . Volte dentro de alguns -
instantes . </ h2 >
14 </ body >
15 </ html >
1 @{
2 Layout = null ;
3 }
4
5 <! DOCTYPE html >
6
7 < html >
8 < head >
9 < meta name = " viewport " content = " width = device - width " / >
10 < title > Pgina no encontrada </ title >
11 </ head >
12 < body >
13 < h2 > Pgina no encontrada </ h2 >
14 </ body >
15 </ html >
Enviando email
Quando um erro ocorre na nossa aplicao, podemos permitir que o usurio envie uma email para
os administradores do sistema. Para enviar as mensagens, podemos utilizar o Web
Exerccios de Fixao
49 Altere a tela de erro adicionando um formulrio para o usurio escrever uma mensagem para os
administradores da aplicao.
1 @{
2 Layout = null ;
3 }
4
5 <! DOCTYPE html >
6
7 < html >
8 < head >
9 < meta name = " viewport " content = " width = device - width " / >
10 < title > Problema no servidor </ title >
11 </ head >
12 < body >
www.facebook.com/k19treinamentos 227
P ROJETO 228
13 < h2 > Desculpe , tivemos problema em nosso servidor . Volte dentro de alguns -
instantes . </ h2 >
14 <p > Envie uma mensagem para os administradores do sistema . </ p >
15 @using ( Html . BeginForm ( " Envia " , " Email " ) )
16 {
17 < div class = " editor - label " >
18 @Html . Label ( " Mensagem " )
19 </ div >
20 < div class = " editor - field " >
21 @Html . TextArea ( " Mensagem " )
22 </ div >
23 < input type = " submit " value = " Enviar " / >
24 }
25 </ body >
26 </ html >
50 Crie um controlador que envie as mensagens por email utilizando o helper WebMail. Observa-
o, utilize usurios, senhas e emails vlidos do gmail para este exerccio.
1 using System ;
2 using System . Collections . Generic ;
3 using System . Linq ;
4 using System . Web ;
5 using System . Web . Mvc ;
6 using System . Web . Helpers ;
7
8 namespace K19CopaDoMundo . Controllers
9 {
10 public class EmailController : Controller
11 {
12
13 public EmailController ()
14 {
15 WebMail . SmtpServer = " smtp . gmail . com " ;
16 WebMail . EnableSsl = true ;
17 WebMail . SmtpPort = 587;
18 WebMail . From = " USUARIO@gmail . com " ;
19 WebMail . UserName = " USUARIO@gmail . com " ;
20 WebMail . Password = " SENHA " ;
21 }
22 //
23 // POST : / Email / Envia
24 [ HttpPost ]
25 public ActionResult Envia ( string mensagem )
26 {
27
28 WebMail . Send ( " EMAIL " , " Copa do Mundo - Erro " , mensagem ) ;
29 return View () ;
30 }
31
32 }
33 }
51 Crie uma pgina Envia.cshtml para mostrar ao usurio que a mensagem foi enviada com su-
cesso e acrescente um link para a pgina inicial do site.
1 @{
2 Layout = null ;
3 }
228 www.k19.com.br
229 B.12. C ADASTRANDO E L ISTANDO S ELEES
4
5 <! DOCTYPE html >
6
7 < html >
8 < head >
9 < title > Envia </ title >
10 </ head >
11 < body >
12 < div >
13 Mensagem enviada com sucesso .
14 </ div >
15 < div >
16 @Html . ActionLink ( " Voltar para pgina inicial " , " Index " , " Selecoes " )
17 </ div >
18 </ body >
19 </ html >
www.facebook.com/k19treinamentos 229
P ROJETO 230
230 www.k19.com.br
APNDICE
R ESPOSTAS
C
Exerccio Complementar 2.1
www.facebook.com/k19treinamentos 231
R ESPOSTAS 232
11
12 System . Console . Write ( " Digite o Ttulo do Livro : " ) ;
13 string titulo = System . Console . ReadLine () ;
14
15 System . Console . Write ( " Digite o Preo do Livro : " ) ;
16 string preco = System . Console . ReadLine () ;
17
18 System . Console . Write ( " Digite o Id da Editora do Livro : " ) ;
19 string editoraId = System . Console . ReadLine () ;
20
21 string textoInsereEditora =
22 @ " INSERT INTO Livros ( Titulo , Preco , EditoraId ) VALUES (? ,? ,?) " ;
23
24 using ( OdbcConnection conexao = new OdbcConnection ( stringDeConexao ) )
25 {
26 OdbcCommand command = new OdbcCommand ( textoInsereEditora , conexao ) ;
27
28 command . Parameters . AddWithValue ( " @Titulo " , titulo ) ;
29 command . Parameters . AddWithValue ( " @Preco " , preco ) ;
30 command . Parameters . AddWithValue ( " @EditoraId " , editoraId ) ;
31
32 conexao . Open () ;
33 command . ExecuteNonQuery () ;
34 }
35 }
36 }
37 }
232 www.k19.com.br
233 R ESPOSTAS
www.facebook.com/k19treinamentos 233
R ESPOSTAS 234
1 @{
2 ViewBag . Title = " Index " ;
3 }
4
5 @for ( int i = 0; i < 10; i ++)
6 {
7 < h2 > Ol @i </ h2 >
8 }
234 www.k19.com.br