Você está na página 1de 206

TRE INAME NTO S

Desenvolvimento Web com ASP.NET MVC 4

Desenvolvimento Web com ASP .NET MVC 4

25 de junho de 2012

Sumrio Sobre a K19 Seguro Treinamento Termo de Uso Cursos 1 Banco de Dados 1.1 Sistemas Gerenciadores de Banco de Dados . 1.2 SQL Server . . . . . . . . . . . . . . . . . . . . 1.3 Bases de Dados (Databases) . . . . . . . . . . 1.4 Tabelas . . . . . . . . . . . . . . . . . . . . . . 1.5 CRUD . . . . . . . . . . . . . . . . . . . . . . . 1.6 Chaves Primria e Estrangeira . . . . . . . . . 1.7 Exerccios de Fixao . . . . . . . . . . . . . . ADO.NET 2.1 Driver . . . . . . . . . . . . . 2.2 ODBC . . . . . . . . . . . . . 2.3 ODBC Manager . . . . . . . 2.4 Criando uma conexo . . . . 2.5 Inserindo registros . . . . . . 2.6 Exerccios de Fixao . . . . 2.7 Exerccios Complementares 2.8 SQL Injection . . . . . . . . . 2.9 Exerccios de Fixao . . . . 2.10 Exerccios Complementares 2.11 Listando registros . . . . . . 2.12 Exerccios de Fixao . . . . 2.13 Exerccios Complementares 2.14 Connection Factory . . . . .
www.k19.com.br

i 1 2 3 4 1 1 2 2 4 6 9 10 23 24 25 25 26 26 27 28 28 29 30 30 31 32 32
i

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

S UMRIO

ii

2.15 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.16 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.17 Desaos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Entity Framework 3.1 Mltiplas sintaxes da linguagem SQL . . . . 3.2 Orientao a Objetos VS Modelo Relacional 3.3 Ferramentas ORM . . . . . . . . . . . . . . . 3.4 Congurao . . . . . . . . . . . . . . . . . . 3.5 Mapeamento . . . . . . . . . . . . . . . . . . 3.6 Manipulando entidades . . . . . . . . . . . 3.7 Exerccios de Fixao . . . . . . . . . . . . . 3.8 Repositrios . . . . . . . . . . . . . . . . . . 3.9 Exerccios de Fixao . . . . . . . . . . . . . Viso Geral do ASP .NET MVC 4.1 Necessidades de uma aplicao web 4.2 ASP .NET MVC . . . . . . . . . . . . . 4.3 MVC e Front Controller . . . . . . . . 4.4 Visual Web Developer . . . . . . . . . 4.5 Exemplo de uma Aplicao Web . . . 4.6 Exerccios de Fixao . . . . . . . . . 4.7 Integrao com Entity Framework . 4.8 Scaffold . . . . . . . . . . . . . . . . . 4.9 Exerccios de Fixao . . . . . . . . . Camada de Apresentao 5.1 Razor e ASPX . . . . . . . . . . . 5.2 Exerccios de Fixao . . . . . . 5.3 Exerccios Complementares . . 5.4 ViewBag e Strogly Typed Views 5.5 Exerccios de Fixao . . . . . . 5.6 HTML Helpers . . . . . . . . . . 5.7 Exerccios de Fixao . . . . . . 5.8 Layouts . . . . . . . . . . . . . . 5.9 Exerccios de Fixao . . . . . . 5.10 Partial views . . . . . . . . . . . 5.11 Exerccios de Fixao . . . . . . Camada de Controle 6.1 Actions . . . . . . . . 6.2 ActionResult . . . . . 6.3 Parmetros . . . . . . 6.4 Exerccios de Fixao 6.5 TempData . . . . . . . 6.6 Exerccios de Fixao

33 34 35 37 37 37 38 39 40 44 47 50 51 53 53 54 54 55 56 57 62 62 63 67 67 70 70 71 73 74 85 87 90 94 96 99 99 100 101 102 104 104

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

Rotas 107 7.1 Adicionando uma rota . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 7.2 Adicionando Parmetros nas Rotas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
www.k19.com.br

ii

iii

S UMRIO

7.3 8

Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 111 111 112 113 114 115 116 119 119 119 120 121

Validao 8.1 Controller . . . . . . . . . . . 8.2 View . . . . . . . . . . . . . . 8.3 Exerccios de Fixao . . . . 8.4 Anotaes . . . . . . . . . . . 8.5 Validao no lado do Cliente 8.6 Exerccios de Fixao . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

Sesso 9.1 Identicando os navegadores 9.2 Sesses no ASP .NET MVC . . . 9.3 Session Mode . . . . . . . . . . 9.4 Exerccios de Fixao . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

10 Autenticao 125 10.1 Filtro de Autenticao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 10.2 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 11 Tratamento de Erros 11.1 Try-Catch . . . . . . . 11.2 Custom Errors . . . . 11.3 Http Errors . . . . . . 11.4 Exerccios de Fixao A ASP.NET Web API A.1 REST . . . . . . . . . . A.2 Resources . . . . . . . A.3 URIs . . . . . . . . . . A.4 Operaes . . . . . . A.5 Media Type . . . . . . A.6 Exerccios de Fixao 131 132 133 133 134 139 139 140 140 141 142 142

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

B Migrations 147 B.1 Passo a Passo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 B.2 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 C Projeto C.1 Modelo . . . . . . . . . . . . . . . C.2 Exerccios de Fixao . . . . . . . C.3 Persistncia - Mapeamento . . . C.4 Exerccios de Fixao . . . . . . . C.5 Persistncia - Congurao . . . C.6 Exerccios de Fixao . . . . . . . C.7 Persistncia - Repositrios . . . . C.8 Exerccios de Fixao . . . . . . . C.9 Exerccios de Fixao . . . . . . . C.10 Apresentao - Template . . . . . C.11 Exerccios de Fixao . . . . . . . C.12 Cadastrando e Listando Selees
www.k19.com.br

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

161 161 161 162 162 163 163 163 163 165 166 166 169
iii

S UMRIO

iv

C.13 C.14 C.15 C.16 C.17 C.18 C.19 C.20 C.21 C.22 C.23 C.24 C.25 C.26 C.27

Exerccios de Fixao . . . . . . . . . . . . . . . . Removendo Selees . . . . . . . . . . . . . . . . Exerccios de Fixao . . . . . . . . . . . . . . . . Cadastrando, Listando e Removendo Jogadores Exerccios de Fixao . . . . . . . . . . . . . . . . Removendo Jogadores . . . . . . . . . . . . . . . Exerccios de Fixao . . . . . . . . . . . . . . . . Membership e Autorizao . . . . . . . . . . . . . Exerccios de Fixao . . . . . . . . . . . . . . . . Exerccios de Fixao . . . . . . . . . . . . . . . . Exerccios de Fixao . . . . . . . . . . . . . . . . Controle de Erro . . . . . . . . . . . . . . . . . . . Exerccios de Fixao . . . . . . . . . . . . . . . . Enviando email . . . . . . . . . . . . . . . . . . . Exerccios de Fixao . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

169 172 172 174 174 177 177 180 180 188 188 189 189 190 190 193

D Respostas

iv

www.k19.com.br

S UMRIO

Sobre a K19
A K19 uma empresa especializada na capacitao de desenvolvedores de software. Sua equipe composta por prossionais formados em Cincia da Computao pela Universidade de So Paulo (USP) e que possuem vasta experincia em treinamento de prossionais para rea de TI. O principal objetivo da K19 oferecer treinamentos de mxima qualidade e relacionados s principais tecnologias utilizadas pelas empresas. Atravs desses treinamentos, seus alunos se tornam capacitados para atuar no mercado de trabalho. Visando a mxima qualidade, a K19 mantm as suas apostilas em constante renovao e melhoria, oferece instalaes fsicas apropriadas para o ensino e seus instrutores esto sempre atualizados didtica e tecnicamente.

www.k19.com.br

S UMRIO

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 possui 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 Treinamento 10% do valor total do curso.

www.k19.com.br

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.k19.com.br

S UMRIO

TR

S TO EN AM EIN TREINAMENTOS TR EIN AM EN TO S

Conhea os nossos cursos


K01- Lgica de Programao

K11 - Orientao a Objetos em Java

K12 - Desenvolvimento Web com JSF2 e JPA2

K21 - Persistncia com JPA2 e Hibernate

K22 - Desenvolvimento Web Avanado com JFS2, EJB3.1 e CDI

K23 - Integrao de Sistemas com Webservices, JMS e EJB

K31 - C# e Orientao a Objetos

K32 - Desenvolvimento Web com ASP.NET MVC

www.k19.com.br/cursos

www.k19.com.br

CAPTULO

B ANCO DE D ADOS

Em geral, as aplicaes necessitam armazenar dados de forma persistente para consult-los posteriormente. 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 fatores importantes nos levam a descartar tal opo. A seguir, apresentamos as principais diculdades a serem consideradas na persistncia de dados.

Segurana: O acesso s informaes potencialmente condenciais deve ser controlado de forma que apenas usurios e sistemas autorizados possam manipul-las. Integridade: Restries relacionadas aos dados armazenados devem ser respeitadas para que as informaes estejam sempre consistentes. Consulta: O tempo gasto para realizar as consultas aos dados armazenados deve ser o menor possvel. Concorrncia: Em geral, diversos sistemas e usurios acessaro concorrentemente as informaes armazenadas. Apesar disso, a integridade dos dados deve ser preservada.

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).

Figura 1.1: Sistema Gerenciador de Banco de Dados

Sistemas Gerenciadores de Banco de Dados


No mercado, h diversas opes de sistemas gerenciadores de banco de dados. Os mais populares so: Oracle Database SQL Server
www.k19.com.br

B ANCO DE D ADOS

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/.

Microsoft SQL Server Management Studio Express

Para interagir com o SQL Server Express, utilizaremos um cliente com interface grca chamado de Microsoft SQL Server Management Studio Express.

Bases de Dados (Databases)


Um sistema gerenciador de banco de dados capaz de gerenciar informaes de diversos sistemas ao mesmo tempo. Por exemplo, as informaes dos clientes de um banco, alm dos produtos de uma loja virtual ou dos livros de uma livraria. Suponha que os dados fossem mantidos sem nenhuma separao lgica. Implementar regras de segurana especcas seria extremamente complexo. Tais regras criam restries quanto ao contedo que pode ser acessado por cada usurio. Por exemplo, determinado usurio poderia ter permisso de acesso aos dados dos clientes do banco, mas no s informaes dos produtos da loja virtual, ou dos livros da livraria. Para obter uma organizao melhor, os dados so armazenados separadamente em um SGDB. Da surge o conceito de base de dados (database). Uma base de dados um agrupamento lgico das informaes de um determinado domnio.

Criando uma base de dados no SQL Server Express

Para criar uma base de dados no SQL Server Express, utilizamos o comando CREATE DATABASE.
2
www.k19.com.br

B ANCO DE D ADOS

www.k19.com.br

B ANCO DE D ADOS

Repare que alm da base de dados livraria h outras bases. Essas bases foram criadas automaticamente pelo prprio SQL Server Express para teste ou para guardar algumas conguraes. 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 informaes de domnios diferentes. Nessa mesma linha de raciocnio, podemos dividir os dados de uma base a m 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 idade cpf 27 31875638735 32 30045667856 Conta saldo 1000 2000

nome Jos Maria

numero 1 2

limite 500 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.

Criando tabelas no SQL Server Express


As tabelas no SQL Server Express so criadas atravs do comando CREATE TABLE. Na criao de uma tabela necessrio denir quais so os nomes e os tipos das colunas.

www.k19.com.br

B ANCO DE D ADOS

www.k19.com.br

B ANCO DE D ADOS

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 ca 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 (Structured Query Language). Essa linguagem oferece quatro comandos bsicos: INSERT, SELECT, UPDATE
6
www.k19.com.br

B ANCO DE D ADOS

e DELETE. Esses comandos so utilizados para inserir, ler, alterar e remover registros, respectivamente.

www.k19.com.br

B ANCO DE D ADOS

www.k19.com.br

B ANCO DE D ADOS

Chaves Primria e Estrangeira


Suponha que os livros da nossa livraria sejam classicados por editoras. As editoras possuem nome e telefone. Para armazenar esses dados, uma nova tabela deveria ser criada. 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.k19.com.br

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 UNIQUE no campo nome da tabela Editora. Porm, ainda teramos mais um problema. Na tabela Livro, 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 devem 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 valores iguais aos da chave primria de outra tabela. Com a denio 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
Abra o Microsoft SQL Server Management Studio Express utilizando NOME_DA_MAQUINA SQLEXPRESS como Server Name, SQL Server Authentication como Authentication, sa como Login e sa como Password.
1

10

www.k19.com.br

11
2

B ANCO DE D ADOS

Caso exista uma base de dados chamada Livraria, remova-a conforme a gura abaixo:

Crie uma nova base de dados chamada livraria, conforme mostrado na gura abaixo. Voc vai utilizar esta base nos exerccios seguintes.
3

www.k19.com.br

11

B ANCO DE D ADOS

12

Crie uma tabela chamada Editoras conforme as guras abaixo.


www.k19.com.br

12

13

B ANCO DE D ADOS

Altere os campos para torn-los obrigatrios, NO permitindo que eles quem em branco NU LL.

Alm disso o campo Id deve ser uma chave primria.


www.k19.com.br

13

B ANCO DE D ADOS

14

O campo Id dever ser incrementado automaticamente. Dena ele com a propriedade Identity segundo a gura abaixo:

14

www.k19.com.br

15
5

B ANCO DE D ADOS

Crie uma tabela chamada Livros conforme as guras abaixo:

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 gura abaixo:
www.k19.com.br

15

B ANCO DE D ADOS

16

Devemos acrescentar o relacionamento entre livro e editora. Clique em Add e posteriormente no boto direita na linha Tables and Columns Specication.

Devemos informar qual a chave primria que a coluna EditoraId da tabela Livros faz referncia.
16
www.k19.com.br

17

B ANCO DE D ADOS

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.

Adicione alguns registros na tabela Editoras. Veja exemplos na gura abaixo:

Adicione alguns registros na tabela Livros. Veja exemplos na gura abaixo:


www.k19.com.br

17

B ANCO DE D ADOS

18

Consulte os registros da tabela Editoras, e em seguida consulte a tabela Livros. Veja exemplos logo abaixo:
7

18

www.k19.com.br

19

B ANCO DE D ADOS

Altere alguns dos registros da tabela Livros. Veja o exemplo abaixo:

Altere alguns dos registros da tabela Editoras. Veja o exemplo abaixo:


www.k19.com.br

19

B ANCO DE D ADOS

20

10

Remova alguns registros da tabela Livros. Veja o exemplo abaixo:

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:
11

20

www.k19.com.br

21

B ANCO DE D ADOS

12 Faa uma consulta para buscar todos os livros de uma determinada editora. Veja um exemplo na gura abaixo:

www.k19.com.br

21

B ANCO DE D ADOS

22

22

www.k19.com.br

CAPTULO
SELECT * FROM tbl_funcionarios WHERE nome LIKE %jonas%; INSERT INTO tbl_funcionarios (nome, codigo, salario) VALUES (Rafael, 1234, 1000);
www.k19.com.br

ADO.NET

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 disponveis 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 conhecimentos 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.

Cadastro de Funcionrios Nome: Cdigo: Salrio:

Figura 2.2: Usurios comuns devem utilizar interfaces simples

www.k19.com.br

23

ADO.NET

24

Driver
As aplicaes interagem com os SGDBs atravs de troca de mensagens. Os SGDBs denem 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

getReference persist begin getTransaction commit

nd

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 complexas para um ser humano compreender. Dessa forma, o trabalho dos desenvolvedores seria muito complexo, aumentando o custo para o desenvolvimento e manuteno das aplicaes.

11 01 01 01 00 01 11 11 11 0 10 010 11 110 01 0 10 01 10 1 10 111 10 110 11 0 01 01 00 01 101 11 1 010 0

Figura 2.4: Mensagens binrias so altamente complexas para os seres humanos

Para resolver esse problema e facilitar o desenvolvimento das aplicaes, as empresas propriet24
www.k19.com.br

1011010111 0010110001 1010111101 0111011100 0101101001 1101011101 0010110011

1011010111 0010110001 1010111101 0111011100 0101101001 1101011101 0010110011

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. Os drivers de conexo so tradutores de comandos escritos em uma determinada linguagem de programao para comandos denidos de acordo com o protocolo de um SGDB. Utilizando um driver de conexo, os desenvolvedores das aplicaes no manipulam diretamente as mensagens binrias trocadas entre as aplicaes e os SGDBs.

Mais Sobre
Em alguns casos, o protocolo binrio de um determinado SGDB fechado. Consequentemente, 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 totalmente independente. Consequentemente, cada driver teria sua prpria interface, ou seja, seu prprio conjunto de instrues. Dessa maneira, o desenvolvedor da aplicao precisa conhecer as instrues de cada um dos drivers dos respectivos bancos que ele for utilizar. Para facilitar o trabalho do desenvolvedor da aplicao, a Microsoft deniu uma especicao chamada ODBC (Open Database Connectivity) para padronizar a interface dos drivers de conexo. Assim, quando uma empresa proprietria de um banco de dados pretende desenvolver um driver, ela segue essa especicao com o intuito de populariz-lo. Os drivers de conexo que respeitam a especicao ODBC, ou seja, possuem um conjunto de comandos padronizados, so chamados de drivers de conexo ODBC.

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 Manager do Windows. O ODBC Manager pode ser executado atravs do item Ferramentas Administrativas do Painel de Controle.
www.k19.com.br

25

ADO.NET

26

Criando uma conexo


Com o driver de conexo ODBC instalado na mquina j possvel criar uma conexo com o banco de dados correspondente. O que necessrio para estabelecer uma conexo com o banco de dados? Escolher o driver de conexo; Denir a localizao do banco de dados; Informar o nome da base de dados; Ter um usurio e senha cadastrados no banco de dados. Todas essas informaes so denidas na chamada string de conexo.
1 2 string stringDeConexao = @ " driver ={ SQL Server }; server = MARCELO - PC \ SQLEXPRESS ; database = livraria ; uid = sa ; pwd = sa ; " ;
Cdigo C# 2.1: Denindo a string de conexo

Aps a denio da string de conexo, podemos utilizar a classe System.Data.Odbc.OdbcConnection do .NET Framework. Essa classe responsvel por criar conexes ODBC.
1 OdbcConnection conexao = new OdbcConnection ( stringDeConexao ) ;
Cdigo C# 2.2: Criando uma conexo ODBC

Inserindo registros
Estabelecida a conexo com o banco de dados, j podemos executar comandos. Por exemplo, possvel inserir registros nas tabelas. O primeiro passo para executar um comando deni-lo em linguagem SQL de acordo com a sintaxe do SGDB utilizado.
26
www.k19.com.br

27
1 2 string textoDoComando = @ " INSERT INTO Editoras ( Nome , Email ) VALUES ( Abril , abril@email . com ) ; " ;

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.

Em seguida, devemos criar um objeto da classe System. Data.Odbc.OdbcCommand a partir do cdigo sql e da conexo previamente criados. O comando no executado quando os objetos dessa classe so instanciados.
1 OdbcCommand comando = new OdbcCommand ( textoDoComando , conexao ) ;
Cdigo C# 2.4: Criando um comando ODBC

Por m, o comando pode ser executado atravs do mtodo ExecuteNonQuery(). A conexo deve ser aberta antes de executar o comando.
1 2 conexao . Open () ; comando . ExecuteNonQuery () ;

Importante
A mesma conexo pode ser reaproveitada para executar vrias operaes. Quando no houver mais operaes a serem executadas, devemos nalizar 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 () ;
Cdigo C# 2.6: Finalizando uma conexo ODBC

Mais Sobre
Em C#, para evitar que o uma conexo no seja fechada aps a sua utilizao, podemos aplicar um bloco using.
1 2 3 4 using ( OdbcConnection conexao = new OdbcConnection ( stringDeConexao ) ) { // utiliza a conexao }
Cdigo C# 2.7: Utilizando um bloco using

No cdigo acima, quando o bloco using que est associado conexo ODBC terminar, automaticamente, essa conexo ser fechada.

Exerccios de Fixao
www.k19.com.br

27

ADO.NET

28

Crie um projeto do tipo Console Application no Microsoft Visual C# Express, chamado ODBC.
1 2 Crie uma classe chamada InsereEditora no projeto ODBC para inserir registros na tabela Editoras.

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3

using System . Data . Odbc ; namespace Odbc { class InsereEditora { static void Main ( string [] args ) { string stringDeConexao = @ " driver ={ SQL Server }; server = MARCELO - PC \ SQLEXPRESS ; database = livraria ; uid = sa ; pwd = sa ; " ; System . Console . Write ( " Digite o Nome da Editora : " ) ; string nome = System . Console . ReadLine () ; System . Console . Write ( " Digite o Email da Editora : " ) ; string email = System . Console . ReadLine () ; string textoInsereEditora = @ " INSERT INTO Editoras ( Nome , Email ) VALUES ( " + nome + @ " , " + email + @ " ) " ; using ( OdbcConnection conexao = new OdbcConnection ( stringDeConexao ) ) { OdbcCommand command = new OdbcCommand ( textoInsereEditora , conexao ) ; conexao . Open () ; command . ExecuteNonQuery () ; } } } }
Cdigo C# 2.8: InsereEditora.cs

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 obtidos 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 comportamento esperado da operao afetado. Eventualmente, registros no so inseridos como deveriam ou brechas de segurana podem se abrir. Por exemplo, considere a classe InsereEditora do exerccio de xao. Se o usurio digitar OReilly e oreilly@email.com, o cdigo SQL gerado pela aplicao seria:
1 INSERT INTO Editoras ( nome , email ) VALUES ( O Reilly , oreilly@email . com )

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.
1 INSERT INTO Editoras ( nome , email ) VALUES ( O Reilly , oreilly@email . com )

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 denominado sanitize.

1 2 3 4 5 6 7 8 9 1 11 12 13 14

// pegando os dados da editora pelo teclado string nome = System . Console . ReadLine () ; string email = System . Console . ReadLine () ; // definindo a sentena SQL com parmetros string textoDoComando = @ " INSERT INTO Editoras ( Nome , Email ) VALUES (? , ?) ; " ; // criando um comando odbc OdbcCommand comando = new OdbcCommand ( textoDoComando , conexao ) ; // atribuindo valores aos parmetros comando . Parameters . AddWithValue ( " @Nome " , nome ) ; comando . Parameters . AddWithValue ( " @Email " , email ) ;
Cdigo C# 2.12: Sanitizando as entradas dos usurios

Observe que a sentena SQL foi denida com parmetros atravs do caractere ?. Antes de executar o comando, necessrio atribuir valores aos parmetros. Isso feito com o mtodo AddWithValue(). Esse mtodo realiza a tarefa de sanitizar os valores enviados pelo usurio.

Exerccios de Fixao
Tente causar um erro de SQL Injection ao inserir editoras com a classe InsereEditora. (Dica: tente entradas com aspas simples)
3

Altere o cdigo da classe InsereEditora para eliminar o problema do SQL Injection. Observe o cdigo abaixo:
4

1 2 3 4 5

using System . Data . Odbc ; namespace Odbc { class InsereEditora

www.k19.com.br

29

ADO.NET
6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 { static void Main ( string [] args ) { string stringDeConexao = @ " driver ={ SQL Server }; server = MARCELO - PC \ SQLEXPRESS ; database = livraria ; uid = sa ; pwd = sa ; " ; System . Console . Write ( " Digite o Nome da Editora : " ) ; string nome = System . Console . ReadLine () ; System . Console . Write ( " Digite o Email da Editora : " ) ; string email = System . Console . ReadLine () ; string textoInsereEditora = @ " INSERT INTO Editoras ( Nome , Email ) VALUES (? ,?) " ; using ( OdbcConnection conexao = new OdbcConnection ( stringDeConexao ) ) { OdbcCommand command = new OdbcCommand ( textoInsereEditora , conexao ) ; command . Parameters . AddWithValue ( " @Nome " , nome ) ; command . Parameters . AddWithValue ( " @Email " , email ) ; conexao . Open () ; command . ExecuteNonQuery () ; } } } }
Cdigo C# 2.13: InsereEditora.cs

30

Agora tente causar novamente o problema de SQL Injection ao inserir novas editoras.

Exerccios Complementares
Provoque um erro de SQL Injection na classe InsereLivro. (Dica: tente entradas com aspas simples.)
2 3 4

Altere o cdigo para eliminar o problema do SQL Injection. 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 insero foi realizada com sucesso. O processo para executar um comando de consulta parecido com o de insero. necessrio denir a sentena SQL e criar um objeto da classe OdbcCommand.
1 2 3 4 5 // definindo a sentena SQL string textoDoComando = @ " SELECT * FROM Editoras ; " ; // criando um comando odbc OdbcCommand comando = new OdbcCommand ( textoDoComando , conexao ) ;
Cdigo C# 2.15: Criando um comando de seleo

A diferena que para executar um comando de consulta necessrio utilizar o mtodo Execu30
www.k19.com.br

31

ADO.NET

teReader() ao invs do ExecuteNonQuery(). Esse mtodo devolve um objeto da classe System.Data.Odbc.OdbcDataReader.


1 OdbcDataReader resultado = comando . ExecuteReader () ;
Cdigo C# 2.16: Executando um comando de consulta

Os dados contidos no OdbcDataReader podem ser acessados atravs dos nomes das colunas.
1 2 string nome = resultado [ " Nome " ] as string ; string email = resultado [ " Email " ] as string ;
Cdigo C# 2.17: Recuperando os campos do primeiro registro do resultado

O cdigo acima mostra como os campos do primeiro registro do resultado da consulta so recuperados. Agora, para recuperar os outros registros necessrio avanar o OdbcDataReader atravs do mtodo Read().
1 2 3 4 5 6 7 string nome1 = resultado [ " nome " ] as string ; string email1 = resultado [ " email " ] as string ; resultado . Read () ; string nome2 = resultado [ " nome " ] as string ; string email2 = resultado [ " email " ] as string ;
Cdigo C# 2.18: Recuperando os campos dos dois primeiros registros do resultado

O prprio mtodo Read() devolve um valor booleano para indicar se o reader conseguiu avanar para o prximo registro. Quando esse mtodo devolver false signica que no h mais registros para serem recuperados.
1 2 3 4 5 while ( resultado . Read () ) { string nome = resultado [ " nome " ] as string ; string email = resultado [ " email " ] as string ; }
Cdigo C# 2.19: Recuperando os campos de todos os registros do resultado

Exerccios de Fixao
Insira algumas editoras utilizando a classe InsereEditora que voc criou nos exerccios anteriores.
6

Adicione uma nova classe ao projeto ODBC chamada ListaEditora. O objetivo listar as editoras que foram salvas no banco. Veja o cdigo dessa classe.
7

1 2 3 4 5 6 7 8

using System . Data . Odbc ; namespace Odbc { class ListaEditora { static void Main ( string [] args ) {

www.k19.com.br

31

ADO.NET
9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 string stringDeConexao = @ " driver ={ SQL Server }; server = MARCELO - PC \ SQLEXPRESS ; database = livraria ; uid = sa ; pwd = sa ; " ; using ( OdbcConnection conexao = new OdbcConnection ( stringDeConexao ) ) { string textoListaEditora = " SELECT * FROM Editoras " ; OdbcCommand command = new OdbcCommand ( textoListaEditora , conexao ) ; conexao . Open () ; OdbcDataReader resultado = command . ExecuteReader () ; while ( resultado . Read () ) { long ? id = resultado [ " Id " ] as long ?; string nome = resultado [ " Nome " ] as string ; string email = resultado [ " Email " ] as string ; System . Console . WriteLine ( " { } : {1} - {2}\ n " ,id , nome , email ) ; } } } } }
Cdigo C# 2.20: ListaEditora.cs

32

Exerccios Complementares
5

Crie uma classe para listar os livros cadastrados na base de dados.

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 car armazenada em diversos locais. Imagine que o driver do banco foi atualizado e mudamos a sua verso. Isso implicaria fazer diversas alteraes no cdigo em cada ocorrncia da string de conexo, tornando o cdigo mais suscetvel a erros e dicultando a sua manuteno. Para resolver esta situao, ns poderamos criar uma classe responsvel pela criao e distribuio 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.
1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 static class ConnectionFactory { public static OdbcConnection CreateConnection () { string driver = @ " SQL Server " ; string servidor = @ " MARCELO - PC \ SQLEXPRESS " ; string baseDeDados = @ " livraria " ; string usuario = @ " sa " ; string senha = @ " sa " ; StringBuilder connectionString = new StringBuilder () ; connectionString . Append ( " driver = " ) ; connectionString . Append ( driver ) ; connectionString . Append ( " ; server = " ) ; connectionString . Append ( servidor ) ; connectionString . Append ( " ; database = " ) ; connectionString . Append ( baseDeDados ) ; connectionString . Append ( " ; uid = " ) ;

32

www.k19.com.br

33
19 2 21 22 23 24 25 connectionString . Append ( usuario ) ; connectionString . Append ( " ; pwd = " ) ; connectionString . Append ( senha ) ; return new OdbcConnection ( connectionString . ToString () ) ; } }
Cdigo C# 2.22: ConnectionFactory.cs

ADO.NET

Agora podemos obter uma nova conexo apenas chamando ConnectionFactory.CreateConnection(). O resto do sistema no precisa mais conhecer os detalhes sobre a conexo com o banco de dados, diminuindo o acoplamento da aplicao.

Exerccios de Fixao
8

Adicione uma nova classe chamada ConnectionFactory com seguinte cdigo:


using System ; using System . Data . Odbc ; using System . Text ; namespace Odbc { static class ConnectionFactory { public static OdbcConnection CreateConnection () { string driver = @ " SQL Server " ; string servidor = @ " MARCELO - PC \ SQLEXPRESS " ; string baseDeDados = @ " livraria " ; string usuario = @ " sa " ; string senha = @ " sa " ; StringBuilder connectionString = new StringBuilder () ; connectionString . Append ( " driver = " ) ; connectionString . Append ( driver ) ; connectionString . Append ( " ; server = " ) ; connectionString . Append ( servidor ) ; connectionString . Append ( " ; database = " ) ; connectionString . Append ( baseDeDados ) ; connectionString . Append ( " ; uid = " ) ; connectionString . Append ( usuario ) ; connectionString . Append ( " ; pwd = " ) ; connectionString . Append ( senha ) ; return new OdbcConnection ( connectionString . ToString () ) ; } } }
Cdigo C# 2.23: ConnectionFactory.cs

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32

Altere as classes InsereEditora e ListaEditora para que elas utilizem a fbrica de conexo. Execute-as novamente.
9

1 2 3 4 5 6

using System . Data . Odbc ; namespace Odbc { class InsereEditora {

www.k19.com.br

33

ADO.NET
7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 static void Main ( string [] args ) { System . Console . Write ( " Digite o Nome da Editora : " ) ; string nome = System . Console . ReadLine () ; System . Console . Write ( " Digite o Email da Editora : " ) ; string email = System . Console . ReadLine () ; string textoInsereEditora = @ " INSERT INTO Editoras ( Nome , Email ) VALUES (? ,?) " ; using ( OdbcConnection conexao = ConnectionFactory . CreateConnection () ) { OdbcCommand command = new OdbcCommand ( textoInsereEditora , conexao ) ; command . Parameters . AddWithValue ( " @Nome " , nome ) ; command . Parameters . AddWithValue ( " @Email " , email ) ; conexao . Open () ; command . ExecuteNonQuery () ; } } } }

34

Cdigo C# 2.24: InsereEditora.cs

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26

using System . Data . Odbc ; namespace Odbc { class ListaEditora { static void Main ( string [] args ) { using ( OdbcConnection conexao = ConnectionFactory . CreateConnection () ) { string textoListaEditora = " SELECT * FROM Editoras " ; OdbcCommand command = new OdbcCommand ( textoListaEditora , conexao ) ; conexao . Open () ; OdbcDataReader resultado = command . ExecuteReader () ; while ( resultado . Read () ) { long ? id = resultado [ " Id " ] as long ?; string nome = resultado [ " Nome " ] as string ; string email = resultado [ " Email " ] as string ; System . Console . WriteLine ( " { } : {1} - {2}\ n " ,id , nome , email ) ; } } } } }

Cdigo C# 2.25: ListaEditora.cs

Exerccios Complementares
Altere as classes InsereLivro e ListaLivro para que elas utilizem a fbrica de conexo. Executeas novamente.
6

34

www.k19.com.br

35

ADO.NET

Desaos
1 2

Implemente um teste que remove uma editora pelo id. Implemente um teste que altera os dados de uma editora pelo id.

www.k19.com.br

35

ADO.NET

36

36

www.k19.com.br

CAPTULO
Driver Oracle ODBC Driver SQL Server ODBC

E NTITY F RAMEWORK

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 denidas 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 denidas atravs de um mecanismo independente da linguagem SQL.

SELECT TOP 100 * FROM livros ORDER BY autor ASC

SELECT * FROM ( SELECT ROW_NUMBER() OVER (ORDER BY autor ASC) AS rownumber, id, titulo, autor FROM livros ) WHERE rownumber <= 100

Figura 3.1: Diferentes sintaxes da linguagem SQL

Orientao a Objetos VS Modelo Relacional


Outro problema na comunicao entre uma aplicao C# e um SGDB o conito de paradigmas. Os SGDBs so organizados seguindo o modelo relacional. Por outro lado, as aplicaes C# utilizam
www.k19.com.br

37

E NTITY F RAMEWORK

38

o modelo orientado a objetos. A transio de dados entre o modelo relacional e o modelo orientado a objetos no simples. Para realizar essa transio, necessrio denir um mapeamento entre os conceitos desses dois paradigmas. Por exemplo, classes podem ser mapeadas para tabelas, objetos para registros, atributos para campos e referncia entre objetos para chaves estrangeiras.

tbl_editoras Livro id = 1 titulo = Os Lusadas autor = Lus Vaz de Cames editora = 1 Editora id = 1 nome = Livraria Cultura Livro id = 2 titulo = Vidas Secas autor = Graciliano Ramos editora = 1 tbl_livros id 1 2 3 4 titulo Os Lusadas Vidas Secas Dom Casmurro O Cortio autor Lus Vaz de Cames Graciliano Ramos Machado de Assis Alusio Azevedo editora_id 1 1 3 2 id 1 2 3 4 nome Cultura FTDA Globo Scipione

ORIENTAO A OBJETOS

MODELO RELACIONAL

Figura 3.2: Modelo Orientado a Objetos vs Modelo Relacional

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). As ferramentas ORM oferecem mecanismos de consultas independentes da linguagem SQL. Dessa forma, o acoplamento entre as aplicaes e os SGDBs diminui drasticamente. As principais ferramentas ORM para C# utilizadas no mercado so o Entity Framework e o NHibernate.
38
www.k19.com.br

39

E NTITY F RAMEWORK

tbl_livros id 1 2 3 4 titulo Os Lusadas Vidas Secas Dom Casmurro O Cortio autor Lus Vaz de Cames Graciliano Ramos Machado de Assis Alusio Azevedo editora_id 1 1 3 2

FERRAMENTA id = 1 ORM titulo = Os Lusadas autor = Lus Vaz de


Cames editora = 1

Livro

Livro id = 2 titulo = Vidas Secas autor = Graciliano Ramos editora = 1

Figura 3.3: Transformao dos dados do Modelo Relacional para o Modelo Orientado a Objetos

tbl_livros

Livro id = 1 titulo = Os Lusadas autor = Lus Vaz de Cames editora = 1

Livro id = 2 titulo = Vidas Secas autor = Graciliano Ramos editora = 1

FERRAMENTA 1 Os Lusadas 2 ORM Vidas Secas


3 4 Dom Casmurro O Cortio

id

titulo

autor Lus Vaz de Cames Graciliano Ramos Machado de Assis Alusio Azevedo

editora_id 1 1 3 2

Figura 3.4: Transformao dos dados do Modelo Orientado a Objetos para o Modelo Relacional

Nesse curso usaremos o Entity Framework 4.3.1, que pode ser obtido em http://www.k19.com. br/EntityFramework.dll ou http://nuget.org/packages/EntityFramework/4.3.1.

Congurao
Para congurar o Entity Framework em uma aplicao, podemos criar um arquivo chamado App.cong. O contedo desse arquivo possuir informaes sobre o banco de dados, como a url de conexo, usurio e senha. Veja abaixo um exemplo de congurao para o App.config.
1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 <? xml version = " 1. " ? > < configuration > < connectionStrings > < add name = " K19Context " providerName = " System . Data . SqlClient " connectionString = " Server =.\ SQLEXPRESS ; Database = k19db ; Trusted_Connection = false ; User Id = sa ; Password = sa ; Persist Security Info = true ; MultipleActiveResultSets = True " / > </ connectionStrings > </ configuration >
Cdigo XML 3.1: App.cong

www.k19.com.br

39

E NTITY F RAMEWORK

40

Mapeamento
Um dos principais objetivos dos frameworks ORM estabelecer o mapeamento entre os conceitos do modelo orientado a objetos e os conceitos do modelo relacional. Este mapeamento pode ser denido atravs de um arquivo XML ou de maneira mais prtica com DbContext. Quando utilizamos DbContext, evitamos a criao de extensos arquivos XML. Considere as entidades Livro e Editora denidas abaixo.
1 2 3 4 5 6 7 public class Livro { public int LivroId { get ; set ; } public string Titulo { get ; set ; } public decimal Preco { get ; set ; } public Editora Editora { get ; set ; } }
Cdigo C# 3.1: Livro.cs

1 2 3 4 5 6 7

public class Editora { public int EditoraId { get ; set ; } public string Nome { get ; set ; } public string Email { get ; set ; } public ICollection < Livro > Livros { get ; set ; } }
Cdigo C# 3.2: Editora.cs

Criaremos uma classe para ajudar a mapear essas entidades para o banco de dados. A classe

EditoraContext deriva de DbContext, que faz parte da biblioteca Code First:


1 2 3 4 5 public class EditoraContext : DbContext { public DbSet < Editora > Editoras { get ; set ; } public DbSet < Livro > Livros { get ; set ; } }
Cdigo C# 3.3: EditoraContext.cs

Utilizamos o recurso Code First do Entity Framework 4 para permitir a persistncia no banco de dados. Isto signica que as propriedades Editoras e Livros de EditoraContext sero mapeadas para tabelas com mesmo nome no banco de dados. Ou seja, a propriedade Editoras ser mapeada para uma tabela chamada Editoras e a propriedade Livros ser mapeada para uma tabela chamada Livros. Cada propriedade denida nas entidades Livro e Editora ser mapeada para uma coluna nas tabelas Livros e Editoras. Abaixo segue a denio da tabela Editoras que foi criada em nosso banco de dados:

40

www.k19.com.br

41

E NTITY F RAMEWORK

Abaixo segue a denio da tabela Livros que foi criada em nosso banco de dados:

Utilizando o Code First, no foi necessrio congurar nada para que a persistncia e o mapeamento fossem realizados. Isto ocorreu simplesmente escrevendo as trs classes acima. Nenhuma congurao a mais necessria. Podemos utilizar anotaes para sobrescrever o mapeamento padro. Para utilizar anotaes, precisamos adicionar como referncia as bibliotecas EntityFramework.dll e System.ComponentModel.DataAnnotations.dll ao projeto e acrescentar using para o namespace System.ComponentModel.DataAnnotations. A seguir descrevemos as principais anotaes. ColumnAttribute: Dene o nome e o tipo da coluna no banco de dados da propriedade mapeada.
1 2 3 4 5 6 7 8 public class Livro { public int LivroId { get ; set ; } [ Column ( " NomeDoLivro " , TypeName = " varchar " ) ] public string Titulo { get ; set ; } public decimal Preco { get ; set ; } public Editora Editora { get ; set ; } }
Cdigo C# 3.4: Livro.cs

DatabaseGeneratedAttribute: Utilizado para indicar que o valor do atributo gerado automaticamente pelo banco de dados. Para denir como o valor do atributo gerado, podemos utilizar trs constantes do enum DatabaseGenerateOption: DatabaseGeneratedOption.Identity: o valor de um atributo com a opo Identity deve ser gerado quando a instncia for salva (com a chamada de SaveChanges()) pela primeira vez. Alm disso, o banco de dados supe que esse valor no ser mais alterado. Portanto, no se deve modicar o valor desse atributo. DatabaseGeneratedOption.Computed: o valor de um atributo com a opo Computed gerado sempre que a instncia for salva. DatabaseGeneratedOption.None: o valor de um atributo com a opo None no ser gerado pelo banco de dados. ForeignKeyAttribute: Dene que o atributo ser mapeado para uma chave estrangeira.
1 2 3 4 public class Livro { public int LivroId { get ; set ; } public string Titulo { get ; set ; }

www.k19.com.br

41

E NTITY F RAMEWORK
5 6 7 8 9 public decimal Preco { get ; set ; } [ ForeignKey ( " Editora " ) ] public int EditoraId { get ; set ; } public Editora Editora { get ; set ; } }
Cdigo C# 3.5: Livro.cs

42

1 2 3 4 5 6 7

public class Editora { public int EditoraId { get ; set ; } public string Nome { get ; set ; } public string Email { get ; set ; } public ICollection < Livro > Livros { get ; set ; } }
Cdigo C# 3.6: Editora.cs

InversePropertyAttribute: Nos relacionamentos bidirecionais, utilizamos essa anotao para evitar o mapeamento de dois relacionamentos unidirecionais ao invs de um bidirecional. Por exemplo, considere as entidades Pessoa e Livro. Podemos estabelecer um relacionamento bidirecional entre essas entidades, pois uma pessoa pode escrever um livro.
1 2 3 4 5 6 public class Pessoa { public int Id { get ; set ; } public string Nome { get ; set ; } public ICollection < Livro > LivrosPublicados { get ; set ; } }
Cdigo C# 3.7: Pessoa.cs

1 2 3 4 5 6 7 8 9 1

public class Livro { public int LivroId { get ; set ; } public string Titulo { get ; set ; } public decimal Preco { get ; set ; } public Editora Editora { get ; set ; } [ InverseProperty ( " LivrosPublicados " ) ] public Pessoa Autor { get ; set ; } }
Cdigo C# 3.8: Livro.cs

No cdigo acima, a propriedade Autor da classe Livro foi mapeada com a anotao InverseProperty para evitar que dois relacionamentos unidirecionais fossem estabelecidos entre Pessoa e Livro. KeyAttribute: Dene uma ou mais propriedades que identicam unicamente as instncias de uma entidade. Se a classe dene propriedades chamadas ID ou Id, ou com o nome da classe seguido por ID ou Id, esta propriedade tratada como chave primria por conveno. Caso contrrio, podemos denir a nossa chave primria com o KeyAttribute. No exemplo abaixo, denimos a propriedade Identificador para ser a chave primria correspondente entidade Pessoa.
1 2 public class Pessoa {

42

www.k19.com.br

43
3 4 5 6 7 8 [ Key ] public public public public }
Cdigo C# 3.9: Pessoa.cs

E NTITY F RAMEWORK

int Identificador { get ; set ; } string Nome { get ; set ; } ICollection < Livro > LivrosPublicados { get ; set ; } ICollection < Livro > LivrosRevisados { get ; set ; }

MaxLengthAttribute: Dene o tamanho mximo permitido para um array ou string. MinLengthAttribute: Dene o tamanho mnimo permitido para um array ou string.
1 2 3 4 5 6 7 8 9 public class Pessoa { public int Id { get ; set ; } [ MinLength (1 , ErrorMessage = " Tamanho minimo : 1 " ) ] [ MaxLength (255 , ErrorMessage = " Tamanho mximo : 255 " ) ] public string Nome { get ; set ; } public ICollection < Livro > LivrosPublicados { get ; set ; } public ICollection < Livro > LivrosRevisados { get ; set ; } }
Cdigo C# 3.10: Pessoa.cs

StringLengthAttribute: Dene os tamanhos mnimo e mximo permitido para o campo string.


1 2 3 4 5 6 7 8 9 public class Editora { public int EditoraId { get ; set ; } [ StringLength (255 , MinimumLength =1 ) ] public string Nome { get ; set ; } public string Email { get ; set ; } public string ExtraInfo { get ; set ; } public ICollection < Livro > Livros { get ; set ; } }
Cdigo C# 3.11: Editora.cs

NotMappedAttribute: Pode ser aplicado em classes ou propriedades. Indica que a classe ou propriedade anotada no deve ser mapeada para o banco de dados.
1 2 3 4 5 6 7 8 9 public class Editora { public int EditoraId { get ; set ; } public string Nome { get ; set ; } public string Email { get ; set ; } [ NotMapped ] public string ExtraInfo { get ; set ; } public ICollection < Livro > Livros { get ; set ; } }
Cdigo C# 3.12: Editora.cs

RequiredAttribute: Dene que o campo obrigatrio. Este atributo ignorado em propriedades do tipo collection. Quando denido numa referncia, indica que a cardinalidade 1 e a propriedade da chave estrangeira no-nula.
1 2 3 4 public class Editora { public int EditoraId { get ; set ; } [ Required ]

www.k19.com.br

43

E NTITY F RAMEWORK
5 6 7 8 9 public public public public }
Cdigo C# 3.13: Editora.cs

44

string Nome { get ; set ; } string Email { get ; set ; } string ExtraInfo { get ; set ; } ICollection < Livro > Livros { get ; set ; }

TableAttribute: Dene a tabela para a qual a classe deve ser mapeada.


1 2 3 4 5 6 7 8 9 1 [ Table ( " Livros " ) ] public class Livro { public int LivroId { get ; set ; } public string Titulo { get ; set ; } public decimal Preco { get ; set ; } public Editora Editora { get ; set ; } public Pessoa Autor { get ; set ; } public Pessoa Revisor { get ; set ; } }
Cdigo C# 3.14: Livro.cs

Manipulando entidades
Mostramos anteriormente que as entidades de uma aplicao so mapeadas atravs de uma classe que deriva de DbContext. Considere o seguinte exemplo. Suponha que as entidades da nossa aplicao foram mapeadas com a classe K19Context, que deriva de DbContext. As instncias das entidades da nossa aplicao sero administradas por objetos da classe K19Context. Esses objetos so responsveis pelas operaes de insero, remoo, alterao e consulta. Mostraremos a seguir as principais operaes que podem ser realizadas atravs de um DbContext.

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. Para armazenar de fato as informaes de um objeto no banco de dados, utilizamos o mtodo SaveChanges() do DbContext. Todos os objetos do contexto que estejam no estado Added so inseridos no banco de dados quando o mtodo SaveChanges() chamado.
1 2 3 4 5 6 7 using ( var context = new EditoraContext () ) { Editora editora = new Editora { Nome = " K19 " , Email = " contato@k19 . com . br " }; // Adiciona a editora criada ao contexto com estado Added context . Editoras . Add ( editora ) ; context . SaveChanges () ; }
Cdigo C# 3.15: Persistindo um objeto

44

www.k19.com.br

45

E NTITY F RAMEWORK

Buscando
Para obter um objeto que contenha informaes do banco de dados, basta utilizar o mtodo

Find() do DbSet. Podemos passar o identicador do objeto que desejamos recuperar como parmetro para esse mtodo.
1 Editora editora = context . Editoras . Find (1) ;
Cdigo C# 3.16: Buscando uma editora com o identicador 1

Removendo
Para indicar que determinado objeto deve ser removido, basta utilizar o mtodo System.Data.Entity.DbSet.Remove(). Esse mtodo marca o objeto para ser removido do banco de dados, colocando-o no estado Deleted. Quando o mtodo SaveChanges() chamado, todas os objetos no estado Deleted so removidos do banco de dados.
1 2 3 Editora editora = context . Editoras . Find (1) ; context . Editoras . Remove ( editora ) ; context . SaveChanges () ;
Cdigo C# 3.17: Removendo uma editora do banco de dados

Atualizando
Para alterar os dados de um registro correspondente a um objeto, basta utilizar as suas propriedades. Quando as propriedades de um objeto do contexto so alteradas, o estado Modied associado a este objeto. Objetos no estado Modified so atualizados no banco de dados quando o mtodo SaveChanges() chamado.
1 2 3 Editora editora = context . Editoras . Find (1) ; editora . Nome = " Abril S / A " ; context . SaveChanges () ;
Cdigo C# 3.18: Alterando o nome de uma editora

Listando
Para obter uma listagem com todos os objetos referentes aos registros de uma tabela, podemos utilizar o Language Integrated Query (LINQ), que nos permite escrever consultas dentro do cdigo C#.
1 2 3 4 5 6 var consulta = from e in context . Editoras where e . Nome . Contains ( " A " ) select e ; // Equivalente a : SELECT * FROM Editoras e where e . Nome Like A % foreach ( var item in consulta )

www.k19.com.br

45

E NTITY F RAMEWORK
7 8 9 { System . Console . WriteLine ( " Editora : " + item . Nome ) ; }
Cdigo C# 3.19: Utilizando LINQ para fazer uma consulta

46

46

www.k19.com.br

47

E NTITY F RAMEWORK

Exerccios de Fixao
Crie um projeto do tipo Console Application no Microsoft Visual C# Express, chamado EF4-Code-First.
1 2

Adicione ao projeto as bibliotecas EntityFramework.dll e System.ComponentModel.Data-

Annotations.dll.

Figura 3.5: Adicionando uma referncia

Faa o download da biblioteca EntityFramework.dll no site da K19 (http://www.k19.com.br/ EntityFramework.dll) e ento adicione-a ao projeto:

Figura 3.6: Adicionando EntityFramework.dll ao projeto

www.k19.com.br

47

E NTITY F RAMEWORK

48

Adicione a biblioteca System.ComponentModel.DataAnnotations.dll ao projeto:

Figura 3.7: Adicionando System.ComponentModel.DataAnnotations.dll ao projeto

Dena uma classe Editora conforme cdigo abaixo:


namespace EF4_Code_First { public class Editora { public int Id { get ; set ; } public string Nome { get ; set ; } public string Email { get ; set ; } } }
Cdigo C# 3.20: Editora.cs

1 2 3 4 5 6 7 8 9

Dena uma classe LivrariaContext que derivada de DbContext. Nesta classe dena uma propriedade Editoras do tipo genrico DbSet<Editora>.
4

1 2 3 4 5 6 7 8 9

using System . Data . Entity ; namespace EF4_Code_First { public class LivrariaContext : DbContext { public DbSet < Editora > Editoras { get ; set ; } } }
Cdigo C# 3.21: LivrariaContext.cs

Adicione o arquivo App.config e dena a string de conexo.


www.k19.com.br

48

49

E NTITY F RAMEWORK

Figura 3.8: App.cong

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15

<? xml version = " 1. " encoding = " utf -8 " ? > < configuration > < connectionStrings > < add name = " LivrariaContext " providerName = " System . Data . SqlClient " connectionString = " Server =.\ SQLEXPRESS ; Database = efcodefirst ; Trusted_Connection = false ; User Id = sa ; Password = sa ; Persist Security Info = true ; MultipleActiveResultSets = True " / > </ connectionStrings > </ configuration >
Cdigo XHTML 3.1: Arquivo App.cong

Dena uma classe InsereEditora:


using System ; namespace EF4_Code_First { public class InsereEditora { static void Main ( string [] args ) { using ( LivrariaContext db = new LivrariaContext () ) { Console . WriteLine ( " Digite o nome da Editora : " ) ; string nome = Console . ReadLine () ; Console . WriteLine ( " Digite o email da Editora : " ) ; string email = Console . ReadLine () ; Editora e = new Editora { Nome = nome , Email = email }; db . Editoras . Add ( e ) ;

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16

www.k19.com.br

49

E NTITY F RAMEWORK
17 18 19 2 21 db . SaveChanges () ; } } } }
Cdigo C# 3.22: InsereEditora.cs

50

Dena a classe ListaEditoras:


using System . Linq ; using System ; namespace EF4_Code_First { public class ListaEditoras { static void Main ( string [] args ) { using ( LivrariaContext db = new LivrariaContext () ) { var consulta = from e in db . Editoras select e ; foreach ( Editora editora in consulta ) { Console . WriteLine ( " { } - {1} {2} " , editora . Id , editora . Nome , editora . Email ) ; } } } } }
Cdigo C# 3.23: classe ListaEditoras

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21

Repositrios
As classes DbContext e DbSet do EF oferecem recursos sucientes para que os objetos do domnio sejam persistidos, recuperados, alterados e removidos do banco de dados. Porm, em aplicaes com alta complexidade e grande quantidade de cdigo, espalhar as chamadas aos mtodos do DbContext e DbSet pode gerar diculdades na manuteno e no entendimento do sistema. Para melhorar a organizao das nossas aplicaes, diminuindo o custo de manuteno e aumentando a legibilidade do cdigo, podemos aplicar o padro Repository do DDD (Domain Driven Design). Conceitualmente, um repositrio representa o conjunto de todos os objetos de um determinado tipo. Ele deve oferecer mtodos para administrar seus elementos. 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 ferramenta ORM como o Entity Framework.
1 2 3 4 5 6 7 using using using using System ; System . Collections . Generic ; System . Linq ; System . Data . Entity ;

namespace EF4_Code_First {

50

www.k19.com.br

51
8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 public class EditoraRepository { DbContext context ; public EditoraRepository ( DbContext context ) { this . context = context ; } public void Adiciona ( Editora e ) { context . Set < Editora >() . Add ( e ) ; context . SaveChanges () ; } public Editora Busca ( int id ) { return context . Set < Editora >() . Find ( id ) ; } public List < Editora > BuscaTodas () { var consulta = from e in context . Set < Editora >() select e ; return consulta . ToList () ; } } }
Cdigo C# 3.24: EditoraRepository.cs

E NTITY F RAMEWORK

1 2 3 4 5

var context = new EditoraContext () ; EditoraRepository repository = new EditoraRepository ( context ) ; List < Editora > editoras = repository . BuscaTodas () ;
Cdigo C# 3.25: Buscando todas as editoras armazenadas no banco de dados

Exerccios de Fixao
8

Implemente um repositrio de editoras criando uma nova classe no projeto EF4-Code-First.


using System ; using System . Linq ; using System . Collections . Generic ; namespace EF4_Code_First { public class EditoraRepository : IDisposable { private LivrariaContext db = new LivrariaContext () ; public void Adiciona ( Editora e ) { db . Editoras . Add ( e ) ; db . SaveChanges () ; } public Editora Busca ( int id ) { Editora e = db . Editoras . Find ( id ) ; return e ; }

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21

www.k19.com.br

51

E NTITY F RAMEWORK
22 23 24 25 26 27 28 29 3 31 32 33 34 35

52

public List < Editora > BuscaTodas () { var consulta = from e in db . Editoras select e ; return consulta . ToList () ; } public void Dispose () { db . Dispose () ; } } }
Cdigo C# 3.26: EditoraRepository.cs

Altere a classe InsereEditora para que utilize o repositrio de editoras.


using System ; namespace EF4_Code_First { public class InsereEditora { static void Main ( string [] args ) { using ( EditoraRepository repository = new EditoraRepository () ) { Console . WriteLine ( " Digite o nome da Editora : " ) ; string nome = Console . ReadLine () ; Console . WriteLine ( " Digite o email da Editora : " ) ; string email = Console . ReadLine () ; Editora e = new Editora { Nome = nome , Email = email }; repository . Adiciona ( e ) ; } } } }
Cdigo C# 3.27: InsereEditora.cs

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19

10

Altere a classe ListaEditoras para que utilize o repositrio de editoras.


using System ; namespace EF4_Code_First { public class ListaEditoras { static void Main ( string [] args ) { using ( EditoraRepository repository = new EditoraRepository () ) { var consulta = repository . BuscaTodas () ; foreach ( Editora editora in consulta ) { Console . WriteLine ( " { } - {1} {2} " , editora . Id , editora . Nome , editora . Email ) ; } } } } }
Cdigo C# 3.28: ListaEditoras.cs

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18

52

www.k19.com.br

CAPTULO

V ISO G ERAL DO ASP.NET MVC

Necessidades de uma aplicao web

HTTP

Os usurios de uma aplicao web utilizam navegadores (browsers) para interagir com essa aplicao. A comunicao entre navegadores e uma aplicao web realizada atravs de requisies e respostas denidas 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 eciente 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 eciente que permita que o contedo das pginas das aplicaes web seja gerado dinamicamente.
www.k19.com.br

53

V ISO G ERAL DO ASP.NET MVC

54

Aplicao Web
Requisio HTTP

TP

HT

qu

isi

Re

www.k19.com.br

www.k19.com.br

Cursos

Artigos

Apostilas

Figura 4.1: Necessidades de uma aplicao web

Soluo
Resolver os trs problemas apresentados tomaria boa parte do tempo de desenvolvimento, alm de exigir conhecimentos tcnicos extremamente especcos por parte dos desenvolvedores. Para facilitar o desenvolvimento de aplicaes web, a plataforma .NET soluciona esses problemas fundamentais. A plataforma .NET oferece os seguintes recursos fundamentais para o desenvolvimento de aplicaes web: Envio e recebimento de mensagens HTTP. Acesso simultneo das aplicaes por vrios usurios de uma maneira eciente. Gerao dinmica das pginas das aplicaes.

ASP .NET MVC


Atualmente, o ASP .NET MVC o framework para desenvolvimento de aplicaes web na plataforma .NET em maior ascenso. A documentao desse framework pode ser obtida em http: //www.asp.net/mvc. O ASP.NET MVC fortemente baseado nos padres MVC e Front Controller.

MVC e Front Controller


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.
54
www.k19.com.br

qu Re aH st TT P
www.k19.com.br

isi Re o sp

HT

TP
Resposta HTTP

Re sp o st a HT TP

55

V ISO G ERAL DO ASP.NET MVC

Esse padro (ou alguma variao) amplamente adotado nas principais plataformas de desenvolvimento atuais. Em particular, ele bastante utilizado no desenvolvimento de aplicaes web. O padro MVC divide uma aplicao em trs tipos de componentes: modelo, viso e controlador.

Modelo: encapsula os dados e as funcionalidades da aplicao. Viso: responsvel pela exibio de informaes, cujos dados so obtidos do modelo. Controlador: recebe as requisies do usurio e aciona o modelo e/ou a viso.

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, Regine Meunier, Hans Rohnert, Peter Sommerlad, Michael Stal e Michael Stal. No padro Front Controller, todas as requisies do usurio so recebidas pelo mesmo componente. Dessa forma, tarefas que devem ser realizadas em todas as requisies podem ser implementadas 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 Web Developer


O primeiro passo para construir uma aplicao web utilizando ASP .NET MVC criar um projeto no Visual Web Developer a partir do modelo adequado. No nosso caso, o modelo de projeto que deve ser utilizado o ASP .NET MVC 4 Web Application.

Figura 4.2: Criando um projeto

www.k19.com.br

55

V ISO G ERAL DO ASP.NET MVC

56

Devemos escolher Basic Project conforme gura abaixo:

Figura 4.3: Criando um projeto

O projeto criado j vem com diversas pastas e arquivos. Ao longo dos prximos captulos, a funo de cada pasta e de cada arquivo ser discutida.

Testando a aplicao
Para vericar o funcionamento do projeto, basta execut-lo atravs do menu: Debug -> Start Debugging. Automaticamente um servidor de desenvolvimento inicializado na mquina e a aplicao implantada nesse servidor. Alm disso, uma janela do navegador padro do sistema aberta na url principal da aplicao. O servidor pode ser nalizado atravs do cone ASP .NET Development Server que ca na barra de tarefas do Windows.

Trocando a porta do servidor


Para trocar a porta utilizada pelo servidor de desenvolvimento que o Visual Web Developer utiliza, basta alterar as propriedades do projeto clicando com o boto direito do mouse no projeto e escolhendo o item properties e depois a aba web.

Exemplo de uma Aplicao Web


56
www.k19.com.br

57

V ISO G ERAL DO ASP.NET MVC

Veremos a seguir um exemplo de uma simples aplicao web em ASP.NET MVC. Essa aplicao ter apenas uma pgina web que mostrar o nmero de acessos essa pgina at o momento. Primeiramente, criaremos uma classe na camada de controle da aplicao para armazenar esse nmero. As classes que denem controladores devem derivar da classe Controller e seus nomes devem terminar com a palavra Controller. Alm disso, essas classes devem estar na pasta Controllers da aplicao. Considere a classe K19Controller denida abaixo.
1 2 3 4 5 6 7 8 9 1 11 public class K19Controller : Controller { private static int NumeroDeAcessos { get ; set ; } public ActionResult Home () { K19Controller . NumeroDeAcessos ++; ViewBag . Acessos = K19Controller . NumeroDeAcessos ; return View () ; } }
Cdigo C# 4.1: K19Controller.cs

A classe K19Controller possui uma propriedade chamada NumeroDeAcessos, que armazenar o nmero de acessos nossa pgina. O mtodo Home() ser chamado toda vez que a url http://<IP_SERVIDOR>:<PORTA_APP>/K19/Home for requisitada por um navegador. Note que essa url formada pelo nome do controlador (nome da classe que dene o controlador sem o suxo Controller) seguido pelo nome desse mtodo. Cada vez que o mtodo Home() chamado, o valor da propriedade NumeroDeAcessos incrementado. Alm disso, o valor atualizado dessa propriedade colocado na ViewBag para que possa ser acessado na camada de apresentao. Para indicar que o uxo de execuo deve seguir para a camada de apresentao, o mtodo Home() invoca o mtodo View() e devolve a resposta obtida. Por padro, o uxo ser direcionado para um arquivo chamado Home.cshtml que deve estar localizado na pasta Views\K19\. Na camada de apresentao, vamos adicionar a tela associada ao mtodo Home(). Para isso, criaremos um arquivo chamado Home.cshtml na pasta Views\K19\ da aplicao com o contedo abaixo.
1 2 3 4 @{ ViewBag . Title = " Home " ; } < h2 > Acessos : @ViewBag . Acessos </ h2 >
Cdigo CSHTML 4.1: Home.cshtml

Para acessar a ViewBag, devemos utilizar o caractere @, como no cdigo acima.

Exerccios de Fixao
1

Crie um projeto do tipo ASP .NET MVC 4 Web Application chamado K19. Utilize o template Basic
www.k19.com.br

57

V ISO G ERAL DO ASP.NET MVC

58

Project.

Figura 4.4: Criando um projeto

Figura 4.5: Criando um projeto

Dena uma pgina de saudao. Para isto, crie um controlador chamado K19 no projeto K19 conforme a gura abaixo:
2

58

www.k19.com.br

59

V ISO G ERAL DO ASP.NET MVC

Figura 4.6: Criando um controlador

Figura 4.7: Criando um controlador

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15

using System ; using System . Web . Mvc ; namespace K19 . Controllers { public class K19Controller : Controller { public ActionResult Home () { Random random = new Random () ; ViewBag . NumeroDaSorte = random . Next () ; return View () ; } } }
Cdigo C# 4.2: K19Controller.cs

www.k19.com.br

59

V ISO G ERAL DO ASP.NET MVC


3

60

Dentro da pasta Views, crie uma pasta chamada K19.

Figura 4.8: Criando uma pasta

Dena a pgina com a mensagem de saudao. Crie um arquivo chamado Home.cshtml dentro da pasta Views\K19\.
4

Figura 4.9: Adicionando uma tela

60

www.k19.com.br

61

V ISO G ERAL DO ASP.NET MVC

Figura 4.10: Adicionando uma tela

1 2 3 4

@{ ViewBag . Title = " Home " ; } < h2 > Ol ! O seu nmero da sorte @ViewBag . NumeroDaSorte </ h2 >

Cdigo CSHTML 4.2: Home.cshtml

Para visualizar a pgina, basta executar o projeto no Visual Studio e acessar o endereo http://localhost:<PORTA_APP>/K19/Home
www.k19.com.br

61

V ISO G ERAL DO ASP.NET MVC

62

Figura 4.11: Acessando a pgina da aplicao

Integrao com Entity Framework


A integrao entre Entity Framework e ASP.NET MVC 4 realizada de maneira extremamente simples. No Visual Studio 2010, ao criar-se um projeto ASP.NET MVC 4 do tipo Basic, a biblioteca do Entity Framework 5 ca disponvel automaticamente para o projeto. A string de conexo que a aplicao ASP.NET MVC 4 utilizar deve ser denida no arquivo de congurao Web.config.
1 2 3 4 5 6 7 8 9 1 11 12 13 14 ... < connectionStrings > < add name = " K19Context " providerName = " System . Data . SqlClient " connectionString = " Server =.\ SQLEXPRESS ; Database = k19bd ; Trusted_Connection = false ; User Id = sa ; Password = sa ; Persist Security Info = true ; MultipleActiveResultSets = True " / > </ connectionStrings > ...
Cdigo XML 4.1: Exemplo de string de conexo

Por m, bastaria implementar as entidades e mape-las como visto no Captulo 3.

Scaffold
O Visual Studio 2010 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 controla62
www.k19.com.br

63

V ISO G ERAL DO ASP.NET MVC

dores gerados podem utilizar as funcionalidades do Entity Framework para interagir com o banco de dados.

Exerccios de Fixao
Vamos gerar o nosso primeiro scaffold. Para isto, dena as classes Editora e K19Context na pasta Models do nosso projeto K19.
6

1 2 3 4 5 6 7 8 9

namespace K19 . Models { public class Editora { public int Id { get ; set ; } public string Nome { get ; set ; } public string Email { get ; set ; } } }

Cdigo C# 4.3: Editora.cs

1 2 3 4 5 6 7 8 9

using System . Data . Entity ; namespace K19 . Models { public class K19Context : DbContext { public DbSet < Editora > Editoras { get ; set ; } } }

Cdigo C# 4.4: K19Context.cs

Dena a string de conexo. Para isto, altere o arquivo Web.config da raiz do projeto K19 e acrescente a string de conexo dentro da tag <conguration>.
7

1 2 3 4 5 6 7 8 9 1 11 12 13 14

... < connectionStrings > < add name = " K19Context " providerName = " System . Data . SqlClient " connectionString = " Server =.\ SQLEXPRESS ; Database = k19bd ; Trusted_Connection = false ; User Id = sa ; Password = sa ; Persist Security Info = true ; MultipleActiveResultSets = True " / > </ connectionStrings > ...

Cdigo XML 4.2: String de conexo

Antes de gerar o scaffold, precisamos fazer um build no projeto.


www.k19.com.br

63

V ISO G ERAL DO ASP.NET MVC

64

Figura 4.12: Build do projeto

Aps o build do projeto, podemos gerar o scaffold. Para isto, devemos criar um controlador chamado Editora conforme a gura abaixo.
9

Figura 4.13: Gerando o scaffold

Dena o model que deseja gerar o scaffold e a classe responsvel pelo acesso ao banco de dados.
64
www.k19.com.br

65

V ISO G ERAL DO ASP.NET MVC

Figura 4.14: Gerando o scaffold

Aps gerar o scaffold, verique os arquivos gerados no projeto.


www.k19.com.br

65

V ISO G ERAL DO ASP.NET MVC

66

Figura 4.15: Scaffold gerado

10

Para testar, acesse o endereo http://localhost:<PORTA_APP>/Editora.

66

www.k19.com.br

CAPTULO

C AMADA DE A PRESENTAO

A camada de apresentao responsvel por gerar as pginas de uma aplicao web. Os dados apresentados em uma pgina web so denidos na camada de modelo. A camada de controle recupera os dados da camada de modelo e os envia para a camada de apresentao. Basicamente, a camada de apresentao denir como esses dados sero apresentados para os usurios da aplicao. O uxo 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. Mostraremos, neste captulo, como a camada de apresentao de uma aplicao web construda com a utilizao de recursos do ASP.NET MVC como Inline Code, HTML Helper, Layout e Partial Views.

Razor e ASPX
At a segunda verso do ASP .NET MVC, as telas (ou pginas) de uma aplicao web eram desenvolvidas 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 (<% %>). Nos exemplos abaixo, mostraremos algumas diferena entre Razor e ASPX.

Criando Variveis
Toda expresso em Razor comea com o caractere @. Para criarmos variveis, precisamos declarlas dentro de um bloco Razor:
1 2 3 4 5 6 @{ string nome = " K19 " ; string telefoneDaK19 = " 2387 -3791 " ; string enderecoDaK19 = " Av . Brigadeiro Faria Lima " ; int numeroDaK19 = 1571; }
Cdigo CSHTML 5.1: Criando variveis em Razor

1 2 3 4 5 6

<% string nome = " K19 " ; string telefoneDaK19 = " 2387 -3791 " ; string enderecoDaK19 = " Av . Brigadeiro Faria Lima " ; int numeroDaK19 = 1571; %>

www.k19.com.br

67

C AMADA DE A PRESENTAO

68

Cdigo ASPX 5.1: Criando variveis em ASPX

Acessando variveis
As variveis podem ser facilmente acessadas.
1 <p > Telefone da K19 : @telefoneDaK19 </ p >
Cdigo CSHTML 5.2: Acessando uma varivel

<p > Telefone da K19 : < %= telefoneDaK19 % > </ p >


Cdigo ASPX 5.2: Acessando uma varivel

Condicionais (if e else)


Podemos utilizar os comandos de controle de uxo if e else. Veja os exemplos abaixo.
1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 @if ( numero == numeroDaK19 ) { <p > Chegou na K19 ! </ p > } else { <p > Continue andando . </ p > } <! -- ou -- > @{ int numero = 463; if ( numero == numeroDaK19 ) { <p > Chegou na K19 ! </ p > } else { <p > Continue andando . </ p > } }
Cdigo CSHTML 5.3: Utilizando if e else em Razor

1 2 3 4 5 6 7 8 9 1 11 12 13 14

<% if ( numero == numeroDaK19 ) { %> <p > Chegou na K19 ! </ p > <% } else { %> <p > Continue andando . </ p > <% } %>
Cdigo CSHTML 5.4: Utilizando if e else em ASPX

68

www.k19.com.br

69

C AMADA DE A PRESENTAO

Laos
Podemos criar laos utilizando o comando for.
1 2 3 4 @for ( int i = ; i < 5; i ++) { <p >i = @i </ p > }
Cdigo CSHTML 5.5: Criando um lao em Razor

1 2 3 4 5 6 7 8

<% for ( int i = ; i < 5; i ++) { %> <p >i = < %= i % > </ p > <% } %>
Cdigo ASPX 5.3: Criando um lao em ASPX

Texto e cdigo
1 2 3 4 @if ( x == " nome " ) { @ : O nome da editora @editora . Nome }
Cdigo CSHTML 5.6: Texto e cdigo em Razor

1 2 3 4 5 6 7 8

<% if ( x == " nome " ) { %> O nome da editora < %= editora . Nome % > <% } %>
Cdigo ASPX 5.4: Texto e cdigo em ASPX

Comentrios
Podemos adicionar comentrios nas pginas.
1 @ * Comentrio * @
Cdigo CSHTML 5.7: Comentrios em Razor

<% -- Comentrio --% >


Cdigo ASPX 5.5: Comentrios em ASPX

www.k19.com.br

69

C AMADA DE A PRESENTAO

70

Exerccios de Fixao
Utilize o projeto K19 e altere o arquivo Views\K19\Home.cshtml para imprimir uma mensagem dez vezes.
1

1 2 3 4 5 6 7 8

@{ ViewBag . Title = " Home " ; } @for ( int i = ; i < 1 ; i ++) { < h2 > Ol ! O seu nmero da sorte @ViewBag . NumeroDaSorte </ h2 > }

Cdigo CSHTML 5.8: Home.cshtml

Para ver o resultado, acesse a url http://localhost:<PORTA_APP>/K19/Home. Altere o arquivo Home.cshtml do exerccio anterior para imprimir uma mensagem a partir de uma varivel.
2

1 2 3 4 5 6 7 8 9

@{ ViewBag . Title = " Home " ; string mensagem = " Ol ! O seu nmero da sorte " + @ViewBag . NumeroDaSorte ; } @for ( int i = ; i < 1 ; i ++) { < h2 > @mensagem </ h2 > }

Cdigo CSHTML 5.9: Home.cshtml

Para ver o resultado, acesse a url http://localhost:<PORTA_APP>/K19/Home.

Exerccios Complementares
1

Altere o arquivo Home.cshtml para gerar a seguinte tela para o usurio:


www.k19.com.br

70

71

C AMADA DE A PRESENTAO

Figura 5.1: Inline Code

ViewBag e Strogly Typed Views


A ViewBag utilizada para transmitir dados da camada de controle para a camada de apresentao. Para adicionar um item propriedade ViewBag, devemos denir uma chave para esse item. Veja o cdigo abaixo.
1 ViewBag . HoraDoServidor = DateTime . Now . ToShortTimeString () ;
Cdigo C# 5.1: Adicionando um item na ViewBag

No cdigo acima, criamos uma chave chamada HoraDoServidor e atribumos um valor a essa chave. Na camada de apresentao, os itens armazenados na ViewBag podem ser acessados facilmente atravs da sintaxe da Razor. Veja um exemplo abaixo.
1 A hora do servidor @ViewBag . HoraDoServidor
Cdigo CSHTML 5.11: Acessando um item da ViewBag

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 adicionadas dinamicamente, no possvel garantir a existncia dessas chaves em tempo de compilao. Considere o cdigo abaixo.
www.k19.com.br

71

C AMADA DE A PRESENTAO
1 2 3 4 5 6 7 8 9 double numero = new Random () . NextDouble () ; if ( numero < .5) { ViewBag . X = " K19 TREINAMENTOS " ; } else { ViewBag . X = 1 ; }
Cdigo C# 5.2: Adcicionando chaves dinamicamente na ViewBag

72

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.
1 <p > @ViewBag . X . Lower () </ p >
Cdigo CSHTML 5.12: Utilizando a chave X ViewBag

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 suciente 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 refatorao no podem ser aplicados com o uso da ViewBag. Uma alternativa utilizao da ViewBag o recurso strongly typed views. Com esse recurso podemos xar, 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 xado, o compilador capaz de vericar 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 parmetro para o mtodo View() um objeto do tipo esperado pela camada de apresentao.
1 2 3 4 5 public ActionResult acao () { Editora editora = new Editora { Nome = " K19 " , Email = " contato@k19 . com . br " }; return View ( editora ) ; }
Cdigo C# 5.3: Passando um objeto para a camada de apresentao

Para denir o tipo do objeto esperado na camada de apresentao, podemos utilizar a sintaxe da Razor. Veja o cdigo abaixo.
1 @model K19 . Models . Editora
Cdigo CSHTML 5.13: Denindo o tipo do objeto esperado na camada de apresentao

Podemos tambm utilizar o comando using.


1 @using K19 . Models

72

www.k19.com.br

73
2 @model Editora
Cdigo CSHTML 5.14: Utilizando o comando using

C AMADA DE A PRESENTAO

Para acessar o objeto transmitido da camada de controle para a camada de apresentao, devemos utilizar a propriedade Model. Observe o cdigo a seguir.
1 2 3 4 5 6 7 8 @using K19 . Models @model Editora <p > Nome : @Model . Nome < br / > Email : @Model . Email </ p >
Cdigo CSHTML 5.15: Utilizando a propriedade Model

Se tentarmos acessar um mtodo ou propriedade inexistentes, um erro de compilao ocorrer, pois agora o compilador conhece o tipo do objeto transmitido. Dessa forma, o cdigo abaixo produz um erro de compilao.
1 2 3 4 5 6 7 8 @using K19 . Models @model Editora <p > Nome : @Model . Nome < br / > Telefone : @Model . Telefone </ p >
Cdigo CSHTML 5.16: Produzindo um erro de compilao

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 ambos os recursos podem ser utilizados ao mesmo tempo.

Exerccios de Fixao
3

Crie uma pgina que mostra a hora do servidor. No projeto K19, dena um controlador chamado

Teste vazio(empty) e uma ao chamada TestaViewBag. Essa ao deve armazenar o horrio atual na ViewBag.
1 2 3 4 5 6 7 8 9 1 11 12 13 14 using System ; using System . Web . Mvc ; namespace K19 . Controllers { public class TesteController : Controller { public ActionResult TestaViewBag () { ViewBag . Hora = DateTime . Now . ToShortTimeString () ; return View () ; } } }

www.k19.com.br

73

C AMADA DE A PRESENTAO

74

Cdigo C# 5.4: TesteController.cs

Crie uma pgina para exibir a hora atual do servidor. Para isto, crie o arquivo TestaViewBag.cshtml dentro de uma pasta chamada Views\Teste\.
4

1 2 3 4 5

@{ ViewBag . Title = " TestaViewBag " ; } < h2 > Hora do servidor : @ViewBag . Hora </ h2 >
Cdigo HTML 5.1: TestaViewBag.cshtml

Para testar, acesse: http://localhost:<PORTA_APP>/Teste/TestaViewBag.


5 Crie uma pgina para mostrar as informaes de um objeto da classe Editora. Este objeto dever ser acessado atravs da propriedade Model.

Altere o controlador Teste e acrescente a action TestaModel. Crie um objeto da classe Editora e passe-o como referncia para a View atravs da propriedade Model.
1 2 3 4 5 6 7 ... public ActionResult TestaModel () { Editora editora = new Editora { Nome = " K19 " , Email = " contato@k19 . com . br " }; return View ( editora ) ; } ...
Cdigo C# 5.5: Nova ao do controlador Teste

Crie o arquivo TestaModel.cshtml que mostrar as informaes do objeto da classe Editora na pasta Views\Teste do projeto K19.
1 2 3 4 5 6 7 8 9 1 11 @model K19 . Models . Editora @{ ViewBag . Title = " TestaModel " ; } <p > Nome : @Model . Nome < br / > Email : @Model . Email </ p >
Cdigo HTML 5.2: TestaModel.cshtml

Para ver o resultado, acesse a url http://localhost:<PORTA_APP>/Teste/TestaModel.

HTML Helpers
A funo das pginas CSHTML gerar hipertexto XHTML para enviar aos navegadores dos usurios. Os arquivos .cshtml misturam tags XHTML com scripts de servidor escritos em C# (ou outra
74
www.k19.com.br

75

C AMADA DE A PRESENTAO

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. Considere a criao de um link utilizando diretamente as tags HTML.
1 <a href = " / Editora / Index / " > Lista de editoras </ a >
Cdigo CSHTML 5.17: Link para a lista de editoras

Se o formato da url para acessar a ao Index do controlador Editora for alterado, o cdigo acima dever ser modicado. Veremos como o formato das urls pode ser congurado no Captulo 7. Para facilitar a manuteno do cdigo das pginas CSHTML, o ASP.NET MVC oferece os chamados 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 " )
Cdigo CSHTML 5.18: Criando um link para a listagem de editoras

Agora, se o formato da url para acessar a ao Index do controlador Editora for alterado, o cdigo 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 " )
Cdigo CSHTML 5.19: Criando um link com controlador implcito

Podemos denir o controlador desejado explicitamente. Para isso, necessrio passar um terceiro parmetro para o mtodo ActionLink.
1 @Html . ActionLink ( " TEXTO PARA O USURIO " , " ACTION " , " CONTROLADOR " )
Cdigo CSHTML 5.20: Criando um link com controlador explcito

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 =
Cdigo CSHTML 5.21: Acrescenta parmetros de url

, Final = 1

})

www.k19.com.br

75

C AMADA DE A PRESENTAO

76

BeginForm e EndForm Helpers


No ASP.NET MVC, h um conjunto de HTML Helpers para facilitar a criao de formulrios nas pginas de uma aplicao web. Para criar um formulrio, utilizamos o helper BeginForm. Para terminar um formulrio, utilizamos o helper EndForm. Veja o exemplo a seguir.
1 2 3 4 5 @ { Html . BeginForm () ;} <! -- elementos do formulrio -- > @ { Html . EndForm () ;}
Cdigo CSHTML 5.22: Utilizando os helpers BeginForm e 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.
1 2 3 4 5 @using ( Html . BeginForm () ) { <! -- elementos de formulrio -- > }
Cdigo CSHTML 5.23: Utilizando o comando using

Por padro, um formulrio criado com o helper BeginForm enviar requisies ao associada url atual. Contudo, podemos denir explicitamente uma outra ao para receber essas requisies. Veja um exemplo no cdigo abaixo.
1 2 3 4 5 @using ( Html . BeginForm ( " ACTION " , " CONTROLADOR " ) ) { <! -- elementos de formulrio -- > }
Cdigo CSHTML 5.24: Denindo uma ao e um controlador explicitamente

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.
1 2 3 4 5 6 7 8 9 1 public class K19Controller : Controller { // POST : / K19 / Home [ HttpPost ] public ActionResult Home () { ... return View () ; } }
Cdigo C# 5.6: Anotando uma ao com HttpPost

76

www.k19.com.br

77

C AMADA DE A PRESENTAO

CheckBox
Podemos adicionar um checkbox em um formulrio atravs do helper CheckBox.
1 @Html . CheckBox ( " Aceito " , false )
Cdigo CSHTML 5.25: Utilizando o helper CheckBox

O cdigo acima produz o seguinte trecho de cdigo HTML:


1 2 < input id = " Aceito " name = " Aceito " type = " checkbox " value = " true " / > < input name = " Aceito " type = " hidden " value = " false " / >
Cdigo HTML 5.3: HTML gerado pelo helper CheckBox

Considere o formulrio a seguir:


1 2 3 4 5 @using ( Html . BeginForm ( " Cadastra " , " Contrato " ) ) { @Html . CheckBox ( " Aceito " , false ) < input type = " submit " value = " Cadastra Contrato " / > }
Cdigo CSHTML 5.26: Formulrio

Agora, considere a ao associada ao formulrio criado no cdigo acima.


1 2 3 4 5 6 7 8 9 1 public class ContratoController : Controller { // POST : / Contrato / Cadastra [ HttpPost ] public ActionResult Cadastra ( Contrato contrato ) { ... return View () ; } }
Cdigo C# 5.7: Ao

O valor enviado atravs do checkbox inserido no formulrio ser armazenado na propriedade

Aceito do contrato enviado como parmetro para a ao Cadastra(). Dessa forma, a classe Contrato deve possuir uma propriedade booleana chamada Aceito.
1 2 3 4 public class Contrato { public Boolean Aceito { get ; set ; } }
Cdigo C# 5.8: Contrato.cs

TextBox
Uma caixa de texto pode ser adicionada atravs do helper TextBox.
1 @Html . TextBox ( " Nome " , " Digite o seu nome " )

www.k19.com.br

77

C AMADA DE A PRESENTAO

78

Cdigo CSHTML 5.27: Utilizando o helper TextBox

O cdigo acima produz o seguinte trecho de cdigo HTML:


1 < input id = " Nome " name = " Nome " type = " text " value = " Digite o seu nome " / >
Cdigo HTML 5.4: HTML gerado pelo helper TextBox

TextArea
Uma caixa para textos maiores pode ser adicionada atravs do helper TextArea.
1 @Html . TextArea ( " Mensagem " , " Digite uma mensagem " )
Cdigo CSHTML 5.28: Utilizando o helper TextArea

O cdigo acima produz o seguinte trecho de cdigo HTML:


1 < textarea cols = " 2 " id = " Mensagem " name = " Mensagem " rows = " 2 " > Digite uma mensagem </ textarea >
Cdigo HTML 5.5: HTML gerado pelo helper TextArea

RadioButton
Um boto do tipo radio pode ser adicionado atravs do helper RadioButton.
1 2 3 @Html . RadioButton ( " CidadeNatal " , " So Paulo " , true ) @Html . RadioButton ( " CidadeNatal " , " Natal " , false ) @Html . RadioButton ( " CidadeNatal " , " Piracicaba " , false )
Cdigo CSHTML 5.29: Utilizando o helper RadioButton

O cdigo acima produz o seguinte trecho de cdigo HTML:


1 2 3 < input checked = " checked " id = " CidadeNatal " name = " CidadeNatal " type = " radio " value = " So Paulo " / > < input id = " CidadeNatal " name = " CidadeNatal " type = " radio " value = " Natal " / > < input id = " CidadeNatal " name = " CidadeNatal " type = " radio " value = " Piracicaba " / >
Cdigo HTML 5.6: HTML gerado pelo helper RadioButton

Hidden
Um campo escondido pode ser adicionado atravs do helper Hidden.
1 @Html . Hidden ( " Id " , 1)
Cdigo CSHTML 5.30: Utilizando o helper Hidden

78

www.k19.com.br

79

C AMADA DE A PRESENTAO

O cdigo acima produz o seguinte trecho de cdigo HTML:


1 < input id = " Id " name = " Id " type = " hidden " value = " 1 " / >
Cdigo HTML 5.7: HTML gerado pelo helper Hidden

Password
Uma caixa para senha pode ser adicionada atravs do helper Password.
1 @Html . Password ( " Password " , " senha " )
Cdigo CSHTML 5.31: Utilizando o helper Password

O cdigo acima produz o seguinte trecho de cdigo HTML:


1 < input id = " Password " name = " Password " type = " password " value = " senha " / >
Cdigo HTML 5.8: HTML gerado pelo helper Password

Mais Sobre
Os dados preenchidos nos elementos de um formulrio so recuperados da ViewBag. Considere o cdigo abaixo:
1 @Html . TextBox ( " Nome " )
Cdigo CSHTML 5.32: Utilizando o helper TextBox

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.
1 @Html . TextBox ( " Nome " , " NomeInicial " )
Cdigo CSHTML 5.33: Utilizando o helper TextBox

Strongly Typed Views


Se os HTML Helpers forem utilizados de maneira anloga mostrada anteriormente, a probabilidade de ocorrer um erro de digitao alta. A forma que os HTML Helpers foram aplicados no permite que o compilador verique a existncia das propriedades associadas aos elementos dos formulrios. Por exemplo, considere o cdigo a seguir.
1 @Html . CheckBox ( " Aceito " , false )
Cdigo CSHTML 5.34: Utilizando o helper CheckBox

www.k19.com.br

79

C AMADA DE A PRESENTAO

80

O cdigo anterior supe que o objeto recebido como parmetro pela ao associada ao formulrio 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 tipadas:
1 2 3 4 @model K19 . Models . Contrato ... @Html . CheckBoxFor ( c = > c . Aceito ) ...
Cdigo CSHTML 5.35: Utilizando o helper CheckBoxFor

Com essa sintaxe, o compilador tem condies de vericar a existncia das propriedades. Sendo assim, ele produzir um erro de compilao se uma propriedade inexistente for utilizada.

TextBoxFor
1 2 3 4 @model K19 . Models . Empresa ... @Html . TextBoxFor ( x = > x . Nome ) ...
Cdigo CSHTML 5.36: Utilizando o helper TextBoxFor

O cdigo acima produz o seguinte trecho de cdigo HTML:


1 < input id = " Nome " name = " Nome " type = " text " value = " K19 Treinamentos " / >
Cdigo HTML 5.9: HTML gerado pelo helper TextBoxFor

TextAreaFor
1 2 3 4 @model K19 . Models . Empresa ... @Html . TextAreaFor ( x = > x . Descricao ) ...
Cdigo CSHTML 5.37: Utilizando o helper TextAreaFor

O cdigo acima produz o seguinte trecho de cdigo HTML:


1 2 3 < textarea cols = " 2 " id = " Descricao " name = " Descricao " rows = " 2 " > K19 Treinamentos em Java e . NET </ textarea >
Cdigo HTML 5.10: HTML gerado pelo helper TextAreaFor

RadioButtonFor
80
www.k19.com.br

81
1 2 3 4 5 6 @model K19 . Models . Pessoa ... @Html . RadioButtonFor ( x = > x . CidadeNatal , " So Paulo " ) @Html . RadioButtonFor ( x = > x . CidadeNatal , " Natal " ) @Html . RadioButtonFor ( x = > x . CidadeNatal , " Piracicaba " ) ...
Cdigo CSHTML 5.38: Utilizando o helper RadioButtonFor

C AMADA DE A PRESENTAO

O cdigo acima produz o seguinte trecho de cdigo HTML:


1 2 3 < input checked = " checked " id = " CidadeNatal " name = " CidadeNatal " type = " radio " value = " So Paulo " / > < input id = " CidadeNatal " name = " CidadeNatal " type = " radio " value = " Natal " / > < input id = " CidadeNatal " name = " CidadeNatal " type = " radio " value = " Piracicaba " / >
Cdigo HTML 5.11: HTML gerado pelo helper RadioButtonFor

HiddenFor
1 2 3 4 @model K19 . Models . Empresa ... @Html . HiddenFor ( e = > e . Id ) ...
Cdigo CSHTML 5.39: Utilizando o helper HiddenFor

O cdigo acima produz o seguinte trecho de cdigo HTML:


1 < input id = " Id " name = " Id " type = " hidden " value = " 1 " / >
Cdigo HTML 5.12: HTML gerado pelo helper HiddenFor

PasswordFor
1 2 3 4 @model K19 . Models . Usuario ... @Html . PasswordFor ( x = > x . Senha ) ...
Cdigo CSHTML 5.40: Utilizando o helper PasswordFor

O cdigo acima produz o seguinte trecho de cdigo HTML:


1 < input id = " Senha " name = " Senha " type = " password " / >
Cdigo HTML 5.13: HTML gerado pelo helper PasswordFor

Mais Sobre
Os dados preenchidos nos elementos de um formulrio de uma tela fortemente tipada so recuperados da propriedade Model. Considere o cdigo abaixo:

www.k19.com.br

81

C AMADA DE A PRESENTAO

82

1 2 3 4

@model K19 . Models . Pessoa ... @Html . TextBoxFor ( x = > x . Nome ) ...
Cdigo CSHTML 5.41: Utilizando o helper TextBoxFor

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.
1 2 3 4 5 6 7 8 9 public class LivroController : Controller { public ActionResult Create () { List < Editora > editoras = editoraRepository . BuscaTodas () ; ViewBag . Editoras = new SelectList ( editoras , " Id " ," Nome " ) ; return View () ; } }
Cdigo C# 5.9: LivroController.cs

O segundo passo adicionar o helper DropDownList na camada de apresentao.


1 @Html . DropDownList ( " Editoras " )
Cdigo CSHTML 5.42: Utilizando o helper DropDownList

EditorFor
Considere a seguinte entidade.
1 2 3 4 5 6 7 8 9 public class Editora { public int Id { get ; set ; } public string Nome { get ; set ; } public string Email { get ; set ; } public bool IsAtivo { get ; set ; } public string Descricao { get ; set ; } public virtual ICollection < Livro > Livros { get ; set ; } }
Cdigo C# 5.10: Editora.cs

82

www.k19.com.br

83

C AMADA DE A PRESENTAO

Para editar os dados de uma editora, temos uma pgina conforme o exemplo abaixo:
1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 @model K19 . Models . Editora @{ ViewBag . Title = " Edio de Editora " ; } < h2 > Edio de Editora </ h2 > @using ( Html . BeginForm () ) { @Html . HiddenFor ( model = > model . Id ) @Html . LabelFor ( model = > model . Nome ) @Html . TextBoxFor ( model = > model . Nome ) < br / > @Html . LabelFor ( model = > model . Email ) @Html . TextBoxFor ( model = > model . Email ) < br / > @Html . LabelFor ( model = > model . Descricao ) @Html . TextAreaFor ( model = > model . Descricao ) < br / > @Html . LabelFor ( model = > model . IsAtivo ) @Html . CheckBoxFor ( model = > model . IsAtivo ) < input type = " submit " value = " Salvar " / > }
Cdigo CSHTML 5.43: Edit.cshtml

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.
1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 @model K19 . Models . Editora @{ ViewBag . Title = " Edio de Editora " ; } < h2 > Edio de Editora </ h2 > @using ( Html . BeginForm () ) { @Html . HiddenFor ( model = > model . Id ) @Html . LabelFor ( model = > model . Nome ) @Html . EditorFor ( model = > model . Nome ) < br / > @Html . LabelFor ( model = > model . Email ) @Html . EditorFor ( model = > model . Email ) < br / >

www.k19.com.br

83

C AMADA DE A PRESENTAO
22 23 24 25 26 27 28 29 3 31 @Html . LabelFor ( model = > model . Descricao ) @Html . EditorFor ( model = > model . Descricao ) < br / > @Html . LabelFor ( model = > model . IsAtivo ) @Html . EditorFor ( model = > model . IsAtivo ) < input type = " submit " value = " Salvar " / > }
Cdigo CSHTML 5.44: Edit.cshtml

84

Para personalizar o funcionamento do helper EditorFor, podemos utilizar algumas anotaes na entidade Editora. Por exemplo, seria mais apropriado utilizar um TextAreaFor para editar a descrio de uma editora ao invs de um TextBoxFor. Contudo, como dito anteriormente, o helper EditorFor utilizar um TextBoxFor para a propriedade Descricao. Nesse caso, podemos aplicar a anotao MultilineText na propriedade Descricao.
1 2 3 4 5 6 7 8 9 1 public class Editora { public int Id { get ; set ; } public string Nome { get ; set ; } public string Email { get ; set ; } public bool IsAtivo { get ; set ; } [ MultilineText ] public string Descricao { get ; set ; } public virtual ICollection < Livro > Livros { get ; set ; } }
Cdigo C# 5.11: Editora.cs

Alm da anotao MultilineText, o ASP.NET MVC dene as seguintes anotaes para personalizar o helper EditorFor. Anotao Descrio Utiliza o Helper Hidden Utiliza o Helper Text Utiliza o Helper TextBox Utiliza o Helper Password Utiliza o Helper TextArea Utiliza o Helper CheckBox ou DropDownList para nullable boolean Utiliza o Helper TextBox e formata para duas casas decimais Percorre as propriedades do objeto e dene o Helper adequado para cada uma Percorre atravs do IEnumerable e dene o Helper para cada elemento

HiddenInput Text String Password MultilineText Boolean Decimal Object Collection

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.
1 2 3 @model K19 . Models . Editora @{

84

www.k19.com.br

85
4 5 6 7 8 9 1 11 12 13 ViewBag . Title = " Edio de Editora " ; } < h2 > Edio de Editora </ h2 > @using ( Html . BeginForm () ) { @Html . EditorForModel () < input type = " submit " value = " Save " / > }
Cdigo CSHTML 5.45: Edit.cshtml

C AMADA DE A PRESENTAO

Exerccios de Fixao
6 No projeto K19, dena uma pgina com um formulrio de cadastro de editoras. Os campos nome e email deste formulrio devem vir preenchidos com os valores dos atributos de um objeto da classe Editora. O nome e email devero ser acessados atravs da propriedade ViewBag.

Acrescente a ao TestaFormularioHtml no controlador Teste.


1 2 3 4 5 6 7 public ActionResult TestaFormularioHtml () { Editora e = new Editora { Nome = " K19 " , Email = " contato@k19 . com . br " }; ViewBag . Nome = e . Nome ; ViewBag . Email = e . Email ; return View () ; }
Cdigo C# 5.12: Action TestaFormularioHtml do TesteController

Crie a pgina TestaFormularioHtml.cshtml dentro da pasta Teste que ca na pasta Views.


1 2 3 4 5 6 7 8 9 1 11 12 13 @{ ViewBag . Title = " TestaFormularioHtml " ; } < h2 > Cadastro de Editora </ h2 > < form > < label for = " Nome " > Nome : </ label > < input id = " Nome " name = " Nome " value = " @ViewBag . Nome " / > < label for = " Email " > Email : </ label > < input id = " Email " name = " Email " value = " @ViewBag . Email " / > < input type = " submit " value = " Enviar " / > </ form >
Cdigo CSHTML 5.46: TestaFormularioHtml.cshtml

Para testar, acesse a url http://localhost:<PORTA_APP>/Teste/TestaFormularioHtml. Crie um formulrio de cadastro de editoras conforme o exerccio anterior, mas utilize Html Helpers. Altere o controlador Teste e acrescente a ao TestaHelpers.
7

1 2 3 4 5

public ActionResult TestaHelpers () { Editora editora = new Editora { Nome = " K19 " , Email = " contato@k19 . com . br " }; return View () ; }

www.k19.com.br

85

C AMADA DE A PRESENTAO

86

Cdigo C# 5.13: Ao TestaHelpers do TesteController

Crie a pgina TestaHelpers.cshtml dentro da pasta Teste que ca na pasta Views.


1 2 3 4 5 6 7 8 9 1 11 12 13 @{ @ViewBag . Title = " TestaHelpers " ; } < h2 > Cadastro de Editora usando Helpers </ h2 > @using ( Html . BeginForm () ) { @Html . Label ( " Nome " ) @Html . TextBox ( " Nome " ) @Html . Label ( " Email " ) @Html . TextBox ( " Email " ) < input type = " submit " value = " Enviar " / > }
Cdigo CSHTML 5.47: TestaHelpers.cshtml

Para testar, acesse acesse a url http://localhost:<PORTA_APP>/Teste/TestaHelpers.


8 Crie um novo formulrio de cadastro de editoras conforme o exerccio anterior, mas utilize HTML Helpers Strongly Typed. Altere o controlador Teste e acrescente a ao TestaHelpersTipados.

1 2 3 4 5

public ActionResult TestaHelpersTipados () { Editora editora = new Editora { Nome = " K19 " , Email = " contato@k19 . com . br " }; return View ( editora ) ; }
Cdigo C# 5.14: Action TestaHelpersTipados do TesteController

Crie a pgina TestaHelpersTipados.cshtml dentro da pasta Teste que ca na pasta Views.


1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 @model K19 . Models . Editora @{ @ViewBag . Title = " TestaHelpersTipados " ; } < h2 > Cadastro de editoras usando HTML Helpers Strongly Typed </ h2 > @using ( Html . BeginForm () ) { @Html . LabelFor ( x = > x . Nome ) @Html . TextBoxFor ( x = > x . Nome ) @Html . LabelFor ( x = > x . Email ) @Html . TextBoxFor ( x = > x . Email ) < input type = " submit " value = " Enviar " / > }
Cdigo CSHTML 5.48: TestaHelpersTipados.cshtml

Para testar, acesse a url http://localhost:<PORTA_APP>/Teste/TestaHelpersTipados. Conforme os exerccios anteriores, crie um formulrio de cadastro de editoras utilizando o HTML Helper EditorFor. Altere o controlador Teste e acrescente a seguinte ao.
9

1 2

public ActionResult TestaEditorFor () {

86

www.k19.com.br

87
3 4 5

C AMADA DE A PRESENTAO
Editora editora = new Editora { Nome = " K19 " , Email = " contato@k19 . com . br " }; return View ( editora ) ; }
Cdigo C# 5.15: Ao TestaEditorFor do TesteController

Crie a pgina TestaEditorFor.cshtml dentro da pasta Teste que ca na pasta Views.


1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 @model K19 . Models . Editora @{ ViewBag . Title = " TestaEditorFor " ; } < h2 > Cadastro de editoras usando EditorFor </ h2 > @using ( Html . BeginForm () ) { @Html . LabelFor ( x = > x . Nome ) @Html . EditorFor ( x = > x . Nome ) @Html . LabelFor ( x = > x . Email ) @Html . EditorFor ( x = > x . Email ) < input type = " submit " value = " Enviar " / > }
Cdigo HTML 5.14: TestaEditorFor.cshtml

Para testar, acesse a url http://localhost:<PORTA_APP>/Teste/TestaEditorFor.

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 modicados. 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 denido em um Layout. Dessa forma, qualquer alterao facilmente realizada modicando-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 dene a formatao padro.
1 2 3 4 5 6 7 8 9 1 11 12 <! DOCTYPE html > < html > < head > < title > @ViewBag . Title </ title > @Styles . Render ( " ~/ Content / Site . css " ) @Scripts . Render ( " ~/ Scripts / jquery -1.5.1. min . js " ) </ head > < body > < div id = " header " > @Html . ActionLink ( " Editoras " , " Index " , " Editora " ) @Html . ActionLink ( " Livros " , " Index " ," Livro " )

www.k19.com.br

87

C AMADA DE A PRESENTAO
13 14 15 16 </ div > @RenderBody () </ body > </ html >
Cdigo CSHTML 5.49: K19Layout.cshtml

88

No layout denido 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 denir o seu prprio ttulo. Por m, o mtodo RenderBody() indica onde o contedo denido em cada pgina ser adicionado. recomendado que os arquivos que denam 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 carregar 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 dicultaria 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 5.50: Utilizando o mtodo Render para adicionar contedo CSS

Analogamente, a propriedade Scripts possui o mtodo Render(), que tambm tem por objetivo agrupar o cdigo JavaScript de diversos arquivos.

Com o layout denido, o prximo passo indicar quais pginas utilizaro esse layout. Por exemplo, podemos atualizar a pgina de edio de editoras para utilizar K19Layout.cshtml como layout.
1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 @model K19 . Models . Editora @{ Layout = " ~/ Views / Shared / K19Layout . cshtml " ; // Define o ttulo especfico desta pgina ViewBag . Title = " Edio de Editora " ; } < h2 > Edio de Editora </ h2 > @using ( Html . BeginForm () ) { @Html . EditorForModel () < input type = " submit " value = " Salvar " / > }
Cdigo CSHTML 5.51: Edit.cshtml

Quando a pgina de edio de editoras requisitada, o arquivo Edit.cshtml processado antes do arquivo K19Layout.cshtml, o que permite denir o valor de ViewBag.Title no arquivo Edit.cshtml
88
www.k19.com.br

89

C AMADA DE A PRESENTAO

e utiliz-lo no layout. Para denir o layout de Edit.cshtml, foi necessrio armazenar o caminho completo do arquivo que dene o layout na propriedade Layout. Este procedimento no muito prtico, pois em cada pgina que deseja utilizar esse layout necessrio denir esta propriedade. A partir da terceira verso do ASP .NET MVC, temos uma nova funcionalidade que permite denir um layout padro para todas as pginas, no havendo necessidade de denir a propriedade Layout em cada pgina. Para isso, basta acrescentarmos o arquivo _ViewStart.cshtml pasta View:

O _ViewStart.cshtml permite denirmos um cdigo que ser executado antes de cada pgina ser renderizada. Nesse arquivo podemos denir, por exemplo, a propriedade Layout:
1 2 3 @{ Layout = " ~/ Views / Shared / K19Layout . cshtml " ; }
Cdigo CSHTML 5.52: _ViewStart.cshtml

Como este cdigo processado antes dos arquivos especcos de cada pgina, no h mais necessidade de denir a propriedade Layout em cada arquivo especco.

Lacunas
Tambm podemos criar sees em um layout para serem preenchidas com contedos especcos denidos nas pginas. Considere o seguinte layout.
1 <! DOCTYPE html >

www.k19.com.br

89

C AMADA DE A PRESENTAO
2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 < html > < head > < title > @ViewBag . Title </ title > @Styles . Render ( " ~/ Content / Site . css " ) @Scripts . Render ( " ~/ Scripts / jquery -1.5.1. min . js " ) </ head > < body > < div id = " header " > @Html . ActionLink ( " Editoras " , " Index " , " Editora " ) @Html . ActionLink ( " Livros " , " Index " ," Livro " ) </ div > < div id = " sidebar " > @RenderSection ( " Sidebar " , false ) </ div > < div id = " content " > @RenderBody () </ div > < div id = " footer " > K19 Treinamentos </ div > </ body > </ html >
Cdigo CSHTML 5.53: K19Layout.cshtml

90

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 preenchimento dessa seo obrigatrio ou no. Para denir o contedo de uma seo, devemos utilizar o cdigo @section. Observe o cdigo de uma pgina que utiliza o layout criado anteriormente e dene a seo Sidebar.
1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 @model K19 . Models . Editora @{ Layout = " ~/ Views / Shared / K19Layout . cshtml " ; // Define o ttulo especfico desta pgina ViewBag . Title = " Edio de Editora " ; } < h2 > Edio de Editora </ h2 > @using ( Html . BeginForm () ) { @Html . EditorForModel () < input type = " submit " value = " Salvar " / > } @section Sidebar { <p > Sidebar do cadastro de Edio de Editora </ p > }
Cdigo CSHTML 5.54: Edit.cshtml

Exerccios de Fixao
Crie um arquivo chamado K19Layout.cshtml dentro da pasta Shared que ca na pasta Views do projeto K19. Este arquivo servir de modelo para as pginas da nossa aplicao.
10

1 2 3 4 5 6 7

<! DOCTYPE html > < html > < head > < meta charset = " utf -8 " / > < meta name = " viewport " content = " width = device - width " / > < title > @ViewBag . Title </ title > @Styles . Render ( " ~/ Content / themes / base / css " , " ~/ Content / css " )

90

www.k19.com.br

91
8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 @Scripts . Render ( " ~/ bundles / modernizr " ) </ head > < body > < div id = " header " > @Html . ActionLink ( " Editoras " , " Index " , " Editora " )

C AMADA DE A PRESENTAO

@Html . ActionLink ( " Testa Formulario Html " , " TestaFormularioHtml " ," Teste " ) @Html . ActionLink ( " Testa Helpers " , " TestaHelpers " ," Teste " ) @Html . ActionLink ( " Testa Helpers Tipados " , " TestaHelpersTipados " ," Teste " ) @Html . ActionLink ( " Testa EditorFor " , " TestaEditorFor " ," Teste " ) </ div > @RenderBody () @Scripts . Render ( " ~/ bundles / jquery " ) @RenderSection ( " scripts " , required : false ) </ body > </ html >
Cdigo CSHTML 5.55: K19Layout.cshtml

11 Altere a pgina TestaFormularioHtml.cshtml para utilizar a pgina de layout denida no exerccio anterior.

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18

@{ ViewBag . Title = " TestaFormularioHtml " ; } @{ Layout = " ~/ Views / Shared / K19Layout . cshtml " ; } < h2 > Cadastro de Editora </ h2 > < form > < label for = " Nome " > Nome : </ label > < input id = " Nome " name = " Nome " value = " @ViewBag . Nome " / > < label for = " Email " > Email : </ label > < input id = " Email " name = " Email " value = " @ViewBag . Email " / > < input type = " submit " value = " Enviar " / > </ form >
Cdigo HTML 5.15: TestaFormularioHtml.cshtml

Teste acessando o endereo: http://localhost:<PORTA_APP>/Teste/TestaFormularioHtml.


12 Dena a pgina K19Layout.cshtml como layout padro para todas as telas. Altere o arquivo _ViewStart.cshtml da pasta Views.

1 2 3

@{ Layout = " ~/ Views / Shared / K19Layout . cshtml " ; }


Cdigo CSHTML 5.56: _ViewStart.cshtml

Teste acessando http://localhost:<PORTA_APP>/Teste/TestaFormularioHtml e navegando pelos links. Dena sees no layout K19Layout.cshtml. Primeiramente, acrescente ao arquivo Site.css da pasta Content o trecho de cdigo a seguir:
13

www.k19.com.br

91

C AMADA DE A PRESENTAO
1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 # sidebar { float : right ; margin :1 px ; padding :1 px ; border : dotted 5 px red ; width :18 px ; } # footer { text - align : center ; clear : both ; } # content { float : left ; margin :1 px ; } ...
Cdigo CSS 5.1: Site.css

92

Finalmente, altere o arquivo K19Layout.cshtml da pasta Views\Shared.


1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 <! DOCTYPE html > < html > < head > < meta charset = " utf -8 " / > < meta name = " viewport " content = " width = device - width " / > < title > @ViewBag . Title </ title > @Styles . Render ( " ~/ Content / themes / base / css " , " ~/ Content / css " ) @Scripts . Render ( " ~/ bundles / modernizr " ) </ head > < body > < div id = " header " > @Html . ActionLink ( " Editoras " , " Index " , " Editora " ) @Html . ActionLink ( " Testa Formulario Html " , " TestaFormularioHtml " ," Teste " ) @Html . ActionLink ( " Testa Helpers " , " TestaHelpers " ," Teste " ) @Html . ActionLink ( " Testa Helpers Tipados " , " TestaHelpersTipados " ," Teste " ) @Html . ActionLink ( " Testa EditorFor " , " TestaEditorFor " ," Teste " ) </ div > < div id = " sidebar " > SideBar Padro </ div > < div id = " content " > @RenderBody () </ div > < div id = " footer " > K19 Treinamentos </ div > @Scripts . Render ( " ~/ bundles / jquery " ) @RenderSection ( " scripts " , required : false ) </ body > </ html >
Cdigo CSHTML 5.57: K19Layout.cshtml

Teste acessando http://localhost:<PORTA_APP>/Editora e navegando pelos links..


14

Acrescente uma seo ao layout K19Layout.cshtml.


<! DOCTYPE html > < html > < head > < meta charset = " utf -8 " / > < meta name = " viewport " content = " width = device - width " / >

1 2 3 4 5

92

www.k19.com.br

93
6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28

C AMADA DE A PRESENTAO
< title > @ViewBag . Title </ title > @Styles . Render ( " ~/ Content / themes / base / css " , " ~/ Content / css " ) @Scripts . Render ( " ~/ bundles / modernizr " ) </ head > < body > < div id = " header " > @Html . ActionLink ( " Editoras " , " Index " , " Editora " ) @Html . ActionLink ( " Testa Formulario Html " , " TestaFormularioHtml " ," Teste " ) @Html . ActionLink ( " Testa Helpers " , " TestaHelpers " ," Teste " ) @Html . ActionLink ( " Testa Helpers Tipados " , " TestaHelpersTipados " ," Teste " ) @Html . ActionLink ( " Testa EditorFor " , " TestaEditorFor " ," Teste " ) </ div > < div id = " sidebar " > @RenderSection ( " Sidebar " , required : false ) </ div > < div id = " content " > @RenderBody () </ div > < div id = " footer " > K19 Treinamentos </ div > @Scripts . Render ( " ~/ bundles / jquery " ) @RenderSection ( " scripts " , required : false ) </ body > </ html >
Cdigo CSHTML 5.58: K19Layout.cshtml

15

Dena na pgina TestaFormularioHtml.cshtml a seo Sidebar.


@{ ViewBag . Title = " TestaFormularioHtml " ; } @{ Layout = " ~/ Views / Shared / K19Layout . cshtml " ; } < h2 > Cadastro de Editora </ h2 > < form > < label for = " Nome " > Nome : </ label > < input id = " Nome " name = " Nome " value = " @ViewBag . Nome " / > < label for = " Email " > Email : </ label > < input id = " Email " name = " Email " value = " @ViewBag . Email " / > < input type = " submit " value = " Enviar " / > </ form > @section Sidebar { <p > Sidebar do TestaFormularioHtml </ p > }
Cdigo CSHTML 5.59: TestaFormularioHtml.cshtml

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22

Para testar, acesse http://localhost:<PORTA_APP>/Teste/TestaFormularioHtml e navegue pelos links..


16

Acrescente uma seo padro que ser utilizada nas pginas que no deniram a seo Side-

bar.
1 2 3 4 5 6 7 <! DOCTYPE html > < html > < head > < meta charset = " utf -8 " / > < meta name = " viewport " content = " width = device - width " / > < title > @ViewBag . Title </ title > @Styles . Render ( " ~/ Content / themes / base / css " , " ~/ Content / css " )

www.k19.com.br

93

C AMADA DE A PRESENTAO
8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 @Scripts . Render ( " ~/ bundles / modernizr " ) </ head > < body > < div id = " header " > @Html . ActionLink ( " Editoras " , " Index " , " Editora " ) @Html . ActionLink ( " Testa Formulario Html " , " TestaFormularioHtml " ," Teste " ) @Html . ActionLink ( " Testa Helpers " , " TestaHelpers " ," Teste " ) @Html . ActionLink ( " Testa Helpers Tipados " , " TestaHelpersTipados " ," Teste " ) @Html . ActionLink ( " Testa EditorFor " , " TestaEditorFor " ," Teste " ) </ div > @if ( IsSectionDefined ( " Sidebar " ) ) { < div id = " sidebar " > @RenderSection ( " Sidebar " , required : false ) </ div > } else { < div id = " sidebar " > Sidebar padro </ div > } < div id = " content " > @RenderBody () </ div > < div id = " footer " > K19 Treinamentos </ div > @Scripts . Render ( " ~/ bundles / jquery " ) @RenderSection ( " scripts " , required : false ) </ body > </ html >
Cdigo CSHTML 5.60: K19Layout.cshtml

94

Para testar, acesse http://localhost:<PORTA_APP>/Editora e navegue pelos links..

Partial views
Quanto mais elaborada uma pgina de uma aplicao web, mais extenso o seu cdigo. Cdigos 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.
1 2 < h1 > Parte 1 </ h > <p > Contedo da parte1 </ p >
Cdigo CSHTML 5.61: _Parte1.cshtml

1 2

< h1 > Parte 2 </ h > <p > Contedo da parte2 </ p >
Cdigo CSHTML 5.62: _Parte2.cshtml

Mais Sobre
Por conveno, o nome dos arquivos que denem as telas parciais de uma aplicao ASP .NET MVC devem iniciar com o caractere _.

94

www.k19.com.br

95

C AMADA DE A PRESENTAO

Por m, devemos criar um arquivo principal para agrupar essas partes. Utilizaremos o mtodo Partial() para inserir o contedo dos arquivos secundrios no arquivo principal.
1 2 3 4 5 6 7 8 9 1 < html > < head > < title > Exemplo de partial </ title > </ head > < body > Html . Partial ( " _Parte1 " ) Html . Partial ( " _Parte2 " ) </ body > </ html >
Cdigo CSHTML 5.63: Principal.cshtml

O mtodo Partial() procura os arquivos _Parte1.cshtml e _Parte2.cshtml no mesmo diretrio do arquivo principal. Caso ele no encontre, ele continua procurando esses arquivos na pasta Views\Shared. Essa lgica tambm aplicada no mtodo View que utilizamos na camada de controle. 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 atravs da propriedade ViewBag. Por exemplo, podemos denir 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 editoras.
1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 <! -- ~/ Views / Editora / _Form . cshtml -- > @model K19 . Models . Editora @Scripts . Render ( " ~/ Scripts / jquery -1.5.1. min . js " , " ~/ Scripts / jquery . validate . min . js " , " ~/ Scripts / jquery . validate . unobtrusive . min . js " ) @using ( Html . BeginForm () ) { @Html . ValidationSummary ( true ) < fieldset > < legend > Editora </ legend > @if ( Model != null ) { @Html . EditorFor ( model = > model . Id ) } < div class = " editor - label " > @Html . LabelFor ( model = > model . Nome ) </ div > < div class = " editor - field " > @Html . EditorFor ( model = > model . Nome ) </ div > < div class = " editor - label " > @Html . LabelFor ( model = > model . Email ) </ div > < div class = " editor - field " > @Html . EditorFor ( model = > model . Email ) </ div > < div class = " editor - label " > @Html . LabelFor ( model = > model . IsAtivo )

www.k19.com.br

95

C AMADA DE A PRESENTAO
34 35 36 37 38 39 4 41 42 43 </ div > < div class = " editor - field " > @Html . EditorFor ( model = > model . IsAtivo ) </ div > <p > < input type = " submit " value = " Save " / > </ p > </ fieldset > }
Cdigo CSHTML 5.64: _Form.cshtml

96

Veja abaixo o exemplo das pginas principais que utilizam a pgina parcial denida no cdigo acima.
1 2 3 4 5 6 7 8 9 1 <! -- ~/ Views / Editora / Create . cshtml -- > @model K19 . Models . Editora @{ ViewBag . Title = " Cadastro de Editora " ; } < h2 > Cadastro de Editora </ h2 > @Html . Partial ( " _Form " )
Cdigo CSHTML 5.65: Create.cshtml

1 2 3 4 5 6 7 8 9 1

<! -- ~/ Views / Editora / Edit . cshtml -- > @model LivrariaVirtual . Models . Editora @{ ViewBag . Title = " Edio de Editora " ; } < h2 > Edio de Editora </ h2 > @Html . Partial ( " _Form " )
Cdigo CSHTML 5.66: Edit.cshtml

Exerccios de Fixao
17

Crie uma pgina principal composta por outras pginas parciais. Para isto, altere o controlador

Teste do projeto K19 e acrescente a ao chamada TestaPartial.


1 2 3 4 5 6 ... public ActionResult TestaPartial () { return View () ; } ...
Cdigo C# 5.16: Nova ao TestaPartial do controlador Teste

Dena duas pginas parciais. Crie os arquivos _Parcial1.cshtml e _Parcial2.cshtml na pasta Teste que ca na pasta Views do projeto K19.
18

96

www.k19.com.br

97
1 < h2 > Parcial1 </ h2 >
Cdigo CSHTML 5.67: _Parcial1.cshtml

C AMADA DE A PRESENTAO

< h2 > Parcial2 </ h2 >


Cdigo CSHTML 5.68: _Parcial2.cshtml

Crie uma pgina principal chamada TestaPartial.cshtml na pasta Teste que ca na pasta Views do projeto K19 e adicione as duas pginas parciais criadas anteriormente.
19

1 2 3 4 5 6 7 8

@{ ViewBag . Title = " TestaPartial " ; } < h2 > Testando Partial </ h2 > @Html . Partial ( " _Parcial1 " ) @Html . Partial ( " _Parcial2 " )
Cdigo CSHTML 5.69: TestaPartial.cshtml

Para testar, acesse http://localhost:<PORTA_APP>/Teste/TestaPartial

www.k19.com.br

97

C AMADA DE A PRESENTAO

98

98

www.k19.com.br

CAPTULO

C AMADA DE C ONTROLE

No ASP.NET MVC as urls so mapeadas para mtodos (aes) em classes que denem os chamadas controladores. As requisies enviadas pelos navegadores so processadas pelos controladores. O processamento realizado por um controlador para tratar uma requisio consiste basicamente em:

Recuperar os dados enviados pelo usurio atravs de formulrios. Interagir com a camada de modelo. 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.

O nome da classe deve ter o suxo Controller. A classe deve implementar a interface System.Web.Mvc.IController ou herdar da classe System.Web.Mvc.Controller.

Raramente, voc denir uma classe para criar um controlador implementando a interface IController. Comumente as classes que denem um controlador derivam de Controller. Diversas propriedade e mtodos so herdados da classe Controller. Essas propriedades facilitam o processamento das requisies e a utilizao dos recursos do ASP.NET MVC.

Actions
Os controladores e as aes so elementos fundamentais de uma aplicao ASP.NET MVC. Um controlador pode conter diversas aes. As aes so utilizadas para processar as requisies realizadas pelos navegadores. Para criar uma ao, necessrio denir um mtodo public dentro da classe de um controlador. Os parmetros desse mtodo podem ser utilizados para receber os dados enviados pelos usurios atravs de formulrios HTML. Esse mtodo deve devolver um ActionResult que ser utilizado pelo ASP .NET MVC para denir o que deve ser executado depois que a ao terminar. Quando um usurio faz uma requisio HTTP atravs de um navegador, o ASP.NET MVC verica na tabela de rotas o controlador e a ao associados url da requisio realizada. Essa tabela denida no arquivo RouteConfig.cs e inicializada no arquivo Global.asax. Por padro, quando criamos um projeto ASP.NET MVC no Visual Web Developer, uma rota com o formato {controller}/{action}/{id} adicionada na tabela de rotas. Com essa rota, se uma
www.k19.com.br

99

C AMADA DE C ONTROLE

100

requisio for realizada para a url http://www.k19.com.br/Editora/Listagem, o controlador denido pela classe EditoraController e a ao implementada pelo mtodo Listagem() dessa classe sero escolhidos para processar essa requisio. Se uma requisio for realizada para a url http://www.k19.com.br/Editora/Remove/1, o controlador denido pela classe EditoraController e a ao implementada pelo mtodo Remove() dessa classe sero escolhidos para processar a requisio realizada. Alm disso, o valor 1 ser passado como parmetro para o mtodo Remove(). Veremos mais sobre rotas no Captulo 7.

ActionResult
Quando uma ao termina, o mtodo correspondente deve devolver um ActionResult. O valor devolvido indica para o ASP .NET MVC o que deve ser executado depois da ao. Veja abaixo uma lista com alguns tipos especcos de ActionResult que podem ser utilizados.

ViewResult: Devolve uma pgina da camada de apresentao. Considere o seguinte exemplo.


1 2 3 4 5 6 7 public class TesteController { public ActionResult Acao () { return View () ; } }

Considerando uma aplicao ASP .NET MVC 4 em C# e Razor, o mtodo View(), ao ser chamado sem parmetros, executar o seguinte processo para determinar qual arquivo deve ser utilizado para construir a pgina de resposta. 1. Se o arquivo Views\Teste\Acao.cshtml existir, ele ser utilizado. 2. Caso contrrio, se o arquivo Views\Shared\Acao.cshtml existir, ele ser utilizado. 3. Se nenhum desses arquivos existir, uma pgina de erro ser devolvida.

Por outro lado, podemos especicar o nome do arquivo que dene a pgina de resposta. Veja o exemplo abaixo.
1 return View ( " NomeDaView " ) ;

Alm disso, podemos passar um objeto para a camada de apresentao. Esse objeto ser utilizado nas pginas fortemente tipadas como vimos no Captulo 5.
1 return View ( editora ) ;

Tambm possvel especicar o nome do arquivo que dene a pgina de resposta e o objeto que deve ser transmitido para a camada de apresentao ao mesmo tempo.
1 return View ( " NomeDaView " , editora ) ;

PartialViewResult: Devolve uma pgina parcial da camada de apresentao. Exemplos:


100
www.k19.com.br

101
1 return PartialView () ;

C AMADA DE C ONTROLE

O mtodo PartialView() utiliza a mesma abordagem do mtodo View() para determinar o arquivo que deve ser utilizado para construir a pgina parcial de resposta.
1 return PartialView ( " NomeDaPartialView " , editora ) ;

RedirectResult: Redireciona o navegador para uma URL especca. Exemplo:


1 return Redirect ( " http :// www . k19 . com . br " ) ;

RedirectToAction: Redireciona para outra ao da camada de controle. Exemplo:


1 return RedirectToAction ( " OutraAction " , " OutroController " ) ;

ContentResult: Devolve texto. Exemplo:


1 return Content ( " Texto " ," text \ plain " ) ;

JsonResult: Devolve um objeto no formato JSON. Exemplo:


1 return Json ( editora ) ;

JavaScriptResult: Devolve cdigo Javascript. Exemplo:


1 return JavaScript ( " \ $ ( \# divResultText ) . html ( JavaScript Passed ) ; " ) ;

FileResult: Devolve dados binrios. Exemplo:


1 return File ( @ " c :\ relatorio . pdf " , " application \ pdf " ) ;

EmptyResult: Devolve uma resposta vazia. Exemplo:


1 return new EmptyResult () ;

Parmetros
Os parmetros enviados pelos usurios atravs de formulrios HTML podem ser recuperados por meio da propriedade Request.
1 string nome = Request [ " Nome " ];
Cdigo C# 6.14: Recuperando o parmetro Nome enviado em uma requisio HTTP

Esses parmetros tambm podem ser recuperados atravs dos parmetros da ao responsvel pelo processamento da requisio HTTP realizada. Para isso, basta denir um parmetro C# para cada parmetro HTTP com o mesmo nome. Veja o exemplo abaixo:
www.k19.com.br

101

C AMADA DE C ONTROLE
1 2 3 4 5 6 7 8 9 1 11 12 < html > < head > < title > Cadastro de Editora </ title > </ head > < body > < form action = " / Editoras / Salva " method = " post " > Nome : < input type = " text " name = " nome " / > Email : < input type = " text " name = " email " / > < input type = " submit " / > </ form > </ body > </ html >
Cdigo CSHTML 6.1: Cadastra.csthml

102

No cdigo acima, criamos um formulrio HTML com os parmetros nome e email. Esses parmetros sero recuperados na ao Salva denida no cdigo abaixo.
1 2 3 4 5 6 7 8 9 ... [ HttpPost ] public ActionResult Salva ( string nome , string email ) { Editora editora = new Editora { Nome = nome , Email = email }; db . Editoras . Add ( editora ) ; return View () ; } ...
Cdigo C# 6.15: EditoraController.cs

O ASP.NET MVC tambm capaz de montar objetos com os valores dos parmetros HTTP enviados pelo usurio e pass-los como argumento para as aes dos controladores.
1 2 3 4 5 6 [ HttpPost ] public ActionResult Salva ( Editora editora ) { db . Editoras . Add ( editora ) ; return View () ; }
Cdigo C# 6.16: EditoraController.cs

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
Adicione no controlador Editora do projeto K19 uma ao para visualizar o formulrio de cadastro de editoras.
1

1 2 3 4 5 6

... public ActionResult Cadastra () { return View () ; } ...


Cdigo C# 6.17: EditoraController.cs

102

www.k19.com.br

103
2

C AMADA DE C ONTROLE

Crie arquivo chamado Cadastra.cshtml na pasta Views\Editora. Nesse arquivo implemente um formulrio para cadastrar de editoras.
1 2 3 4 5 6 7 8 9 1 @{ ViewBag . Title = " Cadastra " ; } < h2 > Cadastro de Editoras </ h2 > < form action = " / Editora / Salva " > Nome : < input name = " Nome " / > Email : < input name = " Email " / > < input type = " submit " value = " Enviar " / > </ form >
Cdigo CSHTML 6.2: Cadastra.cshtml

Dena uma ao para salvar editoras no controlador Editora. Essa ao receber os dados enviados pelo usurio e adicionar uma editora ao banco de dados. Para receber os dados, utilize a propriedade Request.
3

1 2 3 4 5 6 7 8 9

... public ActionResult Salva () { Editora editora = new Editora { Nome = Request [ " Nome " ] , Email = Request [ " Email " ] }; db . Editoras . Add ( editora ) ; db . SaveChanges () ; return RedirectToAction ( " Index " ) ; } ...
Cdigo C# 6.18: EditoraController.cs

Para testar, cadastre uma editora acessando a url http://localhost:<PORTA_APP>/Editora/

Cadastra
Altere ao criada anteriormente para receber os dados do usurio atravs do parmetro do mtodo.
4

1 2 3 4 5 6 7 8 9

... public ActionResult Salva ( string nome , string email ) { Editora editora = new Editora { Nome = nome , Email = email }; db . Editoras . Add ( editora ) ; db . SaveChanges () ; return RedirectToAction ( " Index " ) ; } ...
Cdigo C# 6.19: EditoraController.cs

Para testar, acesse a url http://localhost:<PORTA_APP>/Editora/Cadastra Altere novamente a ao criada anteriormente. Agora, ela deve receber uma editora completa como parmetro.
5

1 2 3 4 5 6 7

... public ActionResult Salva ( Editora editora ) { db . Editoras . Add ( editora ) ; db . SaveChanges () ; return RedirectToAction ( " Index " ) ; }

www.k19.com.br

103

C AMADA DE C ONTROLE
8 ...
Cdigo C# 6.20: EditoraController.cs

104

Para testar, acesse a url http://localhost:<PORTA_APP>/Editora/Cadastra

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 propriedade 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 3 4 5 6 7 8 9 1 ... [ HttpPost ] public ActionResult Salva ( Editora editora ) { db . Editoras . Add ( editora ) ; db . SaveChanges () ; TempData [ " Mensagem " ] = " Editora cadastrada com sucesso ! " ; return RedirectToAction ( " Index " ) ; } ...
Cdigo C# 6.21: EditoraController.cs

Na camada de apresentao, podemos recuperar os dados armazenados na propriedade TempData. Veja o cdigo a seguir:
1 2 3 4 @if ( TempData [ " Mensagem " ] != null ) { <p > @TempData [ " Mensagem " ] </ p > }
Cdigo CSHTML 6.3: Recuperando dados armazenados na propriedade TempData

Exerccios de Fixao
6 Ao adicionar uma editora, o usurio redirecionado para a ao de listagem de editoras. Mostre uma mensagem na pgina de listagem para indicar que a operao foi realizada com sucesso. Inicialmente, tente armazenar essa mensagem na ViewBag.

1 2 3 4 5 6 7 8

... public ActionResult Salva ( Editora editora ) { db . Editoras . Add ( editora ) ; db . SaveChanges () ; ViewBag . Mensagem = " Editora cadastrada com sucesso ! " ; return RedirectToAction ( " Index " ) ; }

104

www.k19.com.br

105
9 ...
Cdigo C# 6.22: EditoraController.cs

C AMADA DE C ONTROLE

Altere o arquivo Index.cshtml da pasta Views\Editora para mostrar a mensagem armazena na

ViewBag.
1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 @model IEnumerable < K19 . Models . Editora > @{ ViewBag . Title = " Index " ; } < h2 > Index </ h2 > @if ( ViewBag . Mensagem != null ) { < h2 > Mensagem : @ViewBag . Mensagem </ h2 > } <p > @Html . ActionLink ( " Create New " , " Create " ) </ p > < table > < tr > < th > @Html . DisplayNameFor ( model = > model . Nome ) </ th > < th > @Html . DisplayNameFor ( model = > model . Email ) </ th > < th > </ th > </ tr > @foreach ( var item in Model ) { < tr > < td > @Html . DisplayFor ( modelItem = > item . Nome ) </ td > < td > @Html . DisplayFor ( modelItem = > item . Email ) </ td > < td > @Html . ActionLink ( " Edit " , " Edit " , new { id = item . Id }) | @Html . ActionLink ( " Details " , " Details " , new { id = item . Id }) | @Html . ActionLink ( " Delete " , " Delete " , new { id = item . Id }) </ td > </ tr > } </ table >
Cdigo CSHTML 6.4: Index.cshtml

Teste a mensagem cadastrando uma editora atravs da url http://localhost:<PORTA_APP>/Editora/ Cadastra. Verique que a mensagem de sucesso no aparecer.
8

Armazene a mensagem de sucesso na propriedade TempData ao invs da ViewBag.


... public ActionResult Salva ( Editora editora ) { db . Editoras . Add ( editora ) ; db . SaveChanges () ; TempData [ " Mensagem " ] = " Editora cadastrada com sucesso ! " ; return RedirectToAction ( " Index " ) ; }

1 2 3 4 5 6 7 8

www.k19.com.br

105

C AMADA DE C ONTROLE
9 ...
Cdigo C# 6.23: EditoraController.cs

106

Recupere a mensagem de sucesso da propriedade TempData ou invs da ViewBag.


@model IEnumerable < K19 . Models . Editora > @{ ViewBag . Title = " Index " ; } < h2 > Index </ h2 > @if ( TempData [ " Mensagem " ] != null ) { < h2 > Mensagem : @TempData [ " Mensagem " ] </ h2 > } <p > @Html . ActionLink ( " Create New " , " Create " ) </ p > < table > < tr > < th > @Html . DisplayNameFor ( model = > model . Nome ) </ th > < th > @Html . DisplayNameFor ( model = > model . Email ) </ th > < th > </ th > </ tr > @foreach ( var item in Model ) { < tr > < td > @Html . DisplayFor ( modelItem = > item . Nome ) </ td > < td > @Html . DisplayFor ( modelItem = > item . Email ) </ td > < td > @Html . ActionLink ( " Edit " , " Edit " , new { id = item . Id }) | @Html . ActionLink ( " Details " , " Details " , new { id = item . Id }) | @Html . ActionLink ( " Delete " , " Delete " , new { id = item . Id }) </ td > </ tr > } </ table >
Cdigo CSHTML 6.5: Index.cshtml

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44

Teste a mensagem cadastrando uma editora atravs da url

http://localhost:<PORTA_APP>/Editora/Cadastra.
Verique que a mensagem de sucesso aparecer.

106

www.k19.com.br

CAPTULO
Cdigo C# 7.1: RouteCong.cs

R OTAS

Para acessar uma determinada ao da nossa aplicao, os usurios devem realizar uma requisio HTTP utilizando a url correspondente ao. Por exemplo, para acessar a listagem de editoras, 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 denido 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 2 3 4 5 routes . MapRoute ( name : " Default " , url : " { controller }/{ action }/{ id } " , defaults : new { controller = " Home " , action = " Index " , id = UrlParameter . Optional } );

O primeiro argumento do mtodo MapRoute o nome da rota, o segundo a expresso que dene 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 processadas de acordo com as regras de rotas. URL Mapeamento da URL

/ /Livro /Livro/Adiciona /Livro/Remove/1

controller controller controller controller

= = = =

"Home", action = "Index" "Livro", action = "Index" "Livro", action = "Adiciona" "Livro", action = "Remove", id = 1

Adicionando uma rota


Para acrescentar uma rota, podemos utilizar o mtodo MapRoute(). Suponha que a listagem de editoras deva ser acessada atravs da url http://localhost:<PORTA_APP>/Catalogo. Nesse caso, podemos adicionar uma rota no arquivo RoutesConfig.cs, como mostrado abaixo.
1 2 3 4 ... routes . MapRoute ( name : " Nova Rota " , url : " Catalogo " ,

www.k19.com.br

107

R OTAS
5 6 7 defaults : new { controller = " Editora " , action = " Index " } ); ...
Cdigo C# 7.2: RoutesCong.cs

108

Importante
As rotas so processadas na ordem em que foram inseridas. Portanto, importante denir as rotas mais especcas antes das rotas mais genricas.

Adicionando Parmetros nas Rotas


Podemos acrescentar parmetros s rotas. Por exemplo, na rota criada anteriormente para a listagem de editoras, poderamos adicionar um parmetro para limitar a quantidade de editoras listadas.
1 2 3 4 5 routes . MapRoute ( name : " Nova Rota " , url : " Catalogo /{ maximo } " , defaults : new { controller = " Editora " , action = " Index " } );
Cdigo C# 7.3: RoutesCong.cs

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 denido na url da requisio. Por exemplo, http://localhost:<PORTA_APP>/Catalogo/2 . 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 3 4 5 6 7 8 ... routes . MapRoute ( name : " Nova Rota " , url : " Catalogo /{ maximo } " , defaults : new { controller = " Editora " , action = " Index " , maximo = UrlParameter . Optional } ); ...
Cdigo C# 7.4: RoutesCong.cs

Os parmetros das rotas podem ser recuperados nas aes. Observe o exemplo abaixo.
1 2 3 4 5 6 ... public ActionResult Index ( int ? maximo ) { // implementao } ...
Cdigo C# 7.5: EditoraController.cs

Ao denir parmetros opcionais, devemos utilizar parmetros do tipo nullable type nas aes, pois quando o parmetro no estiver denido na url de uma requisio, o valor null ser atribudo
108
www.k19.com.br

109

R OTAS

ao parmetro da ao. Por exemplo, para os tipos int e double, devemos utilizar int? e double?, respectivamente.

Exerccios de Fixao
1

Acrescente uma nova rota no projeto K19 para acessarmos a listagem de editoras atravs da url

http://localhost:<PORTA_APP>/Catalogo. Para isso, altere o arquivo RouteConfig.cs da pasta App_Start. Essa nova rota deve ser adiciona antes da rota Default j denida no arquivo RouteConfig.cs.
1 2 3 4 5 6 7 ... routes . MapRoute ( name : " Nova Rota " , url : " Catalogo " , defaults : new { controller = " Editora " , action = " Index " } ); ...
Cdigo C# 7.6: RouteCong.cs

Teste essa nova rota, acessando a url http://localhost:<PORTA_APP>/Catalogo.


2

Acrescente um parmetro chamado prefixo rota criada no exerccio anterior.


... routes . MapRoute ( name : " Nova Rota " , url : " Catalogo /{ prefixo } " , defaults : new { controller = " Editoras " , action = " Index " } ); ...
Cdigo C# 7.7: RouteCong.cs

1 2 3 4 5 6 7

Faa um teste acessando a url http://localhost:<PORTA_APP>/Catalogo. Verique que um erro gerado. Depois tente acessar a url http://localhost:<PORTA_APP>/Catalogo/teste. Verique que a requisio processada com sucesso, pois o parmetro prefixo foi denido.
3

Faa o parmetro prefixo ser opcional.


... routes . MapRoute ( name : " Nova Rota " , url : " Catalogo /{ prefixo } " , defaults : new { controller = " Editoras " , action = " Index " , prefixo = UrlParameter . Optional } ); ...
Cdigo C# 7.8: RouteCong.cs

1 2 3 4 5 6 7 8

Agora, tente acessar a url http://localhost:<PORTA_APP>/Catalogo. Nenhum erro obtido dessa vez. Altere a ao de listagem de editoras para receber o parmetro prefixo da rota denida anteriormente. Dena a lgica para listar as editoras a partir desse parmetro.
4

www.k19.com.br

109

R OTAS
1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 ... public ActionResult Index ( string prefixo ) { if ( String . IsNullOrEmpty ( prefixo ) ) { return View ( db . Editoras . ToList () ) ; } else { var consulta = from e in db . Editoras where e . Nome . StartsWith ( prefixo ) select e ; return View ( consulta . ToList () ) ; } } ...
Cdigo C# 7.9: EditorasController.cs

110

Para testar, acesse a url http://localhost:<PORTA_APP>/Catalogo/<PREFIXO> com diferentes prexos.

110

www.k19.com.br

CAPTULO
)
Cdigo C# 8.1: Denindo as regras de validao Cdigo C# 8.2: Denindo as mensagens de erro de validao

VALIDAO

Os usurios podem cometer erros ao preencher um formulrio. Por exemplo, esquecer de preencher 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 denir a lgica de validao na camada de controle.
1 2 3 4 if ( editora . Nome == null || editora . Nome . Trim () . Length == { // Erro de Validao }

O segundo passo denir 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.
1 2 3 4 if ( editora . Nome == null || editora . Nome . Trim () . Length == ) { ModelState . AddModelError ( " Nome " , " O campo Nome obrigatrio " ) ; }

As mensagens so armazenadas no ModelState atravs do mtodo AddModelError(). Esse mtodo permite que as mensagens sejam agrupadas logicamente, pois ele possui dois parmetros: o primeiro o grupo da mensagem e o segundo e a mensagem propriamente. O cdigo de validao pode ser colocado nos controladores, mais especicamente nas aes. Se algum erro for encontrado, o uxo 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 2 3 4 5 6 7 8 9 [ HttpPost ] public ActionResult Salva ( Editora editora ) { if ( editora . Nome == null || editora . Nome . Trim () . Length == ) { ModelState . AddModelError ( " Nome " , " O campo Nome obrigatrio . " ) ; } if ( ModelState . IsValid ) {

www.k19.com.br

111

VALIDAO
1 11 12 13 14 15 16 17 18 db . Editoras . Add ( editora ) ; TempData [ " mensagem " ] = " A editora foi cadastrada com sucesso ! " ; return RedirectToAction ( " Index " ) ; } else { return View ( " Cadastra " ) ; } }
Cdigo C# 8.3: EditoraController.cs

112

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.
1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 @model K19 . Models . Editora @{ ViewBag . Title = " Cadastro de Editora " ; } < h2 > Cadastro de Editora </ h2 > @using ( Html . BeginForm () ) { @Html . ValidationSummary () < br / > @Html . LabelFor ( model = > model . Nome ) @Html . EditorFor ( model = > model . Nome ) < br / > @Html . LabelFor ( model = > model . Email ) @Html . EditorFor ( model = > model . Email ) < br / > < input type = " submit " value = " Enviar " / > }
Cdigo CSHTML 8.1: Cadastra.cshtml

Podemos utilizar o mtodo ValidationMessageFor() para mostrar somente as mensagens de erro de validao de um determinado grupo. Para no mostrar erros dos grupos com o ValidationSummary(), devemos passar como parmetro o valor true. Nesse caso, apenas os erros que no esto associados a um grupo especco sero apresentados pelo ValidationSummary().
1 2 3 @model LivrariaVirtual . Models . Editora @{

112

www.k19.com.br

113
4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 ViewBag . Title = " Cadastro de Editora " ; } < h2 > Cadastro de Editora </ h2 > @using ( Html . BeginForm () ) { @Html . ValidationSummary ( true ) < br / > @Html . LabelFor ( model = > model . Nome ) @Html . EditorFor ( model = > model . Nome ) @Html . ValidationMessageFor ( model = > model . Nome ) < br / > @Html . LabelFor ( model = > model . Email ) @Html . EditorFor ( model = > model . Email ) @Html . ValidationMessageFor ( model = > model . Email ) < br / > < input type = " submit " value = " Enviar " / > }
Cdigo CSHTML 8.2: Cadastra.cshtml

VALIDAO

Exerccios de Fixao
Dena as regras de validao dos campos das editoras. A editora deve ter obrigatoriamente nome e email. Para exibir as mensagens sobre os erros de validao, utilize os mtodos ValidationMessage() e ValidationMessageFor().
1

No projeto K19, altera a lgica da ao Salva do controlador Editora.


1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 ... public ActionResult Salva ( Editora editora ) { if ( String . IsNullOrEmpty ( editora . Nome ) ) { ModelState . AddModelError ( " Nome " , " O nome da editora obrigatrio " ) ; } if ( String . IsNullOrEmpty ( editora . Email ) ) { ModelState . AddModelError ( " Email " , " O email da editora obrigatrio " ) ; } if ( ModelState . IsValid ) { db . Editoras . Add ( editora ) ; db . SaveChanges () ; TempData [ " Mensagem " ] = " Editora cadastrada com sucesso ! " ; return RedirectToAction ( " Index " ) ; } else { return View ( " Cadastra " , editora ) ; } } ...
Cdigo C# 8.4: EditoraController.cs

www.k19.com.br

113

VALIDAO
2

114

Modique o formulrio de cadastro de editoras.


@model K19 . Models . Editora @{ ViewBag . Title = " Cadastra " ; } < h2 > Cadastro de Editoras </ h2 > @using ( Html . BeginForm ( " Salva " , " Editora " ) ) { @Html . LabelFor ( x = > x . Nome ) @Html . EditorFor ( x = > x . Nome ) @Html . ValidationMessageFor ( x = > x . Nome ) < br / > @Html . LabelFor ( x = > x . Email ) @Html . EditorFor ( x = > x . Email ) @Html . ValidationMessageFor ( x = > x . Email ) < br / > < input type = " submit " value = " Enviar " / > }
Cdigo CSHTML 8.3: Cadastra.cshtml

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24

Para testar, acesse a url http://localhost:<PORTA_APP>/Editora/Cadastra. Deixe o campo nome e email em branco e verique as mensagens de erro de validao.

Anotaes
As lgicas de validao tambm podem ser denidas atravs de anotaes adicionadas nas classes de modelo. Dessa forma, essas lgicas no estariam mais nos controladores, o que conceitualmente o ideal, pois nos controladores s deveria existir lgica para controlar o uxo da execuo.

Required
Uma das validaes mais comuns a de campo obrigatrio. Ela pode ser realizada atravs da anotao Required.
1 2 3 4 5 6 7 public class Editora { [ Required ] public string Nome { get ; set ;} ... }
Cdigo C# 8.5: Editora.cs

Com essa anotao, a lgica de validao pode ser retirada do controlador Editora.
1 2 3 ... [ HttpPost ] public ActionResult Salva ( Editora editora )

114

www.k19.com.br

115
4 5 6 7 8 9 1 11 12 13 14 15 { if ( ModelState . IsValid ) { db . Editoras . Add ( editora ) ; return RedirectToAction ( " Index " ) ; } else { return View ( " Cadastra " , editora ) ; } } ...
Cdigo C# 8.6: EditoraController.cs

VALIDAO

Alterando a mensagem
As anotaes de validao possuem mensagens padro que podem ser alteradas atravs do atributo ErrorMessage.
1 2 3 4 ... [ Required ( ErrorMessage = " O campo Nome obrigatrio " ) ] public string Nome { get ; set ; } ...

Outros validadores
H outras anotaes para validao:

Range ReqularExpression StringLength

Validao no lado do Cliente


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 2 3 @section Scripts { @Scripts . Render ( " ~/ bundles / jqueryval " ) }

www.k19.com.br

115

VALIDAO

116

Exerccios de Fixao
Altere as validaes feitas anteriormente, para utilizar DataAnnotations. Lembre-se de alterar todas as mensagens de erro para a lngua portuguesa. Acrescente tambm a validao no cliente.
3

Primeiramente, altere a camada de modelo.


1 2 3 4 5 6 7 8 9 1 11 12 13 using System . ComponentModel . DataAnnotations ; namespace K19 . Models { public class Editora { public int Id { get ; set ; } [ Required ( ErrorMessage = " O campo nome obrigatrio " ) ] public string Nome { get ; set ; } [ Required ( ErrorMessage = " O campo email obrigatrio " ) ] public string Email { get ; set ; } } }
Cdigo C# 8.8: Editora.cs

Altere a ao Salva retirando a lgica de validao denida anteriormente.


... public ActionResult Salva ( Editora editora ) { if ( ModelState . IsValid ) { db . Editoras . Add ( editora ) ; db . SaveChanges () ; TempData [ " Mensagem " ] = " Editora cadastrada com sucesso ! " ; return RedirectToAction ( " Index " ) ; } else { return View ( " Cadastra " , editora ) ; } } ...
Cdigo C# 8.9: EditoraControlle.cs

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16

Para adicionar a validao no lado do cliente, basta alterar a pgina de cadastro de editoras. Observe o cdigo abaixo.
5

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15

@model K19 . Models . Editora < h2 > Cadastro de Editoras </ h2 > @using ( Html . BeginForm ( " Salva " , " Editora " ) ) { @Html . LabelFor ( x = > x . Nome ) @Html . EditorFor ( x = > x . Nome ) @Html . ValidationMessageFor ( x = > x . Nome ) < br / > @Html . LabelFor ( x = > x . Email ) @Html . EditorFor ( x = > x . Email ) @Html . ValidationMessageFor ( x = > x . Email )

116

www.k19.com.br

117
16 17 18 19 2 21 22 23 < br / > < input type = " submit " value = " Enviar " / > } @section Scripts { @Scripts . Render ( " ~/ bundles / jqueryval " ) }
Cdigo CSHTML 8.5: Cadastra.cshtml

VALIDAO

Para testar, acesse a url http://localhost:<PORTA_APP>/Editora/Cadastra. Deixe o campo nome e email em branco e verique as mensagens de erro de validao.

www.k19.com.br

117

VALIDAO

118

118

www.k19.com.br

CAPTULO

S ESSO

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 nalizada 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 conectado, o servidor manter uma sesso aberta. Dessa forma, podemos separar os dados de cada usurio conectado.

Identicando os navegadores
Para aplicar a ideia de Sesso, necessrio ter a capacidade de identicar o navegador que est requisitando a aplicao a cada requisio. Uma primeira abordagem seria utilizar o endereo IP da mquinas para identicar os navegadores. Porm, nessa abordagem, dois navegadores executando na mesma mquina no poderiam ser identicados individualmente. Outra abordagem deixar a cargo do servidor a criao de um identicador nico para cada navegador conectado. Quando um navegador faz a primeira requisio para a aplicao, o servidor deve gerar um identicador nico para esse navegador e envi-lo na resposta HTTP. A partir da segunda requisio, os navegadores devem enviar para a aplicao o identicador recebido na primeira requisio. Desta maneira, a aplicao saber qual o navegador que est realizando uma requisio. Os navegadores podem enviar os seus respectivos identicadores de diferentes formas. As mais utilizadas so:

Reescrita de URL Nesta abordagem, os identicadores so embutidos nos links e botes das pginas da aplicao. Quando os links ou botes so clicados pelo usurio, o identicador enviado para a aplicao. Uma desvantagem que todas as pginas devem ser geradas dinamicamente para adicionar o identicador 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 usurio. Alm disso, os navegadores enviam os cookies de volta para o servidor em todas as requisies. Os servidores podem armazenar os identicadores gerados em cookies. Dessa forma, a cada requisio, o servidor receber um cookie contendo o identicador.

Sesses no ASP .NET MVC


www.k19.com.br

119

S ESSO

120

No ASP.NET MVC, o objeto que representa uma sesso um dicionrio. Para armazenar informaes, 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.
1 2 3 4 5 6 7 8 9 1 public class LoginController : Controller { ... public ActionResult Login ( Cliente cliente ) { ... Session [ " Cliente " ] = cliente ; ... } }
Cdigo C# 9.1: LonginController.cs

Voc pode adicionar qualquer tipo de valor na sesso. De forma anloga, para resgatar as informaes armazenadas, basta acessar a chave correspondente da propriedade Session. Veja o exemplo a seguir:
1 2 Cliente cliente = ( Cliente ) Session [ " Cliente " ]; string saudacao = " Bem vindo " + cliente . Nome ;
Cdigo C# 9.2: Recuperando informaes da sesso

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 () ;
Cdigo C# 9.3: Eliminando todas as informaes da sesso

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.
1 2 3 4 5 6 7 8 9 1 public class LoginController : Controller { ... public ActionResult Logout () { ... Session . Abandon () ; ... } }
Cdigo C# 9.4: LoginController.cs

Session Mode
O ASP.NET MVC disponibiliza quatro modos de sesso (Session Modes): InProc
120
www.k19.com.br

121

S ESSO

StateServer SQLServer Custom

A diferena entre eles o modo de armazenamento das sesses. No modo InProc, todas as informaes da sesso so armazenadas na memria do servidor. Esse o modo mais simples e mais utilizado, e vem congurado como o padro. Uma desvantagem desse modo a possvel sobrecarga de memria se forem armazenadas muitas informaes na sesso. Por isso no indicado para sistemas muito grandes, com muitos usurios navegando simultaneamente. Outro problema que o servidor da aplicao no pode ser desligado, pois a informao armazenada na memria ser perdida. No modo StateServer, as informaes so serializadas e enviadas para um servidor independente do servidor da aplicao. Isto possibilita que o servidor de aplicao possa ser reiniciado sem que as sesses sejam perdidas. Uma desvantagem o tempo gasto para realizar a serializao e desserializao. No modo SQLServer, as informaes tambm so serializadas, mas so armazenadas em um banco de dados. Alm de permitir que o servidor da aplicao seja reiniciado, este modo possibilita um maior controle de segurana dos dados da sesso. Uma desvantagem importante que o processo naturalmente lento. No modo Custom, todo o processo de identicao de usurios e armazenamento de sesses pode ser personalizado. 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.
1 < sessionState mode = " InProc " / >
Cdigo XML 9.1: Web.Cong

Podemos personalizar nossa sesso, modicando alguns atributos da tag <sessionState>. Por exemplo, podemos determinar o tempo de timeout das sesses. Veja o exemplo abaixo.
1 < sessionState mode = " InProc " timeout = " 3 " / >
Cdigo XML 9.2: Web.Cong

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 " / >
Cdigo XML 9.3: Web.Cong

Exerccios de Fixao
www.k19.com.br

121

S ESSO

122

Para entender o conceito de sesso, vamos mostrar o nome do usurio logado em todas as pginas. Primeiramente, adicione uma classe chamada Usuario na pasta Models do projeto K19.
1

1 2 3 4 5 6 7 8

namespace K19 . Models { public class Usuario { public string Username { get ; set ; } public string Password { get ; set ; } } }
Cdigo C# 9.5: Usuario.cs

Agora, vamos denir um controlador para implementar o processo de autenticao. Adicione um controlador chamado Autenticador na pasta Controllers do projeto K19. Implemente as aes para o usurio logar-se e deslogar-se do sistema.
2

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34

using System . Web . Mvc ; using K19 . Models ; namespace K19 . Controllers { public class AutenticadorController : Controller { public ActionResult Formulario () { return View () ; } public ActionResult Entrar ( Usuario usuario ) { if ( usuario . Username != null && usuario . Password != null && usuario . Username . Equals ( " K19 " ) && usuario . Password . Equals ( " K19 " ) ) { Session [ " Usuario " ] = usuario ; return RedirectToAction ( " Index " , " Editora " ) ; } else { ViewBag . Mensagem = " usurio ou senha incorretos " ; return View ( " Formulario " ) ; } } public ActionResult Sair () { Session . Abandon () ; return RedirectToAction ( " Formulario " ) ; } } }
Cdigo C# 9.6: AutenticadorController.cs

Crie um arquivo chamado Formulario.cshtml em uma pasta chamada Views\Autenticador com o seguinte contedo.
3

1 2 3 4 5

@model K19 . Models . Usuario @{ ViewBag . Title = " Formulario " ; }

122

www.k19.com.br

123
6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26

S ESSO

@if ( ViewBag . Mensagem != null ) { < h2 > @ViewBag . Mensagem </ h2 > } < h2 > Formulario de Autenticao </ h2 > @using ( Html . BeginForm ( " Entrar " , " Autenticador " ) ) { @Html . LabelFor ( x = > x . Username ) @Html . EditorFor ( x = > x . Username ) < br / > @Html . LabelFor ( x = > x . Password ) @Html . EditorFor ( x = > x . Password ) < br / > < input type = " submit " value = " Enviar " / > }
Cdigo CSHTML 9.1: Formulario.cshtml

Faa um teste acessando a url http://localhost:<PORTA_APP>/Autenticador/Formulario. Tente acessar o sistema com usurios ou senhas incorretos. Depois, utilize o usurio K19 e a senha K19. Altere o arquivo K19Layout.cshtml acrescentando links para o usurio logar-se e deslogar-se (caso estiver logado) do sistema.
4

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37

@using K19 . Models <! DOCTYPE html > < html > < head > < meta charset = " utf -8 " / > < meta name = " viewport " content = " width = device - width " / > < title > @ViewBag . Title </ title > @Styles . Render ( " ~/ Content / themes / base / css " , " ~/ Content / css " ) @Scripts . Render ( " ~/ bundles / modernizr " ) </ head > < body > < div id = " header " > @Html . ActionLink ( " Editoras " , " Index " , " Editora " ) @Html . ActionLink ( " Testa Formulario Html " , " TestaFormularioHtml " ," Teste " ) @Html . ActionLink ( " Testa Helpers " , " TestaHelpers " ," Teste " ) @Html . ActionLink ( " Testa Helpers Tipados " , " TestaHelpersTipados " ," Teste " ) @Html . ActionLink ( " Testa EditorFor " , " TestaEditorFor " ," Teste " ) @if ( Session [ " Usuario " ] != null ) { < span > Ol @ (( Session [ " Usuario " ] as Usuario ) . Username ) ! </ span > @Html . ActionLink ( " Logout " , " Sair " , " Autenticador " ) } else { @Html . ActionLink ( " Login " , " Formulario " , " Autenticador " ) } </ div > @if ( IsSectionDefined ( " Sidebar " ) ) { < div id = " sidebar " > @RenderSection ( " Sidebar " , required : false ) </ div > }

www.k19.com.br

123

S ESSO
38 39 4 41 42 43 44 45 46 47 48 else { < div id = " sidebar " > Sidebar padro </ div > } < div id = " content " > @RenderBody () </ div > < div id = " footer " > K19 Treinamentos </ div > @Scripts . Render ( " ~/ bundles / jquery " ) @RenderSection ( " scripts " , required : false ) </ body > </ html >
Cdigo CSHTML 9.2: K19Layout.cshtml

124

Para testar, acesse http://localhost:<PORTA_APP>/Autenticador/Formulario. Faa testes logando e deslogando do sistema.

124

www.k19.com.br

CAPTULO
Cdigo C# 10.1: EditoraController.cs

AUTENTICAO

10

Muitas vezes, queremos restringir o acesso determinadas reas de uma aplicao, seja por questes de segurana ou por organizao. Em nossa aplicao poderamos, por exemplo, denir que para poder adicionar, alterar e remover editoras, o usurio deve estar logado no sistema. Caso contrrio, o usurio apenas poder listar as editoras.
1 2 3 4 5 6 7 8 9 1 11 12 13 ... public ActionResult Cadastra () { if ( Session [ " Cliente " ] != null ) { return base . View () ; } else { return base . RedirectToAction ( " Index " , " Login " ) ; } } ...

No exemplo acima, caso um usurio tente adicionar uma editora atravs do formulrio de cadastro, a ao Cadastra vericar se o usurio j est logado. Essa vericao 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 executou, 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 ltros. Um ltro semelhante a um mtodo que executado antes ou depois que uma ao.

Filtro de Autenticao
O ASP.NET MVC j possui alguns ltros prontos para serem utilizados, como o ltro de autenticao. Podemos utilizar ele para o nosso primeiro exemplo, onde exigimos que o usurio esteja logado (autenticado) para acessar determinadas reas da aplicao. Para isso, precisamos adicionar o seguinte cdigo no nosso mtodo de login:
www.k19.com.br

125

AUTENTICAO
1 2 3 [\ dots **] FormsAuthentication . SetAuthCookie ( usuario . Username , false ) ; [\ dots **]
Cdigo C# 10.2: AutenticadorController.cs

126

Isto adiciona um novo cookie utilizado para a autenticao do usurio. Este novo cookie independente do cookie utilizado para armazenar informaes da sesso. O primeiro parmetro referente ao nome do usurio (ou algo que o identique). O segundo parmetro um booleano relativo 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 3 ... FormsAuthentication . SignOut () ; ...
Cdigo C# 10.3: AutenticadorController.cs

As aes que devem utilizar o ltro de autenticao devem ser anotadas com Authorize.
1 2 3 4 5 6 7 ... [ Authorize ] public ActionResult Cadastra () { return base . View () ; } ...
Cdigo C# 10.4: EditoraController.cs

Se queremos aplicar o mesmo ltro a todas as aes de um controlador, podemos adicionar a notao Authorize na classe.
1 2 3 4 5 [ Authorize ] public class EditoraController : Controller { ... }
Cdigo C# 10.5: EditoraController.cs

Desse modo, todas as aes presentes no controlador da Editora exigem que o usurio esteja autenticado. Quando o ltro de autenticao barra um usurio de acessar uma pgina, podemos redirecionlo para a pgina de login. Devemos incluir o seguinte cdigo dentro da tag <system.web> do arquivo Web.Config.
1 2 3 < authentication mode = " Forms " > < forms loginUrl = " ~/ Autenticador / Formulario " timeout = " 288 " / > </ authentication >
Cdigo XML 10.1: Web.Cong

126

www.k19.com.br

127

AUTENTICAO

Para vericar se o usurio associado sesso atual est autenticada, podemos utilizar a propriedade IsAuthenticated, como a seguir:
1 2 3 4 if ( User . Identity . IsAuthenticated ) { ... }
Cdigo C# 10.6: Vericando se o usurio est autenticado

Podemos pegar a informao de quem est autenticado atravs do seguinte comando:


1 string nome = User . Identity . Name ;
Cdigo C# 10.7: Vericando quem o usurio autenticado

Isto ir pegar o nome que passamos como parmetro para o mtodo SetAuthCookie na autenticao.

Exerccios de Fixao
Altere a ao Cadastra do controlador Editora para que somente usurios logados possam acessar o formulrio de cadastro.
1

1 2 3 4 5 6 7 8 9 1 11 12 13

... public ActionResult Cadastra () { if ( Session [ " Usuario " ] != null ) { return View () ; } else { return RedirectToAction ( " Formulario " , " Autenticador " ) ; } } ...
Cdigo C# 10.8: EditorasController.cs

Teste acessando o seguinte endereo: http://localhost:<PORTA_APP>/Editora/Cadastra. Verique que enquanto o login no for efetuado, no ser possvel acessar o formulrio de cadastro.
2 Ao invs de usar sesso, vamos utilizar o ltro de autenticao pronto do ASP.NET MVC. Primeiro, devemos alterar as aes Entrar e Sair do controlador Autenticador.

1 2 3 4 5 6 7 8 9 1 11 12

using System . Web . Mvc ; using System . Web . Security ; using K19 . Models ; namespace K19 . Controllers { public class AutenticadorController : Controller { public ActionResult Formulario () { return View () ;

www.k19.com.br

127

AUTENTICAO
13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 } public ActionResult Entrar ( Usuario usuario ) { if ( usuario . Username != null && usuario . Password != null && usuario . Username . Equals ( " K19 " ) && usuario . Password . Equals ( " K19 " ) ) { FormsAuthentication . SetAuthCookie ( usuario . Username , false ) ; return RedirectToAction ( " Index " , " Editora " ) ; } else { ViewBag . Mensagem = " usurio ou senha incorretos " ; return View ( " Formulario " ) ; } } public ActionResult Sair () { FormsAuthentication . SignOut () ; return RedirectToAction ( " Formulario " ) ; } } }
Cdigo C# 10.9: AutenticadorController.cs

128

Altere o arquivo de layout para mostrar o usurio logado.


@using K19 . Models <! DOCTYPE html > < html > < head > < meta charset = " utf -8 " / > < meta name = " viewport " content = " width = device - width " / > < title > @ViewBag . Title </ title > @Styles . Render ( " ~/ Content / themes / base / css " , " ~/ Content / css " ) @Scripts . Render ( " ~/ bundles / modernizr " ) </ head > < body > < div id = " header " > @Html . ActionLink ( " Editoras " , " Index " , " Editora " ) @Html . ActionLink ( " Testa Formulario Html " , " TestaFormularioHtml " ," Teste " ) @Html . ActionLink ( " Testa Helpers " , " TestaHelpers " ," Teste " ) @Html . ActionLink ( " Testa Helpers Tipados " , " TestaHelpersTipados " ," Teste " ) @Html . ActionLink ( " Testa EditorFor " , " TestaEditorFor " ," Teste " ) @if ( User . Identity . IsAuthenticated ) { < span > Ol @User . Identity . Name </ span > @Html . ActionLink ( " Logout " , " Sair " , " Autenticador " ) } else { @Html . ActionLink ( " Login " , " Formulario " , " Autenticador " ) } </ div > @if ( IsSectionDefined ( " Sidebar " ) ) { < div id = " sidebar " > @RenderSection ( " Sidebar " , required : false ) </ div > } else { < div id = " sidebar " > Sidebar padro </ div >

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4

128

www.k19.com.br

129
41 42 43 44 45 46 47 48 } < div id = " content " > @RenderBody () </ div > < div id = " footer " > K19 Treinamentos </ div > @Scripts . Render ( " ~/ bundles / jquery " ) @RenderSection ( " scripts " , required : false ) </ body > </ html >
Cdigo CSHTML 10.1: K19Layout.cshtml

AUTENTICAO

Altere o controlador Editora para que somente usurios logados possam acessar o formulrio de cadastro.
4

1 2 3 4 5 6 7

... [ Authorize ] public ActionResult Cadastra () { return View () ; } ...


Cdigo C# 10.10: EditoraController.cs

Dena 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 K19.
5

1 2 3 4 5

... < authentication mode = " Forms " > < forms loginUrl = " ~/ Autenticador / Formulario " timeout = " 288 " / > </ authentication > ...
Cdigo XML 10.2: Web.cong

Acesse o endereo http://localhost:<PORTA_APP>/Editora/Cadastra. Verique o funcionamento do ltro de autenticao que redirecionar os usurios que no esto logados para a url denida no arquivo Web.config.

www.k19.com.br

129

AUTENTICAO

130

130

www.k19.com.br

CAPTULO

T RATAMENTO DE E RROS

11

Inevitavelmente, as aplicaes esto sujeitas a erros de vrias naturezas. Por exemplo, erros podem 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 zessem. Quando um erro desse tipo ocorre, o ASP.NET MVC cria uma pgina web com informaes sobre 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 justicativa que esses detalhes podem confundir os usurios.

Figura 11.1: Exemplo de uma pgina web com informaes sobre um erro

www.k19.com.br

131

T RATAMENTO DE E RROS

132

A segunda justicativa 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 identicados atravs do comando try-catch, que pode ser colocados nos mtodos que denem as aes dos controladores. Ao identicar a ocorrncia de um erro, os controladores podem devolver uma pgina web com alguma mensagem para o usurio.
1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 ... [ HttpPost ] public ActionResult Salva ( Editora editora ) { try { db . Editoras . Add ( editora ) ; } catch { return View ( " Error " ) ; } return RedirectToAction ( " Index " ) ; } ...

Cdigo C# 11.1: EditoraController.cs

Podemos criar uma pgina Error.cshtml na pasta Views\Shared. Dessa forma, todo controlador poder devolver essa pgina.
1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 @{ Layout = null ; } <! DOCTYPE html > < html > < head > < title > Erro </ title > </ head > < body > < h2 > Servidor com problemas </ h2 > <p > Houve um problema em nosso servidor . < br / > Por favor tente novamente dentro de alguns instantes . </ p > </ body > </ html >

Cdigo CSHTML 11.1: Error.cshtml

As pginas de erro que sero mostradas pelos controladores teriam uma mensagem simples informando 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.
132
www.k19.com.br

133

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 ca 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 congurar o ASP .NET MVC para utilizar pginas de erro padro. O primeiro passo alterar o arquivo de congurao Web.config, acrescentando a tag <customErrors> dentro da tag <system.web>.
1 2 3 4 5 ... < customErrors mode = " On " > </ customErrors > ...
Cdigo XML 11.1: Web.Cong

O atributo mode da tag <customErrors> pode assumir trs valores: 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 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 @{ Layout = null ; } <! DOCTYPE html > < html > < head > < title > Erro </ title > </ head > < body > < h2 > Servidor com problemas </ h2 > <p > Houve um problema no nosso servidor . < br / > Por favor tente novamente dentro de alguns instantes . </ p > </ body > </ html >
Cdigo CSHTML 11.2: Error.cshtml

Http Errors
www.k19.com.br

133

T RATAMENTO DE E RROS

134

Um dos erros mais conhecidos do HTTP o 404, que ocorre quando o navegador faz uma requisio 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 congurada 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 considerado 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 especca para ele.
1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 @{ Layout = null ; } <! DOCTYPE html > < html > < head > < title > Arquivo no encontrado ! </ title > </ head > < body > < h2 > Esse arquivo no foi encontrado . Verifique se a url est correta . </ h2 > </ body > </ html >
Cdigo CSHTML 11.3: NotFound.cshtml

No arquivo de congurao, podemos especicar uma pgina web particular para o erro 404 ou para os outros erros do HTTP .
1 2 3 4 5 ... < customErrors mode = " On " > < error statusCode = " 4 4 " redirect = " ~/ ErrorPage / NotFound " / > </ customErrors > ...
Cdigo XML 11.2: Web.Cong

De acordo com o cdigo anterior, devemos denir um controlador chamado ErrorPage com uma ao chamada NotFound. Essa ao ser acionada toda vez que o erro 404 do HTTP ocorrer.
1 2 3 4 5 6 7 8 9 1 namespace K19 . Controllers { public class ErrorPageController : Controller { public ActionResult NotFound () { return View () ; } } }
Cdigo C# 11.2: ErroPageController.cs

Exerccios de Fixao
134

www.k19.com.br

135

T RATAMENTO DE E RROS

Crie uma nova ao no controlador Teste do projeto K19, conforme o cdigo abaixo.
... public ActionResult TestaErro () { string [] nomes = new string [] { " Jonas Hirata " , " Rafael Cosentino " }; string nome = nomes [2]; return View () ; } ...
Cdigo C# 11.3: TesteController.cs

1 2 3 4 5 6 7 8

Acesse o seguinte endereo http://localhost:<PORTA_APP>/Teste/TestaErro e verique a tela de erro. 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 execuo 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.
2 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.

Altere a ao TestaErro do controlador Teste.


1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 ... public ActionResult TestaErro () { try { string [] nomes = new string [] { " Jonas Hirata " , " Rafael Cosentino " }; string nome = nomes [2]; return View () ; } catch { return View ( " Error " ) ; } } ...
Cdigo C# 11.4: TesteController.cs

Altere o cdigo do arquivo Error.cshtml da pasta Views\Shared conforme o cdigo abaixo:


@{ Layout = null ; } <! DOCTYPE html > < html > < head > < meta name = " viewport " content = " width = device - width " / > < title > Error </ title > </ head > < body > < h2 > Sistema Temporariamente Indisponvel ... </ h2 >

1 2 3 4 5 6 7 8 9 1 11 12 13 14

www.k19.com.br

135

T RATAMENTO DE E RROS
15 16 </ body > </ html >
Cdigo CSHTML 11.4: Error.cshtml

136

Acesse novamente o endereo http://localhost:<PORTA_APP>/Teste/TestaErro e verique a nova pgina de erro. Remova o bloco try-catch da ao TestaErro do controlador Teste que voc adicionou no exerccio anterior.
4

1 2 3 4 5 6 7 8

... public ActionResult TestaErro () { string [] nomes = new string [] { " Jonas Hirata " , " Rafael Cosentino " }; string nome = nomes [2]; return View () ; } ...
Cdigo C# 11.5: TesteController.cs

Altere o arquivo Web.config para congurar o ASP.NET MVC para utilizar pginas de erro padro.
5

1 2 3 4 5 6 7

... < system . web > < customErrors mode = " On " > </ customErrors > ... < system . web > ...
Cdigo XML 11.3: Web.cong

Acesse o endereo http://localhost:<PORTA_APP>/Teste/TestaErro e verique a pgina de erro.


6 Vamos denir uma pgina para ser exibida quando o erro 404 ocorrer. Primeiramente, crie um controlador chamado ErrorPage com uma ao chamada NotFound.

1 2 3 4 5 6 7 8 9 1

namespace K19 . Controllers { public class ErrorPageController : Controller { public ActionResult NotFound () { return View () ; } } }
Cdigo C# 11.6: ErroPageController.cs

Na pasta Views\ErrorPage do projeto K19, adicione um arquivo chamado NotFound.cshtml com o seguinte contedo.
7

1 2 3

@{ Layout = null ; }

136

www.k19.com.br

137
4 5 6 7 8 9 1 11 12 13 14 15

T RATAMENTO DE E RROS

<! DOCTYPE html > < html > < head > < title > Arquivo no encontrado ! </ title > </ head > < body > < h2 > Esse arquivo no foi encontrado . Verifique se a url est correta . </ h2 > </ body > </ html >
Cdigo CSHTML 11.5: NotFound.cshtml

8 Altere o arquivo Web.Config para denir que quando um erro 404 ocorrer, a pgina exibida deve ser aquela que acabamos de criar.

1 2 3 4 5 6 7 8

... < system . web > < customErrors mode = " On " > < error statusCode = " 4 4 " redirect = " ~/ ErrorPage / NotFound " / > </ customErrors > ... < system . web > ...
Cdigo XML 11.4: Web.cong

Tente acessar pginas da aplicao que no existam. Acesse, por exemplo, o endereo http: //localhost:<PORTA_APP>/PaginaInexistente.

www.k19.com.br

137

T RATAMENTO DE E RROS

138

138

www.k19.com.br

APNDICE

ASP.NET W EB API

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 identicador nico globalmente. Os identicadores so utililzados para acessar os respectivos resources. Particularmente, em uma rede HTTP, os resources so identicados por URIs(Uniform Resource Identier - http://tools.ietf.org/html/rfc3986). Por exemplo, a URI www.k19.com.br/cursos identica 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 2 3 4 5 6 7 8 9 1 < html > < head > < title > Rafael Cosentino </ title > < head > < body > < h1 > Rafael Cosentino </ h1 > <p > Lder de treinamentos da K19 </ p > </ body > </ html >

1 2 3 4

< pessoa > < nome > Rafael Cosentino </ nome > < descricao > Lder de treinamentos da K19 </ descricao > < pessoa >

www.k19.com.br

139

ASP.NET W EB API
1 { " nome " : " Rafael Cosentino " , " descricao " : " Lder de treinamentos da K19 " }

140

Operaes
Em uma arquitetura REST, um conjunto pequeno e xo de operaes deve ser denido previamente. 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.

Resource www.k19.com.br/cursos www.k19.com.br/cursos

Mtodo HTTP GET POST

Semntica pega a lista de cursos adiciona um curso na lista

Resources
No ASP.NET Web API, os resources so denidos por controladores de uma aplicao ASP.NET MVC que derivam de System.Web.Http.ApiController.
1 2 3 4 public class CursosController : ApiController { ... }
Cdigo C# A.1: CursosController.cs

URIs
As URIs dos resources so denidas 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 2 3 4 5 routes . MapHttpRoute ( name : " DefaultApi " , routeTemplate : " api /{ controller }/{ id } " , defaults : new { id = RouteParameter . Optional } );
Cdigo C# A.2: RouteCong.cs

De acordo com a rota padro do ASP .NET Web API, a URI do resource correspondente ao controlador Cursos http://localhost:<PORTA_APP>/api/cursos.
140
www.k19.com.br

141

ASP.NET W EB API

Operaes
Podemos associar as operaes HTTP aos mtodos da classe CursosController. Essas associaes so estabelecidas automaticamente atravs dos nomes dos mtodos. Por exemplo, a operao GET do HTTP associada automaticamente a um mtodo cujo nome possui o prexo Get. Veja o exemplo abaixo.
1 2 3 4 5 6 7 8 9 1 public class CursosController : ApiController { ... // GET http :// localhost : < PORTA_APP >/ api / cursos public Curso [] GetCursos () { ... } ... }
Cdigo C# A.3: CursosController.cs

Na rota padro do ASP .NET Web API, um parmetro opcional chamado id foi denido. Quando esse parmetro estiver presente em uma requisio do tipo GET, podemos recuperar o valor dele em um mtodo cujo nome possua o prexo Get e tenha um argumento chamado id. Observe o cdigo abaixo.
1 2 3 4 5 6 7 8 9 1 public class CursosController : ApiController { ... // GET http :// localhost : < PORTA_APP >/ api / cursos /5 public Curso [] GetCurso ( int id ) { ... } ... }
Cdigo C# A.4: CursosController.cs

Tambm podemos recuperar parmetros de URL. Para isso, basta denir argumentos com os mesmos nomes desses parmetros nos mtodos associados s operaes do HTTP. Veja o exemplo abaixo
1 2 3 4 5 6 7 8 9 1 public class CursosController : ApiController { ... // GET http :// localhost : < PORTA_APP >/ api / cursos ? sigla = K32 public Curso [] GetCurso ( string sigla ) { ... } ... }
Cdigo C# A.5: CursosController.cs

Considere o cdigo a seguir.


1 public class CursosController : ApiController

www.k19.com.br

141

ASP.NET W EB API
2 3 4 5 6 7 8 9 1 { ... // POST http :// localhost : < PORTA_APP >/ api / cursos public void PostCurso ( Curso curso ) { ... } ... }
Cdigo C# A.6: CursosController.cs

142

O mtodo PostCurso() ser associado a operao POST do HTTP. Os valores dos parmetros enviados 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 denir 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 Vamos denir o nosso primeiro webservice utilizando web api. Para isso, adicione uma classe para modelar cursos na pasta Models.

1 2 3 4 5 6 7 8 9

namespace K19 . Models { public class Curso { public int Id { get ; set ; } public string Nome { get ; set ; } public int CargaHoraria { get ; set ; } } }
Cdigo C# A.7: Curso.cs

2 Agora crie um controlador chamado Cursos para implementar as operaes do webservice. Na criao desse controlador, selecione o template Empty API Controller.

1 2 3 4 5 6 7 8 9

using using using using using using using using

System ; System . Collections . Generic ; System . Linq ; System . Net ; System . Net . Http ; System . Web . Http ; LivrariaVirtual . Models ; System . Web . Mvc ;

142

www.k19.com.br

143
1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52 53 54 55 56 57 58 59 6 61 62 63 64 65 66 67 68 69 7 71 namespace K19 . Controllers { public class CursosController : ApiController { private static List < Curso > cursos = new List < Curso > { new Curso { Id = 1 , Sigla = " K31 " , Nome = " C # e Orientao a Objetos " }, new Curso { Id = 2 , Sigla = " K32 " , Nome = " Desenvolvimento Web com ASP . NET MVC " } }; public List < Curso > Get () { return cursos ; } public Curso Get ( string sigla ) { var consulta = from c in cursos where c . Sigla . Equals ( sigla ) select c ; if ( consulta . Count () == ) { return null ; } else { return consulta . First () ; } } public Curso Get ( int id ) { var consulta = from c in cursos where c . Id == id select c ; if ( consulta . Count () == ) { return null ; } else { return consulta . First () ; } } public void Post ( Curso curso ) { cursos . Add ( curso ) ; } } }

ASP.NET W EB API

Cdigo C# A.8: CursosController.cs

Para testar o webservice que retorna a lista de cursos, basta acessar o seguinte endereo: http:
www.k19.com.br

143

ASP.NET W EB API

144

//localhost:<PORTA_APP>/api/cursos.
4

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.
5

Teste o webservice que devolve um curso a partir de um id. Basta acessar o seguinte endereo:

http://localhost:<PORTA_APP>/api/cursos/1.
6 Dena uma pgina com um formulrio para testar o webservice que adiciona curso. Para isso, crie um controlador TestaWebServiceCurso conforme o cdigo abaixo:

1 2 3 4 5 6 7 8 9 1 11 12

using System . Web . Mvc ; namespace K19 . Controllers { public class TestaWebServiceCursoController : Controller { public ActionResult Formulario () { return View () ; } } }
Cdigo C# A.9: TestaWebServiceCursoController.cs

Para testar o webservice que adiciona curso, devemos denir a pgina Formulario.cshtml.
@model K19 . Models . Curso @{ ViewBag . Title = " Formulario " ; } < h2 > Formulario </ h2 > @using ( Html . BeginForm ( null , null , FormMethod . Post , new { @action = " / api / cursos " }) ) { < fieldset > < legend > Curso </ legend > < div class = " editor - label " > @Html . LabelFor ( model = > model . Id ) </ div > < div class = " editor - field " > @Html . EditorFor ( model = > model . Id ) </ div > < div class = " editor - label " > @Html . LabelFor ( model = > model . Sigla ) </ div > < div class = " editor - field " > @Html . EditorFor ( model = > model . Sigla ) </ div > < div class = " editor - label " > @Html . LabelFor ( model = > model . Nome ) </ div > < div class = " editor - field " > @Html . EditorFor ( model = > model . Nome ) </ div > <p > < input type = " submit " value = " Create " / > </ p > </ fieldset > } @section Scripts { @Scripts . Render ( " ~/ bundles / jqueryval " ) }

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37

144

www.k19.com.br

145

ASP.NET W EB API

Cdigo CSHTML A.1: Formulario.cshtml

Teste o webservice que adiciona curso atravs do formulrio criado no exerccio anterior. Acesse o formulrio atravs do seguinte endereo: http://localhost:<PORTA_APP>/TestaWebServiceCurso/ Formulario. Para vericar se o curso foi adicionado, acesse http://localhost:<PORTA_APP>/api/ cursos/.
8

www.k19.com.br

145

ASP.NET W EB API

146

146

www.k19.com.br

APNDICE

M IGRATIONS

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 modelo 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 utilizaremos o Entity Framework 5.0 RC.

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 RC. Para isso, utilizaremos o gerenciador de pacotes Nuget do Visual Studio.
www.k19.com.br

147

M IGRATIONS

148

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 arquivos de congurao. Mais informaes sobre o Nuget e os pacotes disponveis, acesse o endereo

http://nuget.org/packages
Para instalar o Entity Framework 5.0 RC, basta executar o seguinte comando no Package Manager Console.

Install-Package EntityFramework -Pre

Aps a instalao do Entity Framework 5.0 RC, adicionaremos uma classe de modelo chamada Editora. Essa entidade ser mapeada atravs de uma classe chamada Livraria. Para testar, criaremos uma classe com o mtodo Main(). Observe o cdigo dessas trs classes.
1 2 3 4 5 namespace EFMigrations { public class Editora { public int Id { get ; set ; }

148

www.k19.com.br

149
6 7 8 9 public string Nome { get ; set ; } public string Email { get ; set ; } } }
Cdigo C# B.1: Editora.cs

M IGRATIONS

1 2 3 4 5 6 7

namespace EFMigrations { public class Livraria : DbContext { public DbSet < Editora > Editoras { get ; set ; } } }
Cdigo C# B.2: Livraria.cs

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15

namespace EFMigrations { class Program { static void Main ( string [] args ) { using ( Livraria livraria = new Livraria () ) { Editora e = new Editora { Nome = " K19 " , Email = " contato@k19 . com . br " }; livraria . Editoras . Add ( e ) ; livraria . SaveChanges () ; } } } }
Cdigo C# B.3: Program.cs

Aps a execuo do projeto, teremos a seguinte tabela e banco de dados.

O prximo passo alterar a classe de modelo Editora.


1 2 3 4 5 6 7 8 namespace EFMigrations { public class Editora { public int Id { get ; set ; } public string Nome { get ; set ; } public string Email { get ; set ; }

www.k19.com.br

149

M IGRATIONS
9 1 11 public string Telefone { get ; set ; } } }
Cdigo C# B.4: Editora.cs

150

Com a alterao na classe Editora, um exeo gerada ao executar o projeto.

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 visto acima adiciona uma pasta chamada Migrations no projeto. Esta pasta contm dois arquivos. A classe Configuration permite denir o comportamento do Code First Migrations para o nosso contexto. A classe parcial InitialCreate dene a primeira verso das tabelas do banco de dados. O Code First Migration tem dois comandos fundamentais. Add-Migration que gera o cdigo necessrio para atualizar o banco de dados de acordo com as alteraes nas classes de modelo.
150
www.k19.com.br

151

M IGRATIONS

Update-Database aplica as alteraes pendentes no banco de dados.

Como adicionamos a propriedade Telefone na classe de modelo Editora, devemos criar e executar uma migrao para atualizar o banco de dados. Para criar uma migrao, devemos utilizar o comando Add-Migration. Para executar a migrao, devemos utilizar o comando Update-Database. Observe a execuo do comando Add-Migration.

A classe que dene a migrao adicionada na pasta Migrations

Para aplicar a migrao, devemos executar o comando Update-Database.

No banco de dados, uma coluna adicionada na tabela Editoras.


www.k19.com.br

151

M IGRATIONS

152

Podemos tambm adicionar uma nova entidade. Considere a seguinte classe para denir os livros da nossa aplicao.
1 2 3 4 5 6 7 8 9 1 11 namespace EFMigrations { public class Livro { public int Id { get ; set ; } public string Titulo { get ; set ; } public decimal Preco { get ; set ; } public int EditoraId { get ; set ; } public Editora Editora { get ; set ; } } }
Cdigo C# B.5: Livro.cs

Para estabelecer o relacionamento entre editoras e livros, a classe Editora deve ser alterada.
1 2 3 4 5 6 7 8 9 1 11 12 13 namespace EFMigrations { public class Editora { public int Id { get ; set ; } public string Nome { get ; set ; } public string Email { get ; set ; } public string Telefone { get ; set ; } [ ForeignKey ( " EditoraId " ) ] public virtual IList < Livro > Livros { get ; set ; } } }
Cdigo C# B.6: Editora.cs

A classe livro deve ser mapeada no contexto Livraria.


1 2 3 4 5 6 7 8 namespace EFMigrations { public class Livraria : DbContext { public DbSet < Editora > Editoras { get ; set ; } public DbSet < Livro > Livros { get ; set ; } } }

152

www.k19.com.br

153

M IGRATIONS

Cdigo C# B.7: Livraria.cs

Aps a alterao das classes Editora e Livraria e a criao da entidade Livro, devemos criar uma migrao para atualizar o banco de dados.

Para aplicar a migrao, devemos utilizar o comando Update-Database.

A tabela correspondente classe Livro e a chave estrangeira para realizar o relacionamento entre livros e editoras so adicionadas no banco de dados.
www.k19.com.br

153

M IGRATIONS

154

Exerccios de Fixao
Para testar o Code First Migrations, altere a classe Editora do projeto K19. Acrescente nessa classe uma propriedade chamada Telefone.
1

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17

using System . ComponentModel . DataAnnotations ; namespace K19 . Models { public class Editora { public int Id { get ; set ; } [ Required ( ErrorMessage = " O campo nome obrigatrio " ) ] public string Nome { get ; set ; } [ Required ( ErrorMessage = " O campo email obrigatrio " ) ] public string Email { get ; set ; } public string Telefone { get ; set ; } } }

Cdigo C# B.8: Editora.cs

Acesse o seguinte endereo: http://localhost:<PORTA_APP>/Editora. Verique que uma exceo do tipo System.InvalidOperationException ocorrer.
2

154

www.k19.com.br

155

M IGRATIONS

3 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.k19.com.br

155

M IGRATIONS

156

Verique que uma pasta chamada Migrations com dois arquivos: <DATA>_InitialCreate.cs e Conguration.cs foi gerada no projeto K19. Aps habilitar o Code First Migrations no projeto K19, devemos adicionar uma migrao para atualizar o banco de dados adicionando a coluna Telefone na tabela Editoras. Crie uma migrao chamada AddTelefoneToEditora atravs do comando Add-Migration. Execute este comando atravs do Package Manager Console.
4

Verique que um arquivo de migrao foi criado na pasta Migrations:


1 2 3 4 5 6 7 8 9 1 11 12 13 namespace K19 . Migrations { using System ; using System . Data . Entity . Migrations ; public partial class AddTelefoneToEditora : DbMigration { public override void Up () { AddColumn ( " dbo . Editoras " , " Telefone " , c = > c . String () ) ; } public override void Down ()

156

www.k19.com.br

157
14 15 16 17 18 { DropColumn ( " dbo . Editoras " , " Telefone " ) ; } } }
Cdigo C# B.9: <DATA>_AddTelefoneToEditora.cs

M IGRATIONS

Para atualizar a tabela Editoras no banco de dados, utilize o comando Update-Database que executado atravs do Package Manager Console.
5

Verique que a coluna Telefone foi adicionada a tabela Editoras.


6

Dena uma classe Livro na pasta Models conforme o cdigo abaixo:


namespace K19 . Models { public class Livro { public int Id { get ; set ; } public string Titulo { get ; set ; } public decimal Preco { get ; set ; } public int EditoraId { get ; set ; } public Editora Editora { get ; set ; } }

1 2 3 4 5 6 7 8 9 1

www.k19.com.br

157

M IGRATIONS
11 }
Cdigo C# B.10: Livro.cs

158

Altere a classe K19Context para mapear a classe Livro para uma tabela no banco de dados.
using System . Data . Entity ; namespace K19 . Models { public class K19Context : DbContext { public DbSet < Editora > Editoras { get ; set ; } public DbSet < Livro > Livros { get ; set ; } } }
Cdigo C# B.11: K19Context.cs

1 2 3 4 5 6 7 8 9 1

8 Para gerar a tabela Livros no banco de dados, devemos criar uma migrao. Crie uma migrao chamada AddLivro atravs do comando Add-Migration.

Execute o comando Update-Database atravs do Package Manager Console para gerar a tabela referente a classe Livro no banco de dados.
9

158

www.k19.com.br

159

M IGRATIONS

Verique que a tabela referente a classe Livro foi gerada no banco de dados.

www.k19.com.br

159

M IGRATIONS

160

160

www.k19.com.br

APNDICE
Cdigo C# C.1: Selecao.cs

P ROJETO

Nos captulos anteriores, vimos os recursos do ASP .NET MVC e do Entity Framework. Agora, vamos solidicar os conhecimentos obtidos e, alm disso, mostraremos alguns padres e conceitos relacionados ao desenvolvimento de aplicaes web. Como exemplo de aplicao desenvolveremos uma aplicao de cadastro de jogadores e selees de futebol.

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 restringir s entidades Selecao e Jogador. Devemos estabelecer um relacionamento entre essas entidades j que um jogador atua em uma seleo.

Exerccios de Fixao
Crie um projeto do tipo ASP .NET MVC 4 Web Application chamado K19-CopaDoMundo seguindo os passos vistos no exerccio do captulo 4.
1 2

Adicione na pasta Models as seguintes classes.


namespace K19CopaDoMundo . Models { public class Selecao { public int Id { get ; set ; } public string Pais { get ; set ; } public string Tecnico { get ; set ; } } }

1 2 3 4 5 6 7 8 9

1 2 3 4 5 6 7 8 9 1 11 12 13

namespace K19CopaDoMundo . Models { public class Jogador { public int Id { get ; set ; } public string Nome { get ; set ; } public string Posicao { get ; set ; } public DateTime Nascimento { get ; set ; } public double Altura { get ; set ; } public int SelecaoId { get ; set ; } public Selecao Selecao { get ; set ; } } }

www.k19.com.br

161

P ROJETO

162

Cdigo C# C.2: Jogador.cs

Persistncia - Mapeamento
Depois de denir algumas entidades podemos comear o processo de implementao da persistncia da nossa aplicao. Vamos aplicar os recursos do Entity Framework - Code First que aprendemos nos primeiros captulos. Inicialmente, vamos denir o mapeamento das nossas entidades atravs de uma classe derivada de DbContext e acrescentar as propriedades referentes a chave primria e chave estrangeira.

Exerccios de Fixao
3

Adicione as seguintes propriedades e anotaes as classes Selecao e Jogador.


1 2 3 4 5 6 7 8 9 1 11 12 13 using System . ComponentModel . DataAnnotations . Schema ; namespace K19CopaDoMundo . Models { [ Table ( " Selecoes " ) ] public class Selecao { public int Id { get ; set ; } public string Pais { get ; set ; } public string Tecnico { get ; set ; } public virtual List < Jogador > Jogadores { get ; set ; } } }
Cdigo C# C.3: Selecao.cs

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17

using System . ComponentModel . DataAnnotations . Schema ; namespace K19CopaDoMundo . Models { [ Table ( " Jogadores " ) ] public class Jogador { public int Id { get ; set ; } public string Nome { get ; set ; } public string Posicao { get ; set ; } public DateTime Nascimento { get ; set ; } public double Altura { get ; set ; } public int SelecaoId { get ; set ; } [ InverseProperty ( " Jogadores " ) ] public virtual Selecao Selecao { get ; set ; } } }
Cdigo C# C.4: Jogador.cs

Adicione a classe K19CopaDoMundoContext a pasta Models.


www.k19.com.br

162

163
1 2 3 4 5 6 7 8 9 1 using System . Data . Entity ; namespace K19CopaDoMundo . Models { public class K19CopaDoMundoContext : DbContext { public DbSet < Selecao > Selecoes { get ; set ; } public DbSet < Jogador > Jogadores { get ; set ; } } }
Cdigo C# C.5: K19CopaDoMundoContext.cs

C.3. P ERSISTNCIA - M APEAMENTO

Persistncia - Congurao
Precisamos denir a nossa string de conexo para que a nossa aplicao utilize a base de dados k19copadomundo como padro.

Exerccios de Fixao
5

Acrescente ao arquivo Web.cong, que ca na raiz do projeto, a string de conexo.


< connectionStrings > < add name = " K19CopaDoMundoContext " providerName = " System . Data . SqlClient " connectionString = " Server =.\ SQLEXPRESS ; Database = k19copadomundo ; User Id = sa ; Password = sa ; Trusted_Connection = False ; MultipleActiveResultSets = True " / > </ connectionStrings >
Cdigo XML C.1: Web.cong

1 2 3 4 5 6

Persistncia - Repositrios
Vamos deixar os repositrios para acessar as entidades da nossa aplicao preparados. Os repositrios precisam de DbContexts para realizar as operaes de persistncia. Ento, cada repositrio ter um construtor para receber um DbContext como parmetro.

Exerccios de Fixao
6

Crie uma classe na pasta Models chamada SelecaoRepository.


using System ; using System . Collections . Generic ; namespace K19CopaDoMundo . Models { public class SelecaoRepository : IDisposable { private bool disposed = false ; private K19CopaDoMundoContext context ; public SelecaoRepository ( K19CopaDoMundoContext context ) {

1 2 3 4 5 6 7 8 9 1 11 12 13

www.k19.com.br

163

P ROJETO
14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52 this . context = context ; } public void Adiciona ( Selecao selecao ) { context . Selecoes . Add ( selecao ) ; } public List < Selecao > Selecoes { get { return context . Selecoes . ToList () ; } } public void Salva () { context . SaveChanges () ; } protected virtual void Dispose ( bool disposing ) { if (! this . disposed ) { if ( disposing ) { context . Dispose () ; } } this . disposed = true ; } public void Dispose () { Dispose ( true ) ; GC . SuppressFinalize ( this ) ; } } }
Cdigo C# C.6: SelecaoRepository.cs

164

Analogamente crie um repositrio de jogadores.


using System ; using System . Collections . Generic ; namespace K19CopaDoMundo . Models { public class JogadorRepository : IDisposable { private bool disposed = false ; private K19CopaDoMundoContext context ; public JogadorRepository ( K19CopaDoMundoContext context ) { this . context = context ; } public void Adiciona ( Jogador jogador ) { context . Jogadores . Add ( jogador ) ; } public List < Jogador > Jogadores { get { return context . Jogadores . ToList () ; } }

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25

164

www.k19.com.br

165
26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 public void Salva () { context . SaveChanges () ; } protected virtual void Dispose ( bool disposing ) { if (! this . disposed ) { if ( disposing ) { context . Dispose () ; } } this . disposed = true ; } public void Dispose () { Dispose ( true ) ; GC . SuppressFinalize ( this ) ; } } }
Cdigo C# C.7: JogadorRepository.cs

C.3. P ERSISTNCIA - M APEAMENTO

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
8

Crie uma classe UnitOfWork na pasta Models.


using System ; using System . Collections . Generic ; namespace K19CopaDoMundo . Models { public class UnitOfWork : IDisposable { private bool disposed = false ; private K19CopaDoMundoContext context = new K19CopaDoMundoContext () ; private SelecaoRepository selecaoRepository ; private JogadorRepository jogadorRepository ;

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24

public JogadorRepository JogadorRepository { get { if ( jogadorRepository == null ) { jogadorRepository = new JogadorRepository ( context ) ; } return jogadorRepository ; } }

www.k19.com.br

165

P ROJETO
25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52 53 54 55 56 57 58 59 6 61

166

public SelecaoRepository SelecaoRepository { get { if ( selecaoRepository == null ) { selecaoRepository = new SelecaoRepository ( context ) ; } return selecaoRepository ; } } public void Salva () { context . SaveChanges () ; } protected virtual void Dispose ( bool disposing ) { if (! this . disposed ) { if ( disposing ) { context . Dispose () ; } } this . disposed = true ; } public void Dispose () { Dispose ( true ) ; GC . SuppressFinalize ( this ) ; } } }
Cdigo C# C.8: UnitOfWork.cs

Apresentao - Template
Vamos denir um template para as telas da nossa aplicao. Aplicaremos algumas regras CSS para melhorar a parte visual das telas.

Exerccios de Fixao
9

Na pasta Content, altere o arquivo Site.css acrescentando algumas regras CSS.


. logo { vertical - align : middle ; } . botao { background - color : # 64 D83 ; margin : 2 px ; color : white ; text - decoration : none ; font - size : 2 px ; line - height : 2 px ; padding : 5 px ;

1 2 3 4 5 6 7 8 9 1 11 12 13 14

166

www.k19.com.br

167
15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52 53 54 55 56 57 58 59 6 61 62 63 64 65 66 67 68 69 7 71 72 73 74 75 76 77 78 79 8 81 82 83 84 vertical - align : middle ; } . botao : hover { background - color : # cccccc ; color : #666666; } . formulario fieldset { float : left ; margin : 2 px ; border : 1 px solid #333333; } . formulario fieldset legend { color : # 64 D83 ; font - weight : bold ; } . botao - formulario { background - color : # 64 D83 ; color : # ffffff ; padding : 5 px ; vertical - align : middle ; border : none ; } . titulo { color : # 64 D83 ; clear : both ; } . tabela { border : 1 px solid # 64 D83 ; border - collapse : collapse ; } . tabela tr th { background - color : # 64 D83 ; color : # ffffff ; } . tabela tr th , . tabela tr td { border : 1 px solid # 64 D83 ; padding : 2 px 5 px ; }

C.3. P ERSISTNCIA - M APEAMENTO

/* Styles for validation helpers -- ------ ------ ------- ------ ------ ------ ------ ------ ------ -- */ . field - validation - error { color : # ff ; } . field - validation - valid { display : none ; } . input - validation - error {

www.k19.com.br

167

P ROJETO
85 86 87 88 89 9 91 92 93 94 95 96 97 98 border : 1 px solid # ff ; background - color : # ffeeee ; } . validation - summary - errors { font - weight : bold ; color : # ff ; } . validation - summary - valid { display : none ; }
Cdigo CSS C.1: Site.css

168

Copie o arquivo k19-logo.png da pasta K19-Arquivos da sua rea de Trabalho para a pasta Images.
10 11

Agora altere o arquivo _Layout.cshtml.


<! DOCTYPE html > < html lang = " en " > < head > < meta charset = " utf -8 " / > < title > Copa do Mundo </ title > < link href = " ~/ __TemplateIcon . ico " rel = " shortcut icon " type = " image /x - icon " / > < meta name = " viewport " content = " width = device - width " / > @Styles . Render ( " ~/ Content / themes / base / css " , " ~/ Content / css " ) @Scripts . Render ( " ~/ bundles / modernizr " ) </ head > < body > < header > < div class = " content - wrapper " > < div class = " float - left " > <p class = " site - title " > < img class = " logo " src = " ~/ Images / k19 - logo . jpg " alt = " K19 Logo " / > </ p > </ div > < div class = " float - right " > < nav > < ul id = " menu " > < li > @Html . ActionLink ( " Selecoes " , " Index " , " Selecao " , null , new { @class = " botao " }) </ li > < li > @Html . ActionLink ( " Jogadores " , " Index " , " Jogador " , null , new { @class = " botao " }) </ li > </ ul > </ nav > </ div > </ div > </ header > < div id = " body " > @RenderSection ( " featured " , required : false ) < section class = " content - wrapper main - content clear - fix " > @RenderBody () </ section > </ div > < footer > < div class = " content - wrapper " > < div class = " float - left " > <p >& copy ; @DateTime . Now . Year - K19 Copa do Mundo </ p > </ div > < div class = " float - right " > < ul id = " social " > < li > <a href = " http :// facebook . com / k19treinamentos " class = " facebook " > Facebook - K19 Treinamentos </ a > </ li > < li > <a href = " http :// twitter . com / k19treinamentos " class = " twitter " > Twitter - K19 Treinamentos </ a > </ li > </ ul >

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42

168

www.k19.com.br

169
43 44 45 46 47 48 49 </ div > </ div > </ footer > @Scripts . Render ( " ~/ bundles / jquery " ) @RenderSection ( " scripts " , required : false ) </ body > </ html >

C.12. C ADASTRANDO E L ISTANDO S ELEES

Cdigo CSHTML C.1: _Layout.cshtml

Cadastrando e Listando Selees


Na tela de selees, vamos adicionar um formulrio para cadastrar novas selees e uma tabela para apresentar as j cadastradas. Aplicaremos regras de validao especcas para garantir que nenhum dado incorreto seja armazenado no banco de dados.

Exerccios de Fixao
12

Para cadastrar a seleo, devemos denir o controlador.


using using using using using using using using System ; System . Collections . Generic ; System . Data ; System . Data . Entity ; System . Linq ; System . Web ; System . Web . Mvc ; K19CopaDoMundo . Models ;

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27

namespace K19CopaDoMundo . Controllers { public class SelecaoController : Controller { private UnitOfWork unitOfWork = new UnitOfWork () ; public ActionResult Create () { return View () ; } protected override void Dispose ( bool disposing ) { unitOfWork . Dispose () ; base . Dispose ( disposing ) ; } } }
Cdigo C# C.9: SelecaoController.cs

13 Vamos criar uma tela Create.cshtml para cadastrar as selees. Adicione o arquivo a pasta Views/Selecoes com o seguinte contedo.

1 2 3 4

@model K19CopaDoMundo . Models . Selecao @{ ViewBag . Title = " Create " ;

www.k19.com.br

169

P ROJETO
5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 } < h2 > Create </ h2 > @using ( Html . BeginForm () ) { @Html . ValidationSummary ( true ) < fieldset > < legend > Selecao </ legend > < div class = " editor - label " > @Html . LabelFor ( model = > model . Pais ) </ div > < div class = " editor - field " > @Html . EditorFor ( model = > model . Pais ) @Html . ValidationMessageFor ( model = > model . Pais ) </ div > < div class = " editor - label " > @Html . LabelFor ( model = > model . Tecnico ) </ div > < div class = " editor - field " > @Html . EditorFor ( model = > model . Tecnico ) @Html . ValidationMessageFor ( model = > model . Tecnico ) </ div > <p > < input type = " submit " value = " Create " / > </ p > </ fieldset > } < div > @Html . ActionLink ( " Listagem de Selees " , " Index " ) </ div > @section Scripts { @Scripts . Render ( " ~/ bundles / jqueryval " ) }
Cdigo CSHTML C.2: Create.cshtml

170

14 O prximo passo denir a action que ir salvar a seleo no nosso banco de dados. Devemos tambm acrescentar as validaes a nossa entidade.

1 2 3 4 5 6 7 8 9 1 11

[ HttpPost ] public ActionResult Create ( Selecao selecao ) { if ( ModelState . IsValid ) { unitOfWork . SelecaoRepository . Adiciona ( selecao ) ; unitOfWork . Salva () ; return RedirectToAction ( " Index " ) ; } return View ( selecao ) ; }
Cdigo C# C.10: SelecaoController.cs

1 2 3 4 5 6 7 8

using System . ComponentModel . DataAnnotations . Schema ; using System . ComponentModel . DataAnnotations ; namespace K19CopaDoMundo . Models { [ Table ( " Selecoes " ) ] public class Selecao {

170

www.k19.com.br

171
9 1 11 12 13 14 15 16

C.12. C ADASTRANDO E L ISTANDO S ELEES


public int Id { get ; set ; } [ Required ( ErrorMessage = " O campo Pais obrigatrio . " ) ] public string Pais { get ; set ; } [ Required ( ErrorMessage = " O campo Tecnico obrigatrio . " ) ] public string Tecnico { get ; set ; } public virtual List < Jogador > Jogadores { get ; set ; } } }
Cdigo C# C.11: Selecao.cs

15

Dena a action e a pgina para listar todas as entidades de seleo.


public ActionResult Index () { return View ( unitOfWork . SelecaoRepository . Selecoes ) ; }
Cdigo C# C.12: SelecaoController.cs

1 2 3 4

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34

@model IEnumerable < K19CopaDoMundo . Models . Selecao > @{ ViewBag . Title = " Index " ; } < h2 > Index </ h2 > <p > @Html . ActionLink ( " Create New " , " Create " ) </ p > < table > < tr > < th > @Html . DisplayNameFor ( model = > model . Pais ) </ th > < th > @Html . DisplayNameFor ( model = > model . Tecnico ) </ th > < th > </ th > </ tr > @foreach ( var item in Model ) { < tr > < td > @Html . DisplayFor ( modelItem = > item . Pais ) </ td > < td > @Html . DisplayFor ( modelItem = > item . Tecnico ) </ td > </ tr > } </ table >
Cdigo CSHTML C.3: Index.cshtml

Vamos denir a tela de listagem de Selees como a pgina principal do nosso site. Altere a rota padro no arquivo RouteCong.cs.
16

1 2 3 4 5

routes . MapRoute ( name : " Default " , url : " { controller }/{ action }/{ id } " , defaults : new { controller = " Selecao " , action = " Index " , id = UrlParameter . Optional } ) ;

www.k19.com.br

171

P ROJETO

172

Cdigo C# C.13: RouteCong.cs

Removendo Selees
Vamos acrescentar a funcionalidade de remover selees.

Exerccios de Fixao
17

Acrescente uma coluna na tabela de listagem de selees.


1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 @model IEnumerable < K19CopaDoMundo . Models . Selecao > @{ ViewBag . Title = " Index " ; } < h2 > Index </ h2 > <p > @Html . ActionLink ( " Create New " , " Create " ) </ p > < table > < tr > < th > @Html . DisplayNameFor ( model = > model . Pais ) </ th > < th > @Html . DisplayNameFor ( model = > model . Tecnico ) </ th > < th > </ th > </ tr > @foreach ( var item in Model ) { < tr > < td > @Html . DisplayFor ( modelItem = > item . Pais ) </ td > < td > @Html . DisplayFor ( modelItem = > item . Tecnico ) </ td > < td > @Html . ActionLink ( " Remover " ," Delete " , new { id = item . Id }) </ td > </ tr > } </ table >
Cdigo CSHTML C.4: Index.cshtml

18 Dena um mtodo Busca na classe SelecaoRepository que retorna uma entidade seleo a partir de um parmetro id.

1 2 3 4

public Selecao Busca ( int id ) { return context . Selecoes . Find ( id ) ; }

172

www.k19.com.br

173

C.12. C ADASTRANDO E L ISTANDO S ELEES

Cdigo C# C.14: SelecaoRepository.cs

19

Dena uma action Delete que ir mostrar a tela de conrmao de remoo da entidade.
public ActionResult Delete ( int id ) { Selecao selecao = unitOfWork . SelecaoRepository . Busca ( id ) ; return View ( selecao ) ; }
Cdigo C# C.15: SelecaoController.cs

1 2 3 4 5

20

Dena a tela de conrmao de remoo da seleo.


@model K19CopaDoMundo . Models . Selecao @{ ViewBag . Title = " Delete " ; } < h2 > Remoo de Seleo </ h2 > < h3 > Voc tem certeza que deseja remover esta seleo ? </ h3 > < fieldset > < legend > Selecao </ legend > < div class = " display - label " > @Html . DisplayNameFor ( model = > model . Pais ) </ div > < div class = " display - field " > @Html . DisplayFor ( model = > model . Pais ) </ div > < div class = " display - label " > @Html . DisplayNameFor ( model = > model . Tecnico ) </ div > < div class = " display - field " > @Html . DisplayFor ( model = > model . Tecnico ) </ div > </ fieldset > @using ( Html . BeginForm () ) { <p > < input type = " submit " value = " Delete " / > | @Html . ActionLink ( " Listagem De Selees " , " Index " ) </ p > }
Cdigo CSHTML C.5: Delete.cshtml

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32

Dena um mtodo na classe SelecaoRepository que remove uma entidade seleo a partir de um parmetro id.
21

1 2 3 4 5

public void Remove ( int id ) { Selecao selecao = Busca ( id ) ; context . Selecoes . Remove ( selecao ) ; }
Cdigo C# C.16: SelecaoRepository.cs

22

Dena a action que remove a seleo do banco de dados.


www.k19.com.br

173

P ROJETO
1 2 3 4 5 6 7 8 [ HttpPost ] [ ActionName ( " Delete " ) ] public ActionResult DeleteConfirmed ( int id ) { unitOfWork . SelecaoRepository . Remove ( id ) ; unitOfWork . Salva () ; return RedirectToAction ( " Index " ) ; }
Cdigo C# C.17: SelecoesController.cs

174

Cadastrando, Listando e Removendo Jogadores


Na tela de jogadores, vamos adicionar um formulrio para cadastrar novos jogadores e uma tabela para apresentar os j cadastrados. Aplicaremos regras de validao especcas para garantir que nenhum dado incorreto seja armazenado no banco de dados.

Exerccios de Fixao
23

Para cadastrar o jogador, devemos denir o controlador.


using using using using using using using using System ; System . Collections . Generic ; System . Data ; System . Data . Entity ; System . Linq ; System . Web ; System . Web . Mvc ; K19CopaDoMundo . Models ;

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28

namespace K19CopaDoMundo . Controllers { public class JogadorController : Controller { private UnitOfWork unitOfWork = new UnitOfWork () ; public ActionResult Create () { ViewBag . SelecaoId = new SelectList ( unitOfWork . SelecaoRepository . Selecoes , " Id " , " Pais " ) ; return View () ; } protected override void Dispose ( bool disposing ) { unitOfWork . Dispose () ; base . Dispose ( disposing ) ; } } }
Cdigo C# C.18: JogadorController.cs

Vamos criar uma tela Create.cshtml para cadastrar os jogadores. Adicione o arquivo a pasta Views/Jogador com o seguinte contedo.
24

1 2 3

@model K19CopaDoMundo . Models . Jogador @{

174

www.k19.com.br

175
4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52 53 54 55 56 57 58 59 6 61 62 63 64 65 66 67 ViewBag . Title = " Create " ; } < h2 > Create </ h2 > @using ( Html . BeginForm () ) { @Html . ValidationSummary ( true ) < fieldset > < legend > Jogador </ legend >

C.12. C ADASTRANDO E L ISTANDO S ELEES

< div class = " editor - label " > @Html . LabelFor ( model = > model . Nome ) </ div > < div class = " editor - field " > @Html . EditorFor ( model = > model . Nome ) @Html . ValidationMessageFor ( model = > model . Nome ) </ div > < div class = " editor - label " > @Html . LabelFor ( model = > model . Posicao ) </ div > < div class = " editor - field " > @Html . EditorFor ( model = > model . Posicao ) @Html . ValidationMessageFor ( model = > model . Posicao ) </ div > < div class = " editor - label " > @Html . LabelFor ( model = > model . Nascimento ) </ div > < div class = " editor - field " > @Html . EditorFor ( model = > model . Nascimento ) @Html . ValidationMessageFor ( model = > model . Nascimento ) </ div > < div class = " editor - label " > @Html . LabelFor ( model = > model . Altura ) </ div > < div class = " editor - field " > @Html . EditorFor ( model = > model . Altura ) @Html . ValidationMessageFor ( model = > model . Altura ) </ div > < div class = " editor - label " > @Html . LabelFor ( model = > model . SelecaoId ) </ div > < div class = " editor - field " > @Html . DropDownList ( " SelecaoId " , String . Empty ) @Html . ValidationMessageFor ( model = > model . SelecaoId ) </ div > <p > < input type = " submit " value = " Create " / > </ p > </ fieldset > } < div > @Html . ActionLink ( " Listagem de Jogadores " , " Index " ) </ div > @section Scripts { @Scripts . Render ( " ~/ bundles / jqueryval " ) }
Cdigo CSHTML C.6: Create.cshtml

O prximo passo denir a action que ir salvar o jogador no nosso banco de dados. Devemos tambm acrescentar as validaes a nossa entidade.
25

www.k19.com.br

175

P ROJETO
1 2 3 4 5 6 7 8 9 1 11 12

176
[ HttpPost ] public ActionResult Create ( Jogador jogador ) { if ( ModelState . IsValid ) { unitOfWork . JogadorRepository . Adiciona ( jogador ) ; unitOfWork . Salva () ; return RedirectToAction ( " Index " ) ; } ViewBag . SelecaoId = new SelectList ( unitOfWork . SelecaoRepository . Selecoes , " Id " , " Pais " ) ; return View () ; }
Cdigo C# C.19: JogadorController.cs

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25

using System . ComponentModel . DataAnnotations . Schema ; using System . ComponentModel . DataAnnotations ; namespace K19CopaDoMundo . Models { [ Table ( " Jogadores " ) ] public class Jogador { public int Id { get ; set ; } [ Required ( ErrorMessage = " O campo Nome obrigatrio . " ) ] public string Nome { get ; set ; } [ Required ( ErrorMessage = " O campo Posicao obrigatrio . " ) ] public string Posicao { get ; set ; } [ Required ( ErrorMessage = " O campo Nascimento obrigatrio . " ) ] [ DataType ( DataType . Date ) ] public DateTime Nascimento { get ; set ; } [ Required ( ErrorMessage = " O campo Altura obrigatrio . " ) ] public double Altura { get ; set ; } public int SelecaoId { get ; set ; } [ InverseProperty ( " Jogadores " ) ] public virtual Selecao Selecao { get ; set ; } } }
Cdigo C# C.20: Jogador.cs

26

Dena a action e a pgina para listar todas as entidades de jogador.


public ActionResult Index () { return View ( unitOfWork . JogadorRepository . Jogadores ) ; }
Cdigo C# C.21: JogadorController.cs

1 2 3 4

1 2 3 4 5 6 7 8 9 1 11 12 13

@model IEnumerable < K19CopaDoMundo . Models . Jogador > @{ ViewBag . Title = " Listagem de Jogadores " ; } < h2 > Listagem de Jogadores </ h2 > <p > @Html . ActionLink ( " Cadastrar Jogador " , " Create " ) </ p > < table > < tr >

176

www.k19.com.br

177
14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52 < th > @Html . DisplayNameFor ( model </ th > < th > @Html . DisplayNameFor ( model </ th > < th > @Html . DisplayNameFor ( model </ th > < th > @Html . DisplayNameFor ( model </ th > < th > @Html . DisplayNameFor ( model </ th > < th > </ th > </ tr > @foreach ( var item in Model ) { < tr > < td > @Html . DisplayFor ( modelItem </ td > < td > @Html . DisplayFor ( modelItem </ td > < td > @Html . DisplayFor ( modelItem </ td > < td > @Html . DisplayFor ( modelItem </ td > < td > @Html . DisplayFor ( modelItem </ td > </ tr > } </ table >

C.12. C ADASTRANDO E L ISTANDO S ELEES

= > model . Nome )

= > model . Posicao )

= > model . Nascimento )

= > model . Altura )

= > model . SelecaoId )

= > item . Nome )

= > item . Posicao )

= > item . Nascimento )

= > item . Altura )

= > item . SelecaoId )

Cdigo CSHTML C.7: Index.cshtml

Removendo Jogadores
Vamos acrescentar a funcionalidade de remover jogadores.

Exerccios de Fixao
27

Acrescente uma coluna na tabela de listagem de jogadores.


@model IEnumerable < K19CopaDoMundo . Models . Jogador > @{ ViewBag . Title = " Listagem de Jogadores " ; } < h2 > Listagem de Jogadores </ h2 > <p > @Html . ActionLink ( " Cadastrar Jogador " , " Create " ) </ p > < table > < tr >

1 2 3 4 5 6 7 8 9 1 11 12 13

www.k19.com.br

177

P ROJETO
14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52 < th > @Html . DisplayNameFor ( model </ th > < th > @Html . DisplayNameFor ( model </ th > < th > @Html . DisplayNameFor ( model </ th > < th > @Html . DisplayNameFor ( model </ th > < th > @Html . DisplayNameFor ( model </ th > < th > </ th > </ tr > = > model . Nome )

178

= > model . Posicao )

= > model . Nascimento )

= > model . Altura )

= > model . SelecaoId )

@foreach ( var item in Model ) { < tr > < td > @Html . DisplayFor ( modelItem = > item . Nome ) </ td > < td > @Html . DisplayFor ( modelItem = > item . Posicao ) </ td > < td > @Html . DisplayFor ( modelItem = > item . Nascimento ) </ td > < td > @Html . DisplayFor ( modelItem = > item . Altura ) </ td > < td > @Html . DisplayFor ( modelItem = > item . SelecaoId ) </ td > < td > @Html . ActionLink ( " Remover " , " Delete " , new { id = item . Id }) </ td > </ tr > } </ table >
Cdigo CSHTML C.8: Index.cshtml

Dena um mtodo Busca na classe JogadorRepository que retorna uma entidade jogador a partir de um parmetro id.
28

1 2 3 4

public Jogador Busca ( int id ) { return context . Jogadores . Find ( id ) ; }


Cdigo C# C.22: JogadorRepository.cs

29

Dena uma action Delete que ir mostrar a tela de conrmao de remoo da entidade.
public ActionResult Delete ( int id ) { Jogador jogador = unitOfWork . JogadorRepository . Busca ( id ) ; return View ( jogador ) ; }
Cdigo C# C.23: JogadorController.cs

1 2 3 4 5

30

Dena a tela de conrmao de remoo do jogador.


@model K19CopaDoMundo . Models . Jogador

178

www.k19.com.br

179
2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52 53

C.12. C ADASTRANDO E L ISTANDO S ELEES

@{ ViewBag . Title = " Remoo do Jogador " ; } < h2 > Remoo do Jogador </ h2 > < h3 > Voc tem certeza que deseja remover este jogador ? </ h3 > < fieldset > < legend > Jogador </ legend > < div class = " display - label " > @Html . DisplayNameFor ( model = > model . Nome ) </ div > < div class = " display - field " > @Html . DisplayFor ( model = > model . Nome ) </ div > < div class = " display - label " > @Html . DisplayNameFor ( model = > model . Posicao ) </ div > < div class = " display - field " > @Html . DisplayFor ( model = > model . Posicao ) </ div > < div class = " display - label " > @Html . DisplayNameFor ( model = > model . Nascimento ) </ div > < div class = " display - field " > @Html . DisplayFor ( model = > model . Nascimento ) </ div > < div class = " display - label " > @Html . DisplayNameFor ( model = > model . Altura ) </ div > < div class = " display - field " > @Html . DisplayFor ( model = > model . Altura ) </ div > < div class = " display - label " > @Html . DisplayNameFor ( model = > model . SelecaoId ) </ div > < div class = " display - field " > @Html . DisplayFor ( model = > model . SelecaoId ) </ div > </ fieldset > @using ( Html . BeginForm () ) { <p > < input type = " submit " value = " Delete " / > | @Html . ActionLink ( " Listagem de Jogadores " , " Index " ) </ p > }
Cdigo CSHTML C.9: Delete.cshtml

Dena um mtodo na classe JogadorRepository que remove uma entidade jogador a partir de um parmetro id.
31

1 2 3 4 5

public void Remove ( int id ) { Jogador jogador = context . Jogadores . Find ( id ) ; context . Jogadores . Remove ( jogador ) ; }
Cdigo C# C.24: JogadorRepository.cs

32

Dena a action que remove o jogador do banco de dados.


www.k19.com.br

179

P ROJETO
1 2 3 4 5 6 7 8 [ HttpPost ] [ ActionName ( " Delete " ) ] public ActionResult DeleteConfirmed ( int id ) { unitOfWork . JogadorRepository . Remove ( id ) ; unitOfWork . Salva () ; return RedirectToAction ( " Index " ) ; }
Cdigo C# C.25: JogadoresController.cs

180

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 ltro e Membership. As requisies feitas pelos usurios passaro pelo ltro. A funo do ltro vericar se o usurio est logado ou no. Se estiver logado o ltro autoriza o acesso. Caso contrrio, o ltro redirecionar o usurio para a tela de login.

Exerccios de Fixao
33

Adicione a seguinte classe a pasta Models:


using using using using using System ; System . Collections . Generic ; System . Linq ; System . Web . Mvc ; System . ComponentModel . DataAnnotations ;

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36

namespace K19CopaDoMundo . Models { public class ChangePasswordModel { [ Required ] [ DataType ( DataType . Password ) ] [ Display ( Name = " Senha " ) ] public string OldPassword { get ; set ; } [ Required ] [ StringLength (1 , ErrorMessage = " O { } deve ter no mnimo {2} caracteres . " , MinimumLength = 6) ] [ DataType ( DataType . Password ) ] [ Display ( Name = " Nova senha " ) ] public string NewPassword { get ; set ; } [ DataType ( DataType . Password ) ] [ Display ( Name = " Confirmao de senha " ) ] [ Compare ( " NewPassword " , ErrorMessage = " A senha e a confirmao no conferem . " )] public string ConfirmPassword { get ; set ; } } public class LoginModel { [ Required ] [ Display ( Name = " Usurio " ) ] public string UserName { get ; set ; } [ Required ] [ DataType ( DataType . Password ) ]

180

www.k19.com.br

181
37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52 53 54 55 56 57 58 59 6 61 62 63 64 65 66 67 [ Display ( Name = " Senha " ) ] public string Password { get ; set ; } [ Display ( Name = " Lembrar ? " ) ] public bool RememberMe { get ; set ; } } public class RegisterModel { [ Required ] [ Display ( Name = " Usurio " ) ] public string UserName { get ; set ; } [ Required ] [ DataType ( DataType . EmailAddress ) ] [ Display ( Name = " Email " ) ] public string Email { get ; set ; }

C.12. C ADASTRANDO E L ISTANDO S ELEES

[ Required ] [ StringLength (1 , ErrorMessage = " O { } deve ter no mnimo {2} caracteres . " , MinimumLength = 6) ] [ DataType ( DataType . Password ) ] [ Display ( Name = " Senha " ) ] public string Password { get ; set ; } [ DataType ( DataType . Password ) ] [ Display ( Name = " Confirmao de senha " ) ] [ Compare ( " Password " , ErrorMessage = " A senha e a confirmao no conferem . " ) ] public string ConfirmPassword { get ; set ; } } }
Cdigo C# C.26: Usuario.cs

34

Acrescente a seguinte classe a pasta Controllers.


using using using using using using using System ; System . Collections . Generic ; System . Linq ; System . Web ; System . Web . Mvc ; System . Web . Security ; K19CopaDoMundo . Models ;

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32

namespace K19CopaDoMundo . Controllers { public class UsuarioController : Controller { // // GET : / Usuario / Login public ActionResult Login () { return View () ; } // // POST : / Usuario / Login [ HttpPost ] public ActionResult Login ( LoginModel model , string returnUrl ) { if ( ModelState . IsValid ) { if ( Membership . ValidateUser ( model . UserName , model . Password ) ) { FormsAuthentication . SetAuthCookie ( model . UserName , model . RememberMe ) ; if ( Url . IsLocalUrl ( returnUrl ) && returnUrl . Length > 1 && returnUrl . www.k19.com.br

181

P ROJETO
StartsWith ( " / " ) && ! returnUrl . StartsWith ( " // " ) && ! returnUrl . StartsWith ( " /\\ " ) ) { return Redirect ( returnUrl ) ; } else { return RedirectToAction ( " Index " , " Selecao " ) ; } } else { ModelState . AddModelError ( " " , " O usurio e / ou a senha est incorreto . " ) ; } }

182

33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52 53 54 55 56 57 58 59 6 61 62 63 64 65 66 67 68 69 7 71 72 73 74 75 76 77 78 79 8 81 82 83 84 85 86 87 88 89 9 91 92 93 94 95 96 97 98 99

return View ( model ) ; } // // GET : / Usuario / LogOff public ActionResult LogOff () { FormsAuthentication . SignOut () ; return Redirect ( " / " ) ; } // // GET : / Usuario / Register public ActionResult Register () { return View () ; } // // POST : / Usuario / Register [ HttpPost ] public ActionResult Register ( RegisterModel model ) { if ( ModelState . IsValid ) { // Attempt to register the user MembershipCreateStatus createStatus ; Membership . CreateUser ( model . UserName , model . Password , model . Email , null , null , true , null , out createStatus ) ; if ( createStatus == MembershipCreateStatus . Success ) { FormsAuthentication . SetAuthCookie ( model . UserName , false /* createPersistentCookie */ ) ; return Redirect ( " / " ) ; } else { ModelState . AddModelError ( " " , ErrorCodeToString ( createStatus ) ) ; } }

return View ( model ) ; } // // GET : / Usuario / ChangePassword

182

www.k19.com.br

183
1 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 11 111 112 113 114 115 116 117 118 119 12 121 122 123 124 125 126 127 128 129 13 131 132 133 134 135 136 137 138 139 14 141 142 143 144 145 146 147 148 149 15 151 152 153 154 155 156 157 158 159 16 161 162 163 164 165 [ Authorize ] public ActionResult ChangePassword () { return View () ; } // // POST : / Usuario / ChangePassword

C.12. C ADASTRANDO E L ISTANDO S ELEES

[ Authorize ] [ HttpPost ] public ActionResult ChangePassword ( ChangePasswordModel model ) { if ( ModelState . IsValid ) {

bool changePasswordSucceeded ; try { MembershipUser currentUser = Membership . GetUser ( User . Identity . Name , true /* userIsOnline */ ) ; changePasswordSucceeded = currentUser . ChangePassword ( model . OldPassword , model . NewPassword ) ; } catch ( Exception ) { changePasswordSucceeded = false ; } if ( changePasswordSucceeded ) { return RedirectToAction ( " ChangePasswordSuccess " ) ; } else { ModelState . AddModelError ( " " , " A senha atual ou a confirmao est incorreta . "); } }

return View ( model ) ; } // // GET : / Usuario / ChangePasswordSuccess public ActionResult ChangePasswordSuccess () { return View () ; } private IEnumerable < string > GetErrorsFromModelState () { return ModelState . SelectMany ( x = > x . Value . Errors . Select ( error = > error . ErrorMessage ) ) ; } # region Status Codes private static string ErrorCodeToString ( MembershipCreateStatus createStatus ) { // See http :// go . microsoft . com / fwlink /? LinkID =17755 for // a full list of status codes . switch ( createStatus ) { case MembershipCreateStatus . DuplicateUserName : return " Este nome de usurio j existe . Defina outro usurio . " ; case MembershipCreateStatus . DuplicateEmail :

www.k19.com.br

183

P ROJETO
166 167 168 169 17 171 172 173 174 175 176 177 178 179 18 181 182 183 184 185 186 187 188 189 19 191 192 193 194 195 196 return " Este email j foi cadastrado . Defina outro email . " ; case MembershipCreateStatus . InvalidPassword : return " Senha incorreta . " ; case MembershipCreateStatus . InvalidEmail : return " Email invlido . " ; case MembershipCreateStatus . InvalidAnswer : return " Resposta invlida para recuperar a senha . " ; case MembershipCreateStatus . InvalidQuestion : return " Questo invlida para recuperar a senha . " ; case MembershipCreateStatus . InvalidUserName : return " Usurio invlido . " ; case MembershipCreateStatus . ProviderError : return " Ocorreu um erro durante a autenticao . Se o problema persistir , contate o administrador . " ; case MembershipCreateStatus . UserRejected : return " O cadastro do usurio foi cancelado . Se o problema persistir , contate o administrador . " ; default : return " Um erro inesperado ocorreu . Se o problema persistir , contate o administrador . " ; } } # endregion } }
Cdigo C# C.27: UsuarioController.cs

184

35

Crie uma pasta Usuario na pasta Views e acrescente os quatro arquivos abaixo.
@model K19CopaDoMundo . Models . ChangePasswordModel @{ ViewBag . Title = " Alterao de senha " ; } < hgroup class = " title " > < h1 > @ViewBag . Title . </ h1 > < h2 > Utilize este formulrio para alterar a sua senha . </ h2 > </ hgroup > <p class = " message - info " > Senhas devem ter no mnimo @Membership . MinRequiredPasswordLength caracteres . </ p > @using ( Html . BeginForm () ) { @Html . ValidationSummary () < fieldset > < legend > Alterao de Senha </ legend > < ol > < li > @Html . LabelFor ( m = > m . OldPassword ) @Html . PasswordFor ( m = > m . OldPassword ) </ li > < li > @Html . LabelFor ( m = > m . NewPassword ) @Html . PasswordFor ( m = > m . NewPassword ) </ li > < li >

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3

184

www.k19.com.br

185
31 32 33 34 35 36 37 38 39 4 41

C.12. C ADASTRANDO E L ISTANDO S ELEES


@Html . LabelFor ( m = > m . ConfirmPassword ) @Html . PasswordFor ( m = > m . ConfirmPassword ) </ li > </ ol > < input type = " submit " value = " Alterar Senha " / > </ fieldset > } @section Scripts { @Scripts . Render ( " ~/ bundles / jqueryval " ) }
Cdigo CSHTML C.10: ChangePassword.cshtml

1 2 3 4 5 6 7 8

@{ ViewBag . Title = " Senha alterada " ; } < hgroup class = " title " > < h1 > @ViewBag . Title . </ h1 > < h2 > Sua senha foi alterada com sucesso . </ h2 > </ hgroup >
Cdigo CSHTML C.11: ChangePasswordSuccess.cshtml

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4

@model K19CopaDoMundo . Models . LoginModel @{ ViewBag . Title = " Log in " ; } < hgroup class = " title " > < h1 > @ViewBag . Title . </ h1 > < h2 > Formulrio de Login </ h2 > </ hgroup > @using ( Html . BeginForm ( new { ReturnUrl = ViewBag . ReturnUrl }) ) { @Html . ValidationSummary ( true , " Login no foi efetuado . Informe os dados corretos . " ) < fieldset > < legend > Formulrio de Login </ legend > < ol > < li > @Html . LabelFor ( m = > m . UserName ) @Html . TextBoxFor ( m = > m . UserName ) </ li > < li > @Html . LabelFor ( m = > m . Password ) @Html . PasswordFor ( m = > m . Password ) </ li > < li > @Html . CheckBoxFor ( m = > m . RememberMe ) @Html . LabelFor ( m = > m . RememberMe , new { @class = " checkbox " }) </ li > </ ol > < input type = " submit " value = " Log in " / > </ fieldset > <p > @Html . ActionLink ( " Registrar " , " Register " ) . </ p > } @section Scripts { @Scripts . Render ( " ~/ bundles / jqueryval " ) }
Cdigo CSHTML C.12: Login.cshtml

www.k19.com.br

185

P ROJETO
1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 @model K19CopaDoMundo . Models . RegisterModel @{ ViewBag . Title = " Cadastro " ; } < hgroup class = " title " > < h1 > @ViewBag . Title . </ h1 > < h2 > Cadastrar </ h2 > </ hgroup > <p class = " message - info " > Senhas devem ter no minimo @Membership . MinRequiredPasswordLength caracteres . </ p > @using ( Html . BeginForm () ) { @Html . ValidationSummary () < fieldset > < legend > Cadastro </ legend > < ol > < li > @Html . LabelFor ( m = > m . UserName ) @Html . TextBoxFor ( m = > m . UserName ) </ li > < li > @Html . LabelFor ( m = > m . Email ) @Html . TextBoxFor ( m = > m . Email ) </ li > < li > @Html . LabelFor ( m = > m . Password ) @Html . PasswordFor ( m = > m . Password ) </ li > < li > @Html . LabelFor ( m = > m . ConfirmPassword ) @Html . PasswordFor ( m = > m . ConfirmPassword ) </ li > </ ol > < input type = " submit " value = " Cadastrar " / > </ fieldset > } @section Scripts { @Scripts . Render ( " ~/ bundles / jqueryval " ) }
Cdigo CSHTML C.13: Register.cshtml

186

36

Adicione o seguinte partial View _LoginPartial.cshtml a pasta Shared.


@if ( Request . IsAuthenticated ) { <p > Ol , @Html . ActionLink ( User . Identity . Name , " ChangePassword " , " Usuario " , routeValues : null , htmlAttributes : new { @class = " username " , title = " Alterar senha " }) ! @Html . ActionLink ( " Sair " , " LogOff " , " Usuario " ) </ p > } else { < ul > < li > @Html . ActionLink ( " Cadastrar " , " Register " , " Usuario " , routeValues : null , htmlAttributes : new { id = " registerLink " }) </ li > < li > @Html . ActionLink ( " Entrar " , " Login " , " Usuario " , routeValues : null , htmlAttributes : new { id = " loginLink " }) </ li > </ ul > }
Cdigo CSHTML C.14: _LoginPartial.cshtml

1 2 3

4 5 6 7 8 9 1 11

186

www.k19.com.br

187
37

C.12. C ADASTRANDO E L ISTANDO S ELEES

Altere o arquivo _Layout.cshtml.


<! DOCTYPE html > < html lang = " en " > < head > < meta charset = " utf -8 " / > < title > Copa do Mundo </ title > < link href = " ~/ __TemplateIcon . ico " rel = " shortcut icon " type = " image /x - icon " / > < meta name = " viewport " content = " width = device - width " / > @Styles . Render ( " ~/ Content / themes / base / css " , " ~/ Content / css " ) @Scripts . Render ( " ~/ bundles / modernizr " ) </ head > < body > < header > < div class = " content - wrapper " > < div class = " float - left " > <p class = " site - title " > < img class = " logo " src = " ~/ Images / k19 - logo . jpg " alt = " K19 Logo " / > </ p > </ div > < div class = " float - right " > < section id = " login " > @Html . Partial ( " _LoginPartial " ) </ section > < nav > < ul id = " menu " > < li > @Html . ActionLink ( " Selecoes " , " Index " , " Selecao " , null , new { @class = " botao " }) </ li > < li > @Html . ActionLink ( " Jogadores " , " Index " , " Jogador " , null , new { @class = " botao " }) </ li > </ ul > </ nav > </ div > </ div > </ header > < div id = " body " > @RenderSection ( " featured " , required : false ) < section class = " content - wrapper main - content clear - fix " > @RenderBody () </ section > </ div > < footer > < div class = " content - wrapper " > < div class = " float - left " > <p >& copy ; @DateTime . Now . Year - K19 Copa do Mundo </ p > </ div > < div class = " float - right " > < ul id = " social " > < li > <a href = " http :// facebook . com / k19treinamentos " class = " facebook " > Facebook - K19 Treinamentos </ a > </ li > < li > <a href = " http :// twitter . com / k19treinamentos " class = " twitter " > Twitter - K19 Treinamentos </ a > </ li > </ ul > </ div > </ div > </ footer > @Scripts . Render ( " ~/ bundles / jquery " ) @RenderSection ( " scripts " , required : false ) </ body > </ html >

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52

Cdigo CSHTML C.15: _Layout.cshtml

www.k19.com.br

187

P ROJETO

188

Adicionando um Usurio Administrador com ASP .NET Conguration


Antes de denir o ltro Authorize nos controladores de nosso site, vamos criar um usurio com acesso. A maneira mais fcil de criar o usurio atravs do ASP .NET Conguration.

Exerccios de Fixao
38 39

Execute o ASP .NET Conguration que ca na aba Solution Explorer do Visual Studio.

Isto executar um ambiente de congurao. Abra a aba Security e clique no link Enable roles.
40 41 42 43

Posteriormente, clique em Create or manage roles. Dena um role Administrador e clique Add Role. Clique no boto back e crie um usurio. Dena um usurio admin e senha admink19!.

Autorizao Role-based
Podemos restringir o acesso as pginas com o ltro Authorize e podemos especicar o role que o usurio precisa ter para ter acesso a pgina.

Exerccios de Fixao
Altere o ltro de autenticao no Web.cong para redirecionar o usurio para a action Login do controlador Usuario.
44

1 2 3

< authentication mode = " Forms " > < forms loginUrl = " ~/ Usuario / Login " timeout = " 288 " / > </ authentication >
Cdigo XML C.2: Web.cong

Acrescente a seguinte string de conexo no arquivo Web.cong para denir o local que as informaes dos usurios sero armazenadas (No nosso caso, teremos duas strings de conexo).
45

1 2 3 4 5 6 7 8 9 1 11

< connectionStrings > < add name = " K19CopaDoMundoContext " providerName = " System . Data . SqlClient " connectionString = " Server =.\ SQLEXPRESS ; Database = k19copadomundo ; User Id = sa ; Password = sa ; Trusted_Connection = False ; MultipleActiveResultSets = True " / > <! -- Definindo o provedor para o Membership -- > < add name = " DefaultConnection " providerName = " System . Data . SqlClient " connectionString = " Server =.\ SQLEXPRESS ; Database = k19copadomundo ; User Id = sa ; Password = sa ; Trusted_Connection = False ; MultipleActiveResultSets = True " / > </ connectionStrings >

188

www.k19.com.br

189

C.12. C ADASTRANDO E L ISTANDO S ELEES

Cdigo XML C.3: Web.cong

Acrescente o ltro de autenticao nos controladores Selecoes e Jogadores atravs do atributo Authorize.
46

1 2

[ Authorize ( Roles = " Administrador " ) ] public class SelecaoController : Controller


Cdigo C# C.28: SelecaoController.cs

1 2

[ Authorize ( Roles = " Administrador " ) ] public class JogadorController : Controller


Cdigo C# C.29: JogadorController.cs

Controle de Erro
Podemos congurar uma pgina de erro padro para ser utilizada toda vez que um erro ocorrer.

Exerccios de Fixao
Acrescente ao arquivo Web.cong a tag customErrors para especicar a pgina de erro padro. A tag customErrors ca dentro da tag system.web.
47

1 2 3 4 5 6 7

< system . web > ... < customErrors mode = " On " defaultRedirect = " ~/ Erro / Desconhecido " > < error statusCode = " 4 4 " redirect = " ~/ Erro / PaginaNaoEncontrada " / > </ customErrors > ... </ system . web >
Cdigo XML C.4: Web.cong

Dena o controlador Erro e as pginas de erros padro. As pginas de erro padro sero criadas dentro da pasta Views numa subpasta Erro.
48

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18

using using using using using

System ; System . Collections . Generic ; System . Linq ; System . Web ; System . Web . Mvc ;

namespace K19CopaDoMundo . Controllers { public class ErroController : Controller { // // GET : / Erro / Desconhecido public ActionResult Desconhecido () { return View () ; }

www.k19.com.br

189

P ROJETO
19 2 21 22 23 24 25 26 27 // // GET : / Erro / PaginaNaoEncontrada public ActionResult PaginaNaoEncontrada () { return View () ; } } }
Cdigo C# C.30: ErroController.cs

190

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15

@{ Layout = null ; } <! DOCTYPE html > < html > < head > < meta name = " viewport " content = " width = device - width " / > < title > Problema no servidor </ title > </ head > < body > < h2 > Desculpe , tivemos problema em nosso servidor . Volte dentro de alguns instantes . </ h2 > </ body > </ html >
Cdigo CSHTML C.16: Desconhecido.cshtml

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15

@{ Layout = null ; } <! DOCTYPE html > < html > < head > < meta name = " viewport " content = " width = device - width " / > < title > Pgina no encontrada </ title > </ head > < body > < h2 > Pgina no encontrada </ h2 > </ body > </ html >
Cdigo CSHTML C.17: PaginaNaoEncontrada.cshtml

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.

@{

190

www.k19.com.br

191
2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 Layout = null ; } <! DOCTYPE html >

C.12. C ADASTRANDO E L ISTANDO S ELEES

< html > < head > < meta name = " viewport " content = " width = device - width " / > < title > Problema no servidor </ title > </ head > < body > < h2 > Desculpe , tivemos problema em nosso servidor . Volte dentro de alguns instantes . </ h2 > <p > Envie uma mensagem para os administradores do sistema . </ p > @using ( Html . BeginForm ( " Envia " , " Email " ) ) { < div class = " editor - label " > @Html . Label ( " Mensagem " ) </ div > < div class = " editor - field " > @Html . TextArea ( " Mensagem " ) </ div > < input type = " submit " value = " Enviar " / > } </ body > </ html >
Cdigo CSHTML C.18: Desconhecido.cshtml

50 Crie um controlador que envie as mensagens por email utilizando o helper WebMail. Observao, utilize usurios, senhas e emails vlidos do gmail para este exerccio.

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33

using using using using using using

System ; System . Collections . Generic ; System . Linq ; System . Web ; System . Web . Mvc ; System . Web . Helpers ;

namespace K19CopaDoMundo . Controllers { public class EmailController : Controller { public EmailController () { WebMail . SmtpServer = " smtp . gmail . com " ; WebMail . EnableSsl = true ; WebMail . SmtpPort = 587; WebMail . From = " USUARIO@gmail . com " ; WebMail . UserName = " USUARIO@gmail . com " ; WebMail . Password = " SENHA " ; } // // POST : / Email / Envia [ HttpPost ] public ActionResult Envia ( string mensagem ) { WebMail . Send ( " EMAIL " , " Copa do Mundo - Erro " , mensagem ) ; return View () ; } } }
Cdigo C# C.31: EmailController.cs

www.k19.com.br

191

P ROJETO
51

192

Crie uma pgina Envia.cshtml para mostrar ao usurio que a mensagem foi enviada com sucesso e acrescente um link para a pgina inicial do site.
1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 @{ Layout = null ; } <! DOCTYPE html > < html > < head > < title > Envia </ title > </ head > < body > < div > Mensagem enviada com sucesso . </ div > < div > @Html . ActionLink ( " Voltar para pgina inicial " , " Index " , " Selecoes " ) </ div > </ body > </ html >
Cdigo CSHTML C.19: Envia.cshtml

192

www.k19.com.br

APNDICE
Cdigo C# 2.9: InsereLivro.cs

R ESPOSTAS

Resposta do Complementar 2.1


1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 using System . Data . Odbc ; namespace Odbc { class InsereLivro { static void Main ( string [] args ) { string stringDeConexao = @ " driver ={ SQL Server }; server = MARCELO - PC \ SQLEXPRESS ; database = livraria ; uid = sa ; pwd = sa ; " ; System . Console . Write ( " Digite o Ttulo do Livro : " ) ; string titulo = System . Console . ReadLine () ; System . Console . Write ( " Digite o Preo do Livro : " ) ; string preco = System . Console . ReadLine () ; System . Console . Write ( " Digite o Id da Editora do Livro : " ) ; string editoraId = System . Console . ReadLine () ; string textoInsereEditora = @ " INSERT INTO Livros ( Titulo , Preco , EditoraId ) VALUES ( " + titulo + @ " , " + preco + @ " , " + editoraId + " ) " ; using ( OdbcConnection conexao = new OdbcConnection ( stringDeConexao ) ) { OdbcCommand command = new OdbcCommand ( textoInsereEditora , conexao ) ; conexao . Open () ; command . ExecuteNonQuery () ; } } } }

Resposta do Complementar 2.3

1 2 3 4 5 6 7 8 9 1 11 12

using System . Data . Odbc ; namespace Odbc { class InsereLivro { static void Main ( string [] args ) { string stringDeConexao = @ " driver ={ SQL Server }; server = MARCELO - PC \ SQLEXPRESS ; database = livraria ; uid = sa ; pwd = sa ; " ; System . Console . Write ( " Digite o Ttulo do Livro : " ) ;

www.k19.com.br

193

R ESPOSTAS
13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 string titulo = System . Console . ReadLine () ; System . Console . Write ( " Digite o Preo do Livro : " ) ; string preco = System . Console . ReadLine () ; System . Console . Write ( " Digite o Id da Editora do Livro : " ) ; string editoraId = System . Console . ReadLine () ; string textoInsereEditora = @ " INSERT INTO Livros ( Titulo , Preco , EditoraId ) VALUES (? ,? ,?) " ; using ( OdbcConnection conexao = new OdbcConnection ( stringDeConexao ) ) { OdbcCommand command = new OdbcCommand ( textoInsereEditora , conexao ) ; command . Parameters . AddWithValue ( " @Titulo " , titulo ) ; command . Parameters . AddWithValue ( " @Preco " , preco ) ; command . Parameters . AddWithValue ( " @EditoraId " , editoraId ) ; conexao . Open () ; command . ExecuteNonQuery () ; } } } }
Cdigo C# 2.14: InsereLivro.cs

194

Resposta do Complementar 2.5

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32

using System . Data . Odbc ; namespace Odbc { class ListaLivro { static void Main ( string [] args ) { string stringDeConexao = @ " driver ={ SQL Server }; server = MARCELO - PC \ SQLEXPRESS ; database = livraria ; uid = sa ; pwd = sa ; " ; using ( OdbcConnection conexao = new OdbcConnection ( stringDeConexao ) ) { string textoListaEditora = " SELECT * FROM Livros " ; OdbcCommand command = new OdbcCommand ( textoListaEditora , conexao ) ; conexao . Open () ; OdbcDataReader resultado = command . ExecuteReader () ; while ( resultado . Read () ) { long ? id = resultado [ " Id " ] as long ?; string titulo = resultado [ " Titulo " ] as string ; double ? preco = resultado [ " Preco " ] as double ?; long ? editoraId = resultado [ " EditoraId " ] as long ?; System . Console . WriteLine ( " { } : {1} - {2} - {3}\ n " , id , titulo , preco , editoraId ) ; } } } } }
Cdigo C# 2.21: ListaLivro.cs

194

www.k19.com.br

195

R ESPOSTAS

Resposta do Complementar 2.6

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34

using System . Data . Odbc ; namespace Odbc { class InsereLivro { static void Main ( string [] args ) { System . Console . Write ( " Digite o Ttulo do Livro : " ) ; string titulo = System . Console . ReadLine () ; System . Console . Write ( " Digite o Preo do Livro : " ) ; string preco = System . Console . ReadLine () ; System . Console . Write ( " Digite o Id da Editora do Livro : " ) ; string editoraId = System . Console . ReadLine () ; string textoInsereEditora = @ " INSERT INTO Livros ( Titulo , Preco , EditoraId ) VALUES (? ,? ,?) " ; using ( OdbcConnection conexao = ConnectionFactory . CreateConnection () ) { OdbcCommand command = new OdbcCommand ( textoInsereEditora , conexao ) ; command . Parameters . AddWithValue ( " @Titulo " , titulo ) ; command . Parameters . AddWithValue ( " @Preco " , preco ) ; command . Parameters . AddWithValue ( " @EditoraId " , editoraId ) ; conexao . Open () ; command . ExecuteNonQuery () ; } } } }
Cdigo C# 2.26: InsereLivro.cs

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26

using System . Data . Odbc ; namespace Odbc { class ListaLivro { static void Main ( string [] args ) { using ( OdbcConnection conexao = ConnectionFactory . CreateConnection () ) { string textoListaEditora = " SELECT * FROM Livros " ; OdbcCommand command = new OdbcCommand ( textoListaEditora , conexao ) ; conexao . Open () ; OdbcDataReader resultado = command . ExecuteReader () ; while ( resultado . Read () ) { long ? id = resultado [ " Id " ] as long ?; string titulo = resultado [ " Titulo " ] as string ; double ? preco = resultado [ " Preco " ] as double ?; long ? editoraId = resultado [ " EditoraId " ] as long ?; System . Console . WriteLine ( " { } : {1} - {2} - {3}\ n " , id , titulo , preco , editoraId ) ; } }

www.k19.com.br

195

R ESPOSTAS
27 28 29 } } }
Cdigo C# 2.27: ListaLivro.cs

196

Resposta do Complementar 5.1

1 2 3 4 5 6 7 8

@{ ViewBag . Title = " Home " ; } @for ( int i = ; i < 1 ; i ++) { < h2 > Ol @i </ h2 > }
Cdigo CSHTML 5.10: Home.cshtml

196

www.k19.com.br