Escolar Documentos
Profissional Documentos
Cultura Documentos
Desenvolvimento Web
com ASP.NET MVC 3
Desenvolvimento Web com ASP.NET MVC
22 de junho de 2011
www.k19.com.br ii
Sumrio
1 Banco de dados 1
1.1 Sistemas gerenciadores de banco de dados . . . . . . . . . . . . . . . . . . . . 1
1.2 SQL Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Bases de dados (Databases) . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3.1 Criando uma base de dados no SQL Server Express . . . . . . . . . . . 2
1.4 Tabelas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4.1 Criando tabelas no SQL Server Express . . . . . . . . . . . . . . . . . 5
1.5 Operaes Bsicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.6 Chaves Primria e Estrangeira . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.7 Consultas Avanadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.8 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2 ADO.NET 29
2.1 Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.2 ODBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.3 ODBC Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.4 Criando uma conexo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.5 Inserindo registros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.6 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.7 SQL Injection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.8 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.9 Listando registros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.10 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.11 Fbrica de conexes (Factory) . . . . . . . . . . . . . . . . . . . . . . . . . . 37
2.12 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
iii
SUMRIO SUMRIO
5 Tratamento de Erros 81
5.1 Try-Catch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
5.2 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
5.3 Custom Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
5.4 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
5.5 Erros do HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
5.6 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
www.k19.com.br iv
SUMRIO SUMRIO
8 Rotas 127
8.1 Adicionando uma rota . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
8.2 Definindo parmetros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
8.3 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
9 Validao 131
9.1 Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
9.2 View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
9.3 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
9.4 Anotaes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
9.4.1 Required . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
9.4.2 Alterando a mensagem . . . . . . . . . . . . . . . . . . . . . . . . . . 139
9.4.3 Outros validadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
9.5 Validao no lado do Cliente . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
9.6 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
10 Sesso 145
10.1 Sesso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
10.1.1 Identificando o Usurio . . . . . . . . . . . . . . . . . . . . . . . . . . 145
10.2 Utilizando Session no ASP.NET . . . . . . . . . . . . . . . . . . . . . . . . . 146
10.3 Session Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
10.4 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
v K19 Treinamentos
SUMRIO SUMRIO
11 Filtros 157
11.1 Filtro de Autenticao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
11.2 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
11.3 Action Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
11.4 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
12 Projeto 161
12.1 Modelo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
12.2 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
12.3 Persistncia - Mapeamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
12.4 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
12.5 Persistncia - Configurao . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
12.6 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
12.7 Persistncia - Repositrios . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
12.8 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
12.8.1 Unit of Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
12.9 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
12.10Apresentao - Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
12.11Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
12.12Cadastrando e Listando Selees . . . . . . . . . . . . . . . . . . . . . . . . . 170
12.13Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
12.14Removendo Selees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
12.15Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
12.16Cadastrando, Listando e Removendo Jogadores . . . . . . . . . . . . . . . . . 175
12.17Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
12.18Removendo Jogadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
12.19Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
12.20Membership e Autorizao . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
12.21Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
12.21.1 Adicionando um Usurio Administrador com ASP .NET Configuration 189
12.22Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
12.22.1 Autorizao Role-based . . . . . . . . . . . . . . . . . . . . . . . . . 191
12.23Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
12.24Controle de Erro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
12.25Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
12.26Enviando email . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
12.27Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
www.k19.com.br vi
Captulo 1
Banco de dados
1
Banco de dados
Oracle
SQL Server
PostgreSQL
www.k19.com.br 2
Banco de dados
3 K19 Treinamentos
Banco de dados
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 confi-
guraes.
Quando uma base de dados no mais necessria, ela pode ser removida atravs do co-
mando DROP DATABASE.
1.4 Tabelas
Um servidor de banco de dados dividido em bases de dados com o intuito de separar
as informaes de sistemas diferentes. Nessa mesma linha de raciocnio, podemos dividir os
dados de uma base a fim de agrup-los segundo as suas correlaes. Essa separao feita
atravs de tabelas. Por exemplo, no sistema de um banco, interessante separar o saldo e o
limite de uma conta, do nome e CPF de um cliente. Ento, poderamos criar uma tabela para
os dados relacionados s contas e outra para os dados relacionados aos clientes.
Clientes
Nome Idade Cpf
Jos 27 31875638735
Maria 32 30045667856
Contas
Numero Saldo Limite
1 1000 500
2 2000 700
www.k19.com.br 4
Banco de dados
5 K19 Treinamentos
Banco de dados
www.k19.com.br 6
Banco de dados
No SQL Server os nomes das tabelas so precedidas pelo ID do usurio que possui a tabela.
No caso do usurio sa, o ID dbo. Portanto o nome da tabela Livros fica dbo.Livros.
Se uma tabela no for mais desejada ela pode ser removida atravs do comando DROP
TABLE.
7 K19 Treinamentos
Banco de dados
www.k19.com.br 8
Banco de dados
9 K19 Treinamentos
Banco de dados
www.k19.com.br 10
Banco de dados
1.8 Exerccios
1. 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.
11 K19 Treinamentos
Banco de dados
2. Caso exista uma base de dados chamada Livraria, remova-a conforme a figura abaixo:
www.k19.com.br 12
Banco de dados
3. Crie uma nova base de dados chamada livraria, conforme mostrado na figura abaixo.
Voc vai utilizar esta base nos exerccios seguintes.
13 K19 Treinamentos
Banco de dados
www.k19.com.br 14
Banco de dados
15 K19 Treinamentos
Banco de dados
Altere os campos para torn-los obrigatrios, NO permitindo que eles fiquem em branco
N U LL.
www.k19.com.br 16
Banco de dados
17 K19 Treinamentos
Banco de dados
www.k19.com.br 18
Banco de dados
19 K19 Treinamentos
Banco de dados
Lembrando de NO marcar a opo ALLOW NULL. Alm disso o campo Id deve ser
uma chave primria e automaticamente incrementada.
Voc precisa tornar o campo EditoraId uma chave estrangeira. Clique com o boto
direito sobre a coluna EditoraId e selecione a opo Relantioships..., conforme a figura
abaixo:
www.k19.com.br 20
Banco de dados
21 K19 Treinamentos
Banco de dados
Devemos informar qual a chave primria que a coluna EditoraId da tabela Livros faz
referncia. 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.
www.k19.com.br 22
Banco de dados
23 K19 Treinamentos
Banco de dados
www.k19.com.br 24
Banco de dados
10. Altere alguns dos registros da tabela Editoras. Veja o exemplo abaixo:
25 K19 Treinamentos
Banco de dados
12. 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:
13. Faa uma consulta para buscar todos os livros de uma determinada editora. Veja um
exemplo na figura abaixo:
www.k19.com.br 26
Banco de dados
27 K19 Treinamentos
Banco de dados
www.k19.com.br 28
Captulo 2
ADO.NET
No captulo anterior, aprendemos que utilizar bancos de dados uma boa soluo para o
armazenamento dos dados do estoque de uma loja virtual. Entretanto, voc deve ter percebido
que a interface de utilizao do SQL Server Express (e dos outros bancos de dados em geral)
no muito amigvel. Ela exige que o usurio conhea a sintaxe do SQL para escrever as
consultas. Alm disso, quando o volume de dados muito grande, mais difcil visualizar os
resultados.
Na prtica uma aplicao com interface simples desenvolvida para permitir que os usu-
rios do sistema possam manipular os dados do banco. De alguma forma, essa aplicao precisa
se comunicar com o banco de dados utilizado no sistema.
Nesse captulo vamos desenvolver uma aplicao para acessar os dados do estoque da nossa
loja virtual.
2.1 Driver
Como a aplicao precisa conversar com o banco de dados, ela deve trocar mensagens
com o mesmo. O formato das mensagens precisa ser definido previamente. Por questes de
economia de espao, cada bit de uma mensagem tem um significado diferente. Em outras
palavras, o protocolo de comunicao binrio.
Mensagens definidas com protocolos binrios so facilmente interpretadas por computado-
res. Por outro lado, so complexas para um ser humano compreender. Dessa forma, mais
trabalhoso e mais suscetvel a erro desenvolver uma aplicao que converse com um banco de
dados atravs de mensagens binrias.
Para resolver esse problema e facilitar o desenvolvimento de aplicaes que devem se co-
municar com bancos de dados, as empresas que so proprietrias desses bancos oferecem os
drivers de conexo.
Os drivers de conexo atuam como tradutores de comandos escritos em uma determinada
linguagem de programao para comandos no protocolo do banco de dados. Do ponto de vista
do desenvolvedor da aplicao, no necessrio conhecer o complexo protocolo binrio do
banco.
Em alguns casos, o protocolo binrio de um determinado banco de dados fechado. Con-
sequentemente, a nica maneira de se comunicar com o banco de dados atravs de um driver
de conexo.
29
ADO.NET
2.2 ODBC
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 30
ADO.NET
31 K19 Treinamentos
ADO.NET
Aps a definio da string de conexo, podemos utilizar a classe do .NET Framework que
responsvel por criar conexes ODBC. Esta classe que vamos utilizar a System.Data.Odbc.OdbcConnection.
Por fim, o comando pode ser executado atravs do mtodo ExecuteNonQuery. A conexo
deve ser aberta antes de executar o comando.
1 conexao.Open();
2 comando.ExecuteNonQuery();
Se a aplicao mantiver as conexes abertas o banco de dados pode deixar de atender outras
aplicaes pois h um limite de conexes que o banco pode suportar. Portanto, importante
que as conexes sejam fechadas quando no forem mais necessrias.
1 conexao.Close();
2.6 Exerccios
1. Crie um projeto do tipo Console Application no Microsoft Visual C# Express, chamado
ODBC.
www.k19.com.br 32
ADO.NET
1 using System.Data.Odbc;
2
3 namespace Odbc
4 {
5 class InsereEditora
6 {
7 static void Main(string[] args)
8 {
9 string stringDeConexao = @"driver={SQL Server};
10 server=MARCELO-PC\SQLEXPRESS;database=livraria;uid=sa;pwd=sa;";
11
12
13
14 using (OdbcConnection conexao = new OdbcConnection(stringDeConexao))
15 {
16 string textoInsereEditora =
17 "INSERT INTO Editoras (Nome, Email) Values(Abril, abril@email.com)"-
;
18 OdbcCommand command = new OdbcCommand(textoInsereEditora, conexao);
19 conexao.Open();
20 command.ExecuteNonQuery();
21
22 // A Conexao eh automaticamente fechada
23 // ao final do bloco Using.
24 }
25 }
26 }
27 }
33 K19 Treinamentos
ADO.NET
O problema de SQL Injection pode ser resolvido manualmente. Basta fazer escape dos
caracteres especiais, por exemplo: ponto-e-vrgula e apstrofo. No MySQL Server, os carac-
teres especiais devem ser precedidos pelo caracter \. Ento seria necessrio acrescentar \ em
todas as ocorrncias de caracteres especiais nos valores passados pelo usurio.
Esse processo, alm de trabalhoso, diferente para cada banco de dados, pois o \ no
padronizado e cada banco tem o seu prprio mtodo de escape de caracteres especiais.
Tornando mais prtica a comunicao com o banco de dados o prprio driver faz o trata-
mento das sentenas SQL. Esse processo denominado sanitize.
Observe que a sentena SQL foi definida com parmetros atravs do caracter ?. 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.
2.8 Exerccios
4. Tente causar um erro de SQL Injection na classe feita no exerccio de inserir editoras.
(Dica: tente entradas com aspas simples)
5. Altere o cdigo para eliminar o problema do SQL Injection. Voc deve deixar a classe
com o cdigo abaixo:
www.k19.com.br 34
ADO.NET
1 using System;
2 using System.Data.Odbc;
3
4
5 namespace Odbc
6 {
7 class InsereEditora
8 {
9 static void Main(string[] args)
10 {
11 string stringDeConexao = @"driver={SQL Server};
12 server=MARCELO-PC\SQLEXPRESS;database=livraria;uid=sa;pwd=sa;";
13
14
15 Console.WriteLine("Abrindo conexao...");
16 using (OdbcConnection conexao = new OdbcConnection(stringDeConexao))
17 {
18 string textoInsereEditora =
19 "INSERT INTO Editoras (Nome, Email) Values(?, ?)";
20 Console.WriteLine("Digite o nome da Editora:");
21 string nome = Console.ReadLine();
22 Console.WriteLine("Digite o email da Editora:");
23 string email = Console.ReadLine();
24 OdbcCommand command = new OdbcCommand(textoInsereEditora, conexao);
25 command.Parameters.AddWithValue("@Nome", nome);
26 command.Parameters.AddWithValue("@Email", email);
27 conexao.Open();
28 command.ExecuteNonQuery();
29
30 // A Conexao eh automaticamente fechada
31 // ao final do bloco Using.
32 }
33 }
34 }
35 }
6. Agora tente causar novamente o problema de SQL Injection ao inserir novas editoras.
35 K19 Treinamentos
ADO.NET
O prprio mtodo Read devolve um valor booleano para indicar se o reader conseguiu
avanar para o prximo registro. Quando esse mtodo devolver false significa que no h mais
registros para serem consultados.
1 while(resultado.Read())
2 {
3 string nome = resultado["nome"] as string;
4 string email = resultado["email"] as string;
5 }
2.10 Exerccios
7. Insira algumas editoras utilizando a classe I NSERE E DITORA que voc criou nos exerc-
cios acima.
8. Adicione uma nova classe ao projeto chamada ListaEditora. O objetivo listar as edi-
toras que foram salvas no banco. Adicione o seguinte cdigo esta classe.
www.k19.com.br 36
ADO.NET
1 using System;
2 using System.Data.Odbc;
3
4 namespace Odbc
5 {
6 class ListaEditora
7 {
8 static void Main(string[] args)
9 {
10 string stringDeConexao = @"driver={SQL Server};
11 server=MARCELO-PC\SQLEXPRESS;database=livraria;uid=sa;pwd=sa;";
12
13
14 Console.WriteLine("Abrindo conexao...");
15 using (OdbcConnection conexao = new OdbcConnection(stringDeConexao))
16 {
17 string textoListaEditora =
18 "SELECT * FROM Editoras";
19 OdbcCommand command = new OdbcCommand(textoListaEditora, conexao);
20 conexao.Open();
21 OdbcDataReader resultado = command.ExecuteReader();
22
23 while (resultado.Read())
24 {
25 long? id = resultado["Id"] as long?;
26 string nome = resultado["Nome"] as string;
27 string email = resultado["Email"] as string;
28 Console.WriteLine("{0} : {1} - {2}\n",id,nome,email);
29 }
30 // A Conexao eh automaticamente fechada
31 // ao final do bloco Using.
32 }
33 }
34 }
35 }
Voc deve ter percebido que para cada ao executada no banco de dados, ns precisamos
criar uma conexo. Isso gera um problema relacionado string de conexo ficar armazenada
em diversos locais. Imagine que o driver do banco foi atualizado e mudamos a sua verso.
Isso implicaria fazer diversas alteraes no cdigo em cada ocorrncia da string de conexo,
tornando o cdigo mais suscetvel a erros e dificultando a sua manuteno.
Para resolver esta situao, ns poderamos criar uma classe responsvel pela criao e
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.
37 K19 Treinamentos
ADO.NET
2.12 Exerccios
9. Adicione uma nova classe chamada FABRICA D E C ONEXAO e adicione o seguinte cdigo:
www.k19.com.br 38
ADO.NET
1 using System;
2 using System.Data.Odbc;
3 using System.Text;
4
5 namespace Odbc
6 {
7 static class FabricaDeConexao
8 {
9 public static OdbcConnection CriaConexao()
10 {
11 string driver = @"SQL Server";
12 string servidor = @"MARCELO-PC\SQLEXPRESS";
13 string baseDeDados = @"livraria";
14 string usuario = @"sa";
15 string senha = @"sa";
16
17 StringBuilder connectionString = new StringBuilder();
18 connectionString.Append("driver=");
19 connectionString.Append(driver);
20 connectionString.Append(";server=");
21 connectionString.Append(servidor);
22 connectionString.Append(";database=");
23 connectionString.Append(baseDeDados);
24 connectionString.Append(";uid=");
25 connectionString.Append(usuario);
26 connectionString.Append(";pwd=");
27 connectionString.Append(senha);
28
29 return new OdbcConnection(connectionString.ToString());
30 }
31 }
32 }
10. Altere as classes I NSERE E DITORA e L ISTA E DITORA para que elas utilizem a fbrica de
conexo. Execute-as novamente.
11. (Opcional) Implemente um teste que remove uma editora pelo id.
12. (Opcional) Implemente um teste que altera os dados de uma editora pelo id.
39 K19 Treinamentos
ADO.NET
www.k19.com.br 40
Captulo 3
41
Entity Framework 4.1
3.4 Configurao
Antes de comear a utilizar o Entity Framework, necessrio baixar no site a verso 4.1:
(http://www.microsoft.com/downloads/details.aspx?FamilyID=b41c728e-9b4f
3.5 Mapeamento
Um dos principais objetivos dos frameworks ORM estabelecer o mapeamento entre os
conceitos do modelo orientado a objetos e os conceitos do modelo entidade relacionamento.
Este mapeamento pode ser definido atravs de xml ou de maneira mais prtica com DbContext.
Quando utilizamos DbContext, evitamos a criao de extensos arquivos em xml.
Podemos definir as seguintes entidades:
1
2 public class Livro
3 {
4 public int LivroId { get; set; }
5 public string Titulo { get; set; }
6 public decimal Preco { get; set; }
7 public Editora Editora { get; set; }
8 }
9
10 public class Editora
11 {
12 public int EditoraId { get; set; }
13 public string Nome { get; set; }
14 public string Email { get; set; }
15 public ICollection<Livro> Livros { get; set; }
16 }
Criaremos agora uma classe para ajudar a mapear as entidades para um banco de dados. A
classe EditoraContext deriva de DbContext que faz parte da biblioteca Code First:
Utilizamos o padro EF4 Code First para permitir a persistncia no banco de dados. Isto
significa que as propriedades Editoras e Livros sero mapeadas para tabelas com mesmo nome
banco de dados. Cada propriedade definida na entidade Livro e Editora mapeada para colu-
nas das tabelas Livros e Editoras.
Abaixo segue a definio da tabela Editoras que foi criada em nosso banco de dados:
www.k19.com.br 42
Entity Framework 4.1
Abaixo segue a definio da tabela Livros que foi criada em nosso banco de dados:
43 K19 Treinamentos
Entity Framework 4.1
1
2 public class Livro
3 {
4
5 public int LivroId { get; set; }
6 public string Titulo { get; set; }
7 public decimal Preco { get; set; }
8 [ForeignKey("Editora")]
9 public int EditoraId { get; set; }
10 public Editora Editora { get; set; }
11 }
12
13 public class Editora
14 {
15 public int EditoraId { get; set; }
16 public string Nome { get; set; }
17 public string Email { get; set; }
18 public ICollection<Livro> Livros { get; set; }
19 }
Por exemplo, suponha que tenhamos uma entidade Pessoa pode ser autor ou revisor de
um livro. Uma pessoa pode ter livros publicados e livros revisados, portanto a entidade
Pessoa tem dois relacionamentos diferentes com a entidade Livro.
1
2 public class Pessoa
3 {
4 public int Id { get; set; }
5 public string Nome { get; set; }
6 public ICollection<Livro> LivrosPublicados { get; set; }
7 public ICollection<Livro> LivrosRevisados { get; set; }
8 }
9
10 public class Livro
11 {
12
13 public int LivroId { get; set; }
14 public string Titulo { get; set; }
15 public decimal Preco { get; set; }
16 public Editora Editora { get; set; }
17
18 [InverseProperty("LivrosPublicados")]
19 public Pessoa Autor { get; set; }
20
21 [InverseProperty("LivrosRevisados")]
22 public Pessoa Revisor { get; set; }
23 }
Se a classe define propriedades com ID ou Id, ou nome da classe seguido por ID ou Id,
esta propriedade tratada como chave primria por conveno.
www.k19.com.br 44
Entity Framework 4.1
1
2 public class Pessoa
3 {
4 [Key]
5 public int Identificador { get; set; }
6 public string Nome { get; set; }
7 public ICollection<Livro> LivrosPublicados { get; set; }
8 public ICollection<Livro> LivrosRevisados { get; set; }
9 }
1
2 public class Editora
3 {
4 public int EditoraId { get; set; }
5 public string Nome { get; set; }
6 public string Email { get; set; }
7 [NotMapped]
8 public string ExtraInfo { get; set; }
9 public ICollection<Livro> Livros { get; set; }
10 }
45 K19 Treinamentos
Entity Framework 4.1
RequiredAttribute Define que este campo obrigatrio. Este atributo ignorado em propri-
edades do tipo collection. Quando definido numa referncia, indica que cardinalidade
1 e a propriedade da chave estrangeira no-nula.
1
2 public class Editora
3 {
4 public int EditoraId { get; set; }
5 [Required]
6 public string Nome { get; set; }
7 public string Email { get; set; }
8 public string ExtraInfo { get; set; }
9 public ICollection<Livro> Livros { get; set; }
10 }
1
2 [Table("Livros")]
3 public class Livro
4 {
5 public int LivroId { get; set; }
6 public string Titulo { get; set; }
7 public decimal Preco { get; set; }
8 public Editora Editora { get; set; }
9 public Pessoa Autor { get; set; }
10 public Pessoa Revisor { get; set; }
11 }
1
2 EditoraContext context = new EditoraContext();
3 // Neste momento ser criado o banco de dados, caso no exista
4 context.Editoras.Add(new Editora{ Nome = "Abril" });
A poltica de criao das tabelas pode ser alterada atravs do mtodo de classe (esttico)
System.Data.Entity.Database.SetInitializer<TypeContext>. Neste mtodo devemos passar ins-
tncias do tipo System.Data.Entity.IDatabaseInitializer. No EF 4.1 temos 3 classes que defi-
nem estratgias para criao do banco de dados: DropCreateDatabaseAlways criar o banco
de dados a cada instncia criada do contexto, ideal para ambiente de testes. CreateDataba-
seIfNotExists somente criar o banco de dados, caso ele no exista, este a estratgia padro.
www.k19.com.br 46
Entity Framework 4.1
3.7 Exerccios
47 K19 Treinamentos
Entity Framework 4.1
www.k19.com.br 48
Entity Framework 4.1
1
2 namespace EF4_Code_First
3 {
4 public class Editora
5 {
6 public int Id { get; set; }
7 public string Nome { get; set; }
8 public string Email { get; set; }
9
10 }
11 }
4. Defina uma classe EditoraContext que derivada de DbContext. Nesta classe defina uma
propriedade Editoras do tipo genrico DbSet<Editora>.
49 K19 Treinamentos
Entity Framework 4.1
1
2 using System.Data.Entity;
3
4 namespace EF4_Code_First
5 {
6 public class EditoraContext : DbContext
7 {
8 public DbSet<Editora> Editoras { get; set; }
9 }
10 }
1
2 namespace EF4_Code_First
3 {
4 class GeraTabelas
5 {
6 static void Main(string[] args)
7 {
8 using (var context = new EditoraContext())
9 {
10 // Neste momento as tabelas so geradas
11 context.Editoras.Add(new Editora { Nome = "Abril", Email = "abril@email-
.com" });
12 }
13 }
14 }
15 }
Atravs do SQL Server Management Express verifique se a tabela E DITORAS foi criada
corretamente.
1
2 <connectionStrings>
3 <add
4 name="EditoraContext" providerName="System.Data.SqlClient"
5 connectionString="Server=.\SQLEXPRESS;Database=livraria;
6 Trusted_Connection=true;Integrated Security=True;MultipleActiveResultSets=True"/>
7 </connectionStrings>
Quando a aplicao for executada, o banco de dados livraria ser criado. Devemos habilitar
a opo MultipleActiveResultSets=True para permitir a leitura de objetos relacionados em
www.k19.com.br 50
Entity Framework 4.1
blocos foreach do C#, pois o EF tenta criar um novo leitor de dados e ocorrer uma falha de
execuo a menos que a opo MultipleActiveResultSets seja true. Uma outra maneira de fazer
a leitura dos objetos relacionados dentro do bloco foreach atravs de uma List, que fecha o
leitor de dados e permite voc percorrer a coleo e acessar os objetos relacionados.
3.9 Exerccios
6. Remova o banco de dados EF4_Code_First.EditoraContext.
7. Sobrescreva a conveno do Code First para nome de banco de dados. Para isto acres-
cente ao projeto EF4-Code-First o arquivo App.config com a definio da string de
conexo.
1
2 var context = new EditoraContext();
3.10.1 Persistindo
Para armazenar as informaes de um objeto no banco de dados basta utilizar o mtodo S A -
VE C HANGES () do D B C ONTEXT. As entidades com o estado Added so inseridas no banco de
dados quando o mtodo S AVE C HANGES () chamado. Utilize o mtodo System.Data.Entity.DbSet.Add.
O mtodo Add adiciona a entidade ao contexto com o estado Added.
3.10.2 Buscando
Para obter um objeto que contenha informaes do banco de dados basta utilizar o mtodo
Find do D B S ET.
51 K19 Treinamentos
Entity Framework 4.1
3.10.3 Removendo
3.10.4 Atualizando
3.10.5 Listando
Para obter uma listagem com todos os objetos referentes aos registros de uma tabela, pode-
mos utilizar o Language Integrated Query LIN Q, que permite os desenvolvedores escreverem
a consulta em C#.
3.11 Exerccios
8. Crie um teste para inserir editoras no banco de dados.
www.k19.com.br 52
Entity Framework 4.1
1 using System;
2
3 namespace EF4_Code_First
4 {
5 class InsereEditoraComEF
6 {
7 static void Main(string[] args)
8 {
9 using (var context = new EditoraContext())
10 {
11 Editora editora = new Editora();
12 Console.WriteLine("Digite o nome da Editora:");
13 editora.Nome = Console.ReadLine();
14 Console.WriteLine("Digite o email da Editora:");
15 editora.Email = Console.ReadLine();
16 //Adiciona editora ao contexto
17 //Status: Added
18 context.Editoras.Add(editora);
19
20 //Persisto editora
21 context.SaveChanges();
22 }
23 }
24 }
25 }
1 using System;
2 using System.Linq;
3
4 namespace EF4_Code_First
5 {
6 class ListaEditoraComEF
7 {
8 static void Main(string[] args)
9 {
10 using (EditoraContext context = new EditoraContext())
11 {
12 var consulta = from e in context.Editoras
13 select e;
14 foreach (var item in consulta)
15 {
16 Console.WriteLine("{0}: {1} - {2}", item.Id,item.Nome,item.Email);
17 }
18 }
19 }
20 }
21 }
3.12 Repository
A classe D B C ONTEXT e D B S ET do EF oferece recursos suficientes para que os objetos
do domnio sejam recuperados ou persistidos no banco de dados. Porm, em aplicaes com
alta complexidade e grande quantidade de cdigo, espalhar as chamadas aos mtodos do
D B C ONTEXT e D B S ET pode gerar dificuldades 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
53 K19 Treinamentos
Entity Framework 4.1
Driven Design).
Conceitualmente, um repositrio representa o conjunto de todos os objetos de um determi-
nado tipo. Ele deve oferecer mtodos para recuperar e para adicionar 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 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Data.Entity;
5
6 namespace EF4_Code_First
7 {
8 public class EditoraRepository
9 {
10 DbContext context;
11
12 public EditoraRepository(DbContext context)
13 {
14 this.context = context;
15 }
16
17 public void Adiciona(Editora e)
18 {
19 context.Set<Editora>().Add(e);
20 context.SaveChanges();
21 }
22
23 public Editora Busca(int id)
24 {
25 return context.Set<Editora>().Find(id);
26 }
27
28 public List<Editora> BuscaTodas()
29 {
30 var consulta = from e in context.Set<Editora>()
31 select e;
32 return consulta.ToList();
33 }
34
35 }
36 }
1 Database.SetInitializer<EditoraContext>(new DropCreateDatabaseIfModelChanges<-
EditoraContext>());
2
3 var context = new EditoraContext();
4
5 EditoraRepository repository = new EditoraRepository(context);
6
7 List<Editora> editoras = repository.BuscaTodas();
3.13 Exerccios
10. Implemente um repositrio de editoras criando uma nova classe no projeto EF4-Code-
First.
www.k19.com.br 54
Entity Framework 4.1
11. Altere a classe InsereEditoraComEF para que ela utilize o repositrio de editoras.
1 using System;
2
3 namespace EF4_Code_First
4 {
5 class InsereEditoraComEF
6 {
7 static void Main(string[] args)
8 {
9 var context = new EditoraContext();
10 EditoraRepository repository = new EditoraRepository(context);
11
12 Editora editora = new Editora();
13 Console.WriteLine("Digite o nome da Editora:");
14 editora.Nome = Console.ReadLine();
15 Console.WriteLine("Digite o email da Editora:");
16 editora.Email = Console.ReadLine();
17
18 repository.Adiciona(editora);
19
20 }
21 }
22 }
12. (Opcional) Altere a classe ListaEditoraComEF para que ela utilize o repositrio de
editoras.
55 K19 Treinamentos
Entity Framework 4.1
www.k19.com.br 56
Captulo 4
57
Viso Geral do ASP .NET MVC
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 3 Web Application.
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.
www.k19.com.br 58
Viso Geral do ASP .NET MVC
1 // LivrariaVirtual/Controllers/SaudacaoController.cs
2 using System;
3 using System.Web.Mvc;
4 using System.Web.Routing;
5
6 namespace LivrariaVirtual.Controllers
7 {
8 public class SaudacaoController : Controller
9 {
10 public string Index()
11 {
12 return "Welcome to ASP.NET MVC!";
13 }
14 }
15 }
Por padro, a url que deve ser utilizada para enviar uma requisio a um controlador
a concatenao da url principal da aplicao seguido do nome do controlador (ex: http:
//localhost/Saudacao).
Por conveno, o arquivo cs contendo o cdigo da classe do controlador deve ser colocado
na pasta Controllers.
59 K19 Treinamentos
Viso Geral do ASP .NET MVC
4.5 Exerccios
1. Crie um projeto do tipo ASP.NET MVC 3 Web Application chamado LivrariaVirtual.
Crie um Empty Project.
2. Implemente uma pgina de saudao criando uma classe dentro da pasta Controllers
chamada SaudacaoController.
1 using System.Web.Mvc;
2
3 namespace LivrariaVirtual.Controllers
4 {
5 public class SaudacaoController : Controller
6 {
7 //
8 // GET: /Saudacao/
9
10 public string Index()
11 {
12 return "Welcome to ASP.NET MVC!";
13 }
14
15 }
16 }
4.7 Exerccios
3. Altere a pgina inicial da nossa aplicao para a pgina de saudao criada no exerccio
anterior.
www.k19.com.br 60
Viso Geral do ASP .NET MVC
4.9 Exerccios
1
2 using System.Collections.Generic;
3
4 namespace LivrariaVirtual.Models
5 {
6 public class Editora
7 {
8 public int Id { get; set; }
9 public string Nome { get; set; }
10 public string Email { get; set; }
11 public virtual ICollection<Livro> Livros { get; set; }
12 }
13 }
1
2 namespace LivrariaVirtual.Models
3 {
4 public class Livro
5 {
6 public int Id { get; set; }
7 public string Titulo { get; set; }
8 public decimal Preco { get; set; }
9 public int EditoraId { get; set; }
10 public virtual Editora Editora { get; set; }
11 }
12 }
1
2 using System.Data.Entity;
3
4 namespace LivrariaVirtual.Models
5 {
6 public class LivrariaVirtualContext : DbContext
7 {
8 public DbSet<Editora> Editoras { get; set; }
9 public DbSet<Livro> Livros { get; set; }
10 }
11 }
61 K19 Treinamentos
Viso Geral do ASP .NET MVC
1
2 using System.Collections.Generic;
3 using System.Linq;
4
5 namespace LivrariaVirtual.Models
6 {
7 public class LivroRepository
8 {
9 private LivrariaVirtualContext context = new LivrariaVirtualContext();
10
11 public void Adiciona(Livro e)
12 {
13 context.Livros.Add(e);
14 context.SaveChanges();
15 }
16
17 public Livro Busca(int id)
18 {
19 return context.Livros.Find(id);
20 }
21
22 public List<Livro> BuscaTodas()
23 {
24 var consulta = from e in context.Livros
25 select e;
26 return consulta.ToList();
27 }
28 }
29 }
1
2 using System.Collections.Generic;
3 using System.Linq;
4
5 namespace LivrariaVirtual.Models
6 {
7 public class EditoraRepository
8 {
9 private LivrariaVirtualContext context = new LivrariaVirtualContext();
10
11 public void Adiciona(Editora e)
12 {
13 context.Editoras.Add(e);
14 context.SaveChanges();
15 }
16
17 public Editora Busca(int id)
18 {
19 return context.Editoras.Find(id);
20 }
21
22 public List<Editora> BuscaTodas()
23 {
24 var consulta = from e in context.Editoras
25 select e;
26 return consulta.ToList();
27 }
28 }
29 }
www.k19.com.br 62
Viso Geral do ASP .NET MVC
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5 using System.Web.Mvc;
6 using LivrariaVirtual.Models;
7
8 namespace LivrariaVirtual.Controllers
9 {
10 public class EditorasController : Controller
11 {
12 //
13 // GET: /Editoras/
14
15 public ActionResult Index()
16 {
17 var editoraRepository = new EditoraRepository();
18
19 return View(editoraRepository.BuscaTodas());
20 }
21
22 }
23 }
Repare que o controlador responsvel pela lista de editoras interage com o repository de
Editora. Alm disso, ele envia uma lista de editoras para a pgina atravs do mtodo View.
Para listar as editoras que foram passados como parmetro pelo EditorasController de-
vemos criar uma pgina com o mesmo nome da action Index. Alm disso, esta pgina deve
ser criada, por conveno, dentro de uma pasta Editoras, pasta com o mesmo nome do nosso
controller sem o sufixo Controller, dentro da pasta Views.
63 K19 Treinamentos
Viso Geral do ASP .NET MVC
www.k19.com.br 64
Viso Geral do ASP .NET MVC
1
2 @model IList<LivrariaVirtual.Models.Editora>
3
4 @{
5 ViewBag.Title = "Editoras";
6 }
7
8 <h2>Editoras</h2>
9
10 <table>
11 <tr>
12 <th>
13 Nome
14 </th>
15 <th>
16 Email
17 </th>
18 <th></th>
19 </tr>
20
21 @foreach (var item in Model) {
22 <tr>
23 <td>
24 @Html.DisplayFor(modelItem => item.Nome)
25 </td>
26 <td>
27 @Html.DisplayFor(modelItem => item.Email)
28 </td>
29 <td>
30 @Html.ActionLink("Edit", "Edit", new { id=item.Id })
31 </td>
32 </tr>
33 }
34
35 </table>
Para gerar o contedo dinmico de nossa pgina, estamos utilizando Razor que permite
acrescentar cdigo de servidor juntamente com cdigo HTML de forma mais clara e concisa.
No ASP .NET MVC temos os Helpers que so classes que facilitam a criao de uma pgina
e renderizao de elementos HTML. Na nossa pgina Index estamos utilizando a propriedade
Html que uma instncia da classe System.Web.Mvc.HtmlHelper que prov mtodos para
renderizar elementos como input, select, anchor, form. Veremos com mais detalhes os Helpers
e Razor nos captulos posteriores.
4.11 Exerccios
5. Implemente um controlador chamado EditorasController para que liste todas as editoras
existentes na base de dados quando a url /Editoras for requisitada.
65 K19 Treinamentos
Viso Geral do ASP .NET MVC
formulrio de cadastro de editora e outro de livro. Por exemplo, suponha que para criar uma
editora devemos acessar a url /Editoras/Create. Primeiro devemos criar uma mtodo para action
Create no nosso controlador EditorasController que redirecionar para a pgina que contm o
formulrio, quando acessarmos a url /Editoras/Create pelo browser atravs de requisio GET.
Por conveno, o nome do mtodo o mesmo nome da action.
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5 using System.Web.Mvc;
6 using LivrariaVirtual.Models;
7
8 namespace LivrariaVirtual.Controllers
9 {
10 public class EditorasController : Controller
11 {
12 //
13 // GET: /Editoras/
14
15 public ActionResult Index()
16 {
17 var editoraRepository = new EditoraRepository();
18
19 return View(editoraRepository.BuscaTodas());
20 }
21
22 //
23 // GET: /Editoras/Create
24
25 public ActionResult Create()
26 {
27 return View();
28 }
29
30 }
31 }
Devemos agora criar a pgina que contm o formulrio para inserir uma editora. Por padro,
esta pgina dever ser criada na pasta View/Editoras com o mesmo nome da action, portanto
deveremos ter um arquivo com o nome Create.cshtml.
www.k19.com.br 66
Viso Geral do ASP .NET MVC
1 @model LivrariaVirtual.Models.Editora
2
3 @{
4 ViewBag.Title = "Create";
5 }
6
7 <h2>Create</h2>
8 @using (@Html.BeginForm())
9 {
10 <fieldset>
11 <legend>Editora</legend>
12
13 <div class="editor-label">
14 @Html.LabelFor(model => model.Nome)
15 </div>
16 <div class="editor-field">
17 @Html.EditorFor(model => model.Nome)
18 </div>
19
20 <div class="editor-label">
21 @Html.LabelFor(model => model.Email)
22 </div>
23 <div class="editor-field">
24 @Html.EditorFor(model => model.Email)
25 </div>
26
27 <p>
28 <input type="submit" value="Create" />
29 </p>
30 </fieldset>
31 }
Quando o usurio clicar no boto "submit", uma action dever receber a requisio com
os dados preenchidos no formulrio pelo usurio. Os dados sero enviados atravs de uma
requisio POST, por padro , e deveremos ter uma action Create que receber os dados de
uma requisio POST. Por conveno, deveremos ter no nosso controlador um mtodo com o
mesmo nome da action e restringiremos o mtodo para tratar somente requisies POST com
a anotao HttpPost. Neste mtodo faremos a insero da editora atravs da classe Editora-
Repository.
67 K19 Treinamentos
Viso Geral do ASP .NET MVC
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5 using System.Web.Mvc;
6 using LivrariaVirtual.Models;
7
8 namespace LivrariaVirtual.Controllers
9 {
10 public class EditorasController : Controller
11 {
12 private EditoraRepository editoraRepository = new EditoraRepository();
13 //
14 // GET: /Editoras/
15
16 public ActionResult Index()
17 {
18 return View(this.editoraRepository.BuscaTodas());
19 }
20
21 //
22 // GET: /Editoras/Create
23
24 public ActionResult Create()
25 {
26 return View();
27 }
28
29 //
30 // POST: /Editoras/Create
31
32 [HttpPost]
33 public ActionResult Create(Editora editora)
34 {
35
36 editoraRepository.Adiciona(editora);
37 return RedirectToAction("Index");
38
39 }
40
41 }
42 }
4.13 Exerccios
7. Crie um mtodo para action Create no nosso controlador EditorasController respons-
vel por apresentar um formulrio de cadastramento de editoras. Este formulrio dever
ser acessado atravs de uma URL /Editoras/Create. Ao enviar os dados do formulrio
para o servidor atravs de uma requisio POST, defina um mtodo para esta action que
receba estes dados enviados pelo usurio e salve na base de dados utilizando a nossa
classe EditoraRepository.
www.k19.com.br 68
Viso Geral do ASP .NET MVC
Devemos permitir que o usurio possa definir a editora a qual o livro pertence. Para
isto, devemos ter uma caixa de seleo com todas as editoras da nossa base de dados.
Antes de criar a caixa de seleo, devemos enviar uma lista para a nossa View, atravs
da propriedade ViewBag, com todas as editoras da nossa base de dados.
1
2 using System;
3 using System.Collections.Generic;
4 using System.Data;
5 using System.Data.Entity;
6 using System.Linq;
7 using System.Web;
8 using System.Web.Mvc;
9 using LivrariaVirtual.Models;
10
11 namespace LivrariaVirtual.Controllers
12 {
13 public class LivrosController : Controller
14 {
15 private LivroRepository livroRepository = new LivroRepository();
16 private EditoraRepository editoraRepository = new EditoraRepository();
17
18 //
19 // GET: /Livros/
20
21 public ViewResult Index()
22 {
23
24 return View(livroRepository.BuscaTodas());
25 }
26
27 //
28 // GET: /Livros/Create
29
30 public ActionResult Create()
31 {
32 var consulta = editoraRepository.BuscaTodas().Select(e => new { e.Id, e.-
Nome});
33 ViewBag.Editoras = consulta.ToList();
34 return View();
35 }
36
37 //
38 // POST: /Livros/Create
39
40 [HttpPost]
41 public ActionResult Create(Livro livro)
42 {
43 livroRepository.Adiciona(livro);
44 return RedirectToAction("Index");
45 }
46
47
48
49
50 }
51 }
69 K19 Treinamentos
Viso Geral do ASP .NET MVC
1
2 @model LivrariaVirtual.Models.Livro
3
4 @{
5 ViewBag.Title = "Insere Livro";
6 }
7
8 <h2>Insere Livro</h2>
9
10 @using (Html.BeginForm()) {
11 <fieldset>
12 <legend>Livro</legend>
13
14 <div class="editor-label">
15 @Html.LabelFor(model => model.Titulo)
16 </div>
17 <div class="editor-field">
18 @Html.EditorFor(model => model.Titulo)
19 </div>
20
21 <div class="editor-label">
22 @Html.LabelFor(model => model.Preco)
23 </div>
24 <div class="editor-field">
25 @Html.EditorFor(model => model.Preco)
26 </div>
27 <div class="editor-label">
28 @Html.LabelFor(model => model.EditoraId)
29 </div>
30 <div class="editor-field">
31 @Html.DropDownListFor(model => model.EditoraId,new SelectList(@ViewBag.-
Editoras, "Id", "Nome"))
32 </div>
33
34 <p>
35 <input type="submit" value="Create" />
36 </p>
37 </fieldset>
38 }
Normalmente surge a necessidade de atualizar os dados de uma editora ou livro. Por exem-
plo, uma atualizao dos preos. Portanto, a nossa aplicao deve permitir que o usurio faa
alteraes nos livros e nas editoras.
Suponha que para alterar as informaes da editora, o usurio precise acessar a URL /Edi-
toras/Edit/1, onde o 1 (um) define o ID da editora que o usurio deseje alterar as informaes
e ser passado como parmetro na nossa action. O primeiro passo definir um mtodo para
a action Edit no controlador EditorasController que receber o Id da editora fornecido pelo
usurio e encaminhar para o formulrio de edio.
www.k19.com.br 70
Viso Geral do ASP .NET MVC
1
2 using System;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Web;
6 using System.Web.Mvc;
7 using LivrariaVirtual.Models;
8
9 namespace LivrariaVirtual.Controllers
10 {
11 public class EditorasController : Controller
12 {
13 private EditoraRepository editoraRepository = new EditoraRepository();
14 //
15 // GET: /Editoras/
16
17 public ActionResult Index()
18 {
19 return View(this.editoraRepository.BuscaTodas());
20 }
21
22 //
23 // GET: /Editoras/Create
24
25 public ActionResult Create()
26 {
27 return View();
28 }
29
30 //
31 // POST: /Editoras/Create
32
33 [HttpPost]
34 public ActionResult Create(Editora editora)
35 {
36
37 editoraRepository.Adiciona(editora);
38 return RedirectToAction("Index");
39
40 }
41
42 //
43 // GET: /Editoras/Edit/5
44
45 public ActionResult Edit(int id)
46 {
47 Editora editora = editoraRepository.Busca(id);
48 return View(editora);
49 }
50
51
52 }
53 }
O formulrio de edio dever vir preenchido com as informaes da editora que o usurio
definiu. Para isto, passamos como parmetro editora no mtodo View e acessamos atravs da
propriedade Model.
71 K19 Treinamentos
Viso Geral do ASP .NET MVC
1
2 @model LivrariaVirtual.Models.Editora
3
4 @{
5 ViewBag.Title = "Edit";
6 }
7
8 <h2>Edit</h2>
9
10 @using (Html.BeginForm()) {
11 <fieldset>
12 <legend>Editora</legend>
13
14 @Html.HiddenFor(model => model.Id)
15
16 <div class="editor-label">
17 @Html.LabelFor(model => model.Nome)
18 </div>
19 <div class="editor-field">
20 @Html.EditorFor(model => model.Nome)
21 </div>
22
23 <div class="editor-label">
24 @Html.LabelFor(model => model.Email)
25 </div>
26 <div class="editor-field">
27 @Html.EditorFor(model => model.Email)
28 </div>
29
30 <p>
31 <input type="submit" value="Save" />
32 </p>
33 </fieldset>
34 }
Ao submeter o formulrio, requisio POST por padro, devemos ter um mtodo para esta
action que receber os dados enviados e far a alterao em nossa base de dados.
www.k19.com.br 72
Viso Geral do ASP .NET MVC
1
2 using System;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Web;
6 using System.Web.Mvc;
7 using LivrariaVirtual.Models;
8
9 namespace LivrariaVirtual.Controllers
10 {
11 public class EditorasController : Controller
12 {
13 private EditoraRepository editoraRepository = new EditoraRepository();
14 //
15 // GET: /Editoras/
16
17 public ActionResult Index()
18 {
19 return View(this.editoraRepository.BuscaTodas());
20 }
21
22 //
23 // GET: /Editoras/Create
24
25 public ActionResult Create()
26 {
27 return View();
28 }
29
30 //
31 // POST: /Editoras/Create
32
33 [HttpPost]
34 public ActionResult Create(Editora editora)
35 {
36
37 editoraRepository.Adiciona(editora);
38 return RedirectToAction("Index");
39
40 }
41
42 //
43 // GET: /Editoras/Edit/5
44
45 public ActionResult Edit(int id)
46 {
47 Editora editora = editoraRepository.Busca(id);
48 return View(editora);
49 }
50
51 //
52 // POST: /Editoras/Edit/5
53
54 [HttpPost]
55 public ActionResult Edit(Editora e)
56 {
57 editoraRepository.Atualiza(e);
58 return RedirectToAction("Index");
59 }
60
61 }
62 }
73 K19 Treinamentos
Viso Geral do ASP .NET MVC
1
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Data;
5
6 namespace LivrariaVirtual.Models
7 {
8 public class EditoraRepository
9 {
10 private LivrariaContext context = new LivrariaContext();
11
12 public void Adiciona(Editora e)
13 {
14 context.Editoras.Add(e);
15 context.SaveChanges();
16 }
17
18 public void Atualiza(Editora e)
19 {
20 context.Entry(e).State = EntityState.Modified;
21 context.SaveChanges();
22 }
23
24 public Editora Busca(int id)
25 {
26 return context.Editoras.Find(id);
27 }
28
29 public List<Editora> BuscaTodas()
30 {
31 var consulta = from e in context.Editoras
32 select e;
33 return consulta.ToList();
34 }
35 }
36 }
Nas listagens de editoras e livros, podemos acrescentar um link alterao para cada item.
Para isso, devemos alterar as pginas de listagem.
www.k19.com.br 74
Viso Geral do ASP .NET MVC
1
2 @model IList<LivrariaVirtual.Models.Editora>
3
4 @{
5 ViewBag.Title = "Editoras";
6 }
7
8 <h2>Editoras</h2>
9
10 <table>
11 <tr>
12 <th>
13 Nome
14 </th>
15 <th>
16 Email
17 </th>
18 <th></th>
19 </tr>
20
21 @foreach (var item in Model) {
22 <tr>
23 <td>
24 @Html.DisplayFor(modelItem => item.Nome)
25 </td>
26 <td>
27 @Html.DisplayFor(modelItem => item.Email)
28 </td>
29 <td>
30 @Html.ActionLink("Edit", "Edit", new { id=item.Id })
31 </td>
32 </tr>
33 }
34
35 </table>
4.15 Exerccios
10. Implemente um mtodo para a action Edit no controlador LivrosController que ser
responsvel por apresentar um formulrio para a atualizao de um livro. Ao submeter
o formulrio devemos ter um mtodo para esta action que receber os dados enviados e
far a alterao em nossa base de dados. No esquea da modificar a pgina que lista os
livros para chamar o formulrio de edio atravs de um link.
75 K19 Treinamentos
Viso Geral do ASP .NET MVC
1
2 //
3 // GET: /Livros/Edit/5
4
5 public ActionResult Edit(int id)
6 {
7 Livro livro = livroRepository.Busca(id);
8 var consulta = editoraRepository.BuscaTodas().Select(e => new { e.Id, e.Nome });
9 ViewBag.Editoras = consulta.ToList();
10 ViewBag.editora = new Editora { Nome = "iuiuiu" };
11 return View(livro);
12 }
13
14 //
15 // POST: /Editoras/Edit/5
16
17 [HttpPost]
18 public ActionResult Edit(Livro l)
19 {
20 livroRepository.Atualiza(l);
21 return RedirectToAction("Index");
22 }
Classe LivroRepository:
1
2 public void Atualiza(Livro l)
3 {
4 context.Entry(l).State = EntityState.Modified;
5 context.SaveChanges();
6 }
A pgina Edit.cshtml:
www.k19.com.br 76
Viso Geral do ASP .NET MVC
1
2 @model LivrariaVirtual.Models.Livro
3
4 @{
5 ViewBag.Title = "Edit";
6 }
7
8 <h2>Alterar Livro</h2>
9
10 @using (Html.BeginForm()) {
11 <fieldset>
12 <legend>Livro</legend>
13
14 @Html.HiddenFor(model => model.Id)
15
16 <div class="editor-label">
17 @Html.LabelFor(model => model.Titulo)
18 </div>
19 <div class="editor-field">
20 @Html.EditorFor(model => model.Titulo)
21 </div>
22
23 <div class="editor-label">
24 @Html.LabelFor(model => model.Preco)
25 </div>
26 <div class="editor-field">
27 @Html.EditorFor(model => model.Preco)
28 </div>
29
30 <div class="editor-label">
31 @Html.LabelFor(model => model.EditoraId)
32 </div>
33
34 <div class="editor-field">
35 @Html.DropDownListFor(model => model.EditoraId, new SelectList(ViewBag.-
Editoras,"Id","Nome"))
36 </div>
37
38 <p>
39 <input type="submit" value="Save" />
40 </p>
41 </fieldset>
42 }
77 K19 Treinamentos
Viso Geral do ASP .NET MVC
1 @model IList<LivrariaVirtual.Models.Editora>
2
3 @{
4 ViewBag.Title = "Editoras";
5 }
6
7 <h2>Editoras</h2>
8
9 <table>
10 <tr>
11 <th>
12 Nome
13 </th>
14 <th>
15 Email
16 </th>
17 <th></th>
18 </tr>
19
20 @foreach (var item in Model) {
21 <tr>
22 <td>
23 @Html.DisplayFor(modelItem => item.Nome)
24 </td>
25 <td>
26 @Html.DisplayFor(modelItem => item.Email)
27 </td>
28 <td>
29 @Html.ActionLink("Edit", "Edit", new { id=item.Id })
30 </td>
31 <td>
32 @Html.ActionLink("Delete", "Delete", new { id=item.Id })
33 </td>
34 </tr>
35 }
36
37 </table>
www.k19.com.br 78
Viso Geral do ASP .NET MVC
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5 using System.Web.Mvc;
6 using LivrariaVirtual.Models;
7
8 namespace LivrariaVirtual.Controllers
9 {
10 public class EditorasController : Controller
11 {
12 private EditoraRepository editoraRepository = new EditoraRepository();
13
14 //
15 // GET: /Editoras/Delete/5
16 public ActionResult Delete(int id)
17 {
18 Editora editora = editoraRepository.Busca(id);
19 return View(editora);
20 }
21
22 //
23 // POST: /Editoras/Delete/5
24 [HttpPost, ActionName("Delete")]
25 public ActionResult DeleteConfirmed(int id)
26 {
27 Editora editora = editoraRepository.Busca(id);
28 editoraRepository.Remove(editora);
29 return RedirectToAction("Index");
30 }
31
32 }
33 }
Ao enviar uma requisio POST atravs da URL /Editoras/Delete/5, o mtodo que tratar
esta action ser o DeleteConfirmed. Para isto, renomeamos a action com a anotao Action-
Name, pois por padro a action contm o mesmo nome do mtodo do controlador. Precisamos
tambm definir uma pgina de confirmao da remoo da entidade:
79 K19 Treinamentos
Viso Geral do ASP .NET MVC
1 @model LivrariaVirtual.Models.Editora
2
3 @{
4 ViewBag.Title = "Apagar Editora";
5 }
6
7 <h2>Apagar Editora</h2>
8
9 <h3>Voc tem certeza que deseja apagar esta editora?</h3>
10 <fieldset>
11 <legend>Editora</legend>
12
13 <div class="display-label">Nome</div>
14 <div class="display-field">
15 @Html.DisplayFor(model => model.Nome)
16 </div>
17
18 <div class="display-label">Email</div>
19 <div class="display-field">
20 @Html.DisplayFor(model => model.Email)
21 </div>
22 </fieldset>
23 @using (Html.BeginForm()) {
24 <p>
25 <input type="submit" value="Delete" /> |
26 @Html.ActionLink("Voltar para listagem de Editoras", "Index")
27 </p>
28 }
4.17 Exerccios
11. Implemente os mtodos para as actions de remoo no EditorasController que sero
responsveis por remover uma editora. No se esquea de modificar a pgina de listagem
de editoras para incluir o link de remoo.
12. Implemente os mtodos para as actions de remoo no LivrosController que sero res-
ponsveis por remover um livro. No se esquea de modificar a pgina de listagem de
livros para incluir o link de remoo.
www.k19.com.br 80
Captulo 5
Tratamento de Erros
Por outro lado, h erros que no so causados por falhas dos usurios. Por exemplo, um erro
de conexo com o banco de dados. Nesses casos, improvvel que os usurios possam fazer
algo que resolva o problema. E mesmo que pudessem, provavelmente, no seria conveniente
esperar que eles o fizessem.
Quando um erro desse tipo ocorre, o ASP.NET cria uma pgina web com informaes
sobre o erro e a envia aos usurios. Para usurios locais, o ASP.NET envia uma pgina web
com informaes detalhadas do erro ocorrido. Para usurios remotos, a pgina web enviada
no contm informaes detalhadas.
81
Tratamento de Erros
Em geral, no conveniente que os usurios recebam detalhes tcnicos sobre os erros ge-
rados por falhas da aplicao. A primeira justificativa que esses detalhes podem confundir os
usurios. A segunda justificativa que esses detalhes podem expor alguma falha de segurana
da aplicao deixando a mais vulnervel a ataques.
5.1 Try-Catch
Os erros de aplicao podem ser identificados atravs do comando try-catch que pode ser
colocado nos mtodos das actions dos controladores. Ao identificar a ocorrncia de um erro,
os controladores podem mostrar uma pgina web com alguma mensagem para o usurio.
www.k19.com.br 82
Tratamento de Erros
1 [HttpPost]
2 public ActionResult Create(Editora editora)
3 {
4 try
5 {
6 this.editoraRepository.Adiciona(editora);
7 }
8 catch
9 {
10 return View("Error");
11
12 }
13
14 return RedirectToAction("Index");
15
16 }
1
2 @{
3 Layout = null;
4 }
5
6 <!DOCTYPE html>
7 <html>
8 <head>
9 <title>Erro</title>
10 </head>
11 <body>
12 <h2>
13 Servidor com problemas
14 </h2>
15 <p>
16 Houve um problema no nosso servidor.<br/>
17 Por favor tente novamente dentro de alguns instantes.
18 </p>
19 </body>
20 </html>
As pginas de erro que sero mostradas pelos controladores teriam uma mensagem sim-
ples 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.
5.2 Exerccios
1. Altere o cdigo do mtodo da action Create do controlador EditorasController para
capturar erros usando try-catch.
83 K19 Treinamentos
Tratamento de Erros
1 <customErrors mode="On">
2 </customErrors>
On: A pgina de erro padro ser enviada para usurios locais ou remotos.
Off: A pgina de erro detalhada ser enviada para usurios locais ou remotos.
RemoteOnly: A pgina de erro detalhada ser enviada para 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 XHTML.
1 @{
2 Layout = null;
3 }
4
5 <!DOCTYPE html>
6 <html>
7 <head>
8 <title>Erro</title>
9 </head>
10 <body>
11 <h2>
12 Servidor com problemas
13 </h2>
14 <p>
15 Houve um problema no nosso servidor.<br/>
16 Por favor tente novamente dentro de alguns instantes.
17 </p>
18 </body>
19 </html>
5.4 Exerccios
2. Configure nossa aplicao para utilizar pginas de erro padro. Lembre-se que no vamos
mais precisar do comando try-catch colocado no exerccio anterior.
www.k19.com.br 84
Tratamento de Erros
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 utiliza a pgina padro para erros de aplicao con-
figurada no Web.config atravs da tag customErrors. Porm, esse erro no deve ser considerado
um erro de aplicao pois ele pode ser gerado por falhas dos usurios. Ele tambm no deve ser
considerado um erro de usurio pois ele pode ser gerado por falhas da aplicao. Consequente-
mente, comum tratar o erro 404 de maneira particular criando uma pgina de erro especfica
para ele.
1 @{
2 Layout = null;
3 }
4
5 <!DOCTYPE html>
6 <html>
7 <head>
8 <title>Arquivo no encontrado!</title>
9 </head>
10 <body>
11 <h2>
12 Esse arquivo no foi encontrado. Verifique se a url est correta.
13 </h2>
14 </body>
15 </html>
No arquivo de configurao, podemos determinar uma pgina web especfica para o erro
404 ou para os outros erros do HTTP.
1 <customErrors mode="On">
2 <error statusCode="404" redirect="~/ErrorPages/NotFound"/>
3 </customErrors>
Devemos definir uma controlador com o nome ErrorPages, por padro, alm do mtodo
para a action NotFound.
1 using System.Web.Mvc;
2
3 namespace LivrariaVirtual.Controllers
4 {
5 public class ErrorPagesController : Controller
6 {
7
8 public ActionResult NotFound()
9 {
10 return View();
11 }
12
13 }
14 }
85 K19 Treinamentos
Tratamento de Erros
5.6 Exerccios
3. Crie uma pgina de erro e um controlador especfico para o erro 404 e modifique o
arquivo Web.config para fazer redirecionamento apropriado.
www.k19.com.br 86
Captulo 6
A maneira mais simples de gerar contedo dinmico atravs de inline code - que so
blocos de cdigo inseridos entre tags como (<% ... %>). Tags existentes tambm no PHP,
Rails, JSP, que permite voc inserir uma lgica simples para gerar o contedo dinmico.
No ASP .NET MVC 3 podemos inserir cdigo C# na View utilizando o Razor ao invs do
tradicional ASPX que obriga colocar o cdigo entre <% ... %>. A principal caracterstica do
Razor ser conciso e simples, diminuindo o nmero de caracteres e tags scripts na View, pois
diferentemente de outras sintaxes, no h necessidade de explicitar no cdigo HTML um bloco
de cdigo de servidor.
Segue abaixo alguns exemplos cdigo utilizando Razor e o equivalente em ASPX:
Bloco de cdigo:
1 //Razor
2 @{
3 int x = 123;
4 string nome = "Marcelo";
5 }
87
Camada de Apresentao (View)
1 //ASPX
2 <%
3 int x = 123;
4 string nome = "Marcelo.";
5 %>
Expresso:
Texto e HTML
Cdigo e texto
Comentrios
www.k19.com.br 88
Camada de Apresentao (View)
1
2 public class Editora
3 {
4 public int Id { get; set; }
5 public string Nome { get; set; }
6 public string Email { get; set; }
7 public virtual ICollection<Livro> Livros { get; set; }
8 }
89 K19 Treinamentos
Camada de Apresentao (View)
1
2 @model LivrariaVirtual.Models.Editora
3
4 @{
5 Layout = null;
6 }
7
8 <!DOCTYPE html>
9
10 <html>
11 <head>
12 <title>@Model.Nome </title>
13 </head>
14 <body>
15 <h1>Editora @Model.Nome</h1>
16 <div>
17 Contato: @Model.Email
18 </div>
19
20 <h3>Livros:</h3>
21 <ul>
22 @foreach(var livro in @Model.Livros) {
23 <li>
24 <b>@livro.Titulo</b> - R$ @livro.Preco
25 </li>
26 }
27 </ul>
28 </body>
29 </html>
www.k19.com.br 90
Camada de Apresentao (View)
No ASP .NET MVC, o controlador consegue fornecer dados a View atravs de:
1 //
2 // GET: /Livros/Edit/5
3
4 public ActionResult Edit(int id)
5 {
6 Livro livro = livroRepository.Busca(id);
7 ViewData["Mensagem"] = "Hora Atual: " + DateTime.Now.ToShortTimeString();
8 ViewData["Editoras"] = editoraRepository.BuscaTodas();
9 //Equivalente a: ViewData.Model = livro;
10 return View(livro);
11 }
No ASP .NET MVC 3 podemos utilizar ViewBag ao invs de ViewData. ViewBag uma
coleo dinmica que permite o envio de dados do controlador para a View. O suporte a coleo
dinmica fruto do suporte a tipos dinmicos do .NET 4. Segue um exemplo de ViewBag:
1 //
2 // GET: /Livros/Edit/5
3
4 public ActionResult Edit(int id)
5 {
6 Livro livro = livroRepository.Busca(id);
7 ViewBag.Mensagem = "Hora Atual: " + DateTime.Now.ToShortTimeString();
8 ViewBag.Editoras = editoraRepository.BuscaTodas();
9 //Equivalente a: ViewData.Model = livro;
10 return View(livro);
11 }
91 K19 Treinamentos
Camada de Apresentao (View)
1
2 @model LivrariaVirtual.Models.Livro
3
4 @{
5 ViewBag.Title = "Edit";
6 }
7
8 <h2>Alterar Livro</h2>
9
10 @using (Html.BeginForm()) {
11 <fieldset>
12 <legend>Livro</legend>
13
14 @Html.HiddenFor(model => model.Id)
15
16 <div class="editor-label">
17 @Html.LabelFor(model => model.Titulo)
18 </div>
19 <div class="editor-field">
20 @Html.TextBoxFor(model => model.Titulo)
21 </div>
22
23 <div class="editor-label">
24 @Html.LabelFor(w => w.Preco)
25 </div>
26 <div class="editor-field">
27 @Html.EditorFor(model => model.Preco)
28 </div>
29
30 <div class="editor-label">
31 @Html.LabelFor(model => model.EditoraId)
32 </div>
33
34 <div class="editor-field">
35 @Html.DropDownListFor(model => model.EditoraId, new SelectList(ViewBag.-
Editoras,"Id","Nome"))
36 </div>
37
38 <p>
39 <input type="submit" value="Save" />
40 </p>
41 </fieldset>
42 }
43
44 <div>
45 @ViewBag.Mensagem
46 </div>
www.k19.com.br 92
Camada de Apresentao (View)
1
2
3 <ul>
4 @foreach(var e in Model)
5 {
6 <li>
7 @e.Nome - @e.Email
8 <a href="/Editoras/Edit/@e.Id">alterar</a>
9 <a href="/Editoras/Delete/@e.Id">remover</a>
10 </li>
11 }
12 </ul>
93 K19 Treinamentos
Camada de Apresentao (View)
Caso queiramos acrescentar um link para redirecionar para um outro controlador, devemos
acrescentar um terceiro parmetro:
O ActionLink permite que parmetros sejam adicionados no link gerado. Para isso, basta
acrescentar um parmetro.
1 @{Html.BeginForm();}
2
3 <!-- Elementos de Formulrio -->
4
5 @{Html.EndForm();}
1 @using(Html.BeginForm()) {
2
3 <!-- Elementos de Formulrio -->
4
5 }
www.k19.com.br 94
Camada de Apresentao (View)
1 @using(Html.BeginForm("ACTION", "CONTROLADOR")) {
2
3 <!-- Elementos de Formulrio -->
4
5 }
Por padro, o formulrio enviar uma requisio POST. Devemos definir no nosso contro-
lador o mtodo que ir receber esta requisio.
1 //
2 // POST: /Editoras/Create
3 [HttpPost]
4 public ActionResult Create(Editora editora)
5 {
6 this.editoraRepository.Adiciona(editora);
7 return RedirectToAction("Index");
8 }
Para definir os campos do nosso formulrio, podemos utilizar os HTML Helpers string-
based:
Check Box:
Text Box:
Text Area:
Radio Button:
Hidden Field:
95 K19 Treinamentos
Camada de Apresentao (View)
Password Field:
Text Box:
Text Area:
Radio Button:
Hidden Field:
Password Field:
www.k19.com.br 96
Camada de Apresentao (View)
1 @Html.TextBox("Nome")
Isto equivalente a:
1 @Html.TextBox("Nome", ViewData.Eval("Nome"))
Caso a key Nome da ViewDataDictionary da pgina no exista, o valor deste elemento ser
preenchido com ViewData.Model.Nome. Lembrando que para acessar o value associado a key,
podemos utilizar, por exemplo, ViewBag.Nome, equivalente a ViewData["Nome"].
No caso de Helpers HTML strongly typed, o valor do elemento ser sempre associado a
propriedade ViewData.Model da pgina.
1 //
2 // GET: /Livros/Edit/5
3 public ActionResult Edit(int id)
4 {
5 Livro livro = livroRepository.Busca(id);
6 List<Editora> editoras = editoraRepository.BuscaTodas();
7 ViewBag.EditoraId = new SelectList(editoras,"Id","Nome");
8 return View(livro);
9 }
Pelo fato do Helper HTML strongly typed Drop Down List no aceitar tipos dinmicos,
devemos fazer o cast para SelectList.
97 K19 Treinamentos
Camada de Apresentao (View)
Para editar o cadastro de uma editora, teramos uma pgina Edit.cshtml conforme exemplo
abaixo:
1 @model LivrariaVirtual.Models.Editora
2
3 @{
4 ViewBag.Title = "Edio de Editora";
5 }
6
7 <h2>Edio de Editora</h2>
8
9 @using (Html.BeginForm()) {
10 @Html.ValidationSummary(true)
11 <fieldset>
12 <legend>Editora</legend>
13
14 @Html.HiddenFor(model => model.Id)
15
16 <div class="editor-label">
17 @Html.LabelFor(model => model.Nome)
18 </div>
19 <div class="editor-field">
20 @Html.TextBoxFor(model => model.Nome)
21 </div>
22
23 <div class="editor-label">
24 @Html.LabelFor(model => model.Email)
25 </div>
26 <div class="editor-field">
27 @Html.TextBoxFor(model => model.Email)
28 </div>
29
30 <div class="editor-label">
31 @Html.LabelFor(model => model.IsAtivo)
32 </div>
33 <div class="editor-field">
34 @Html.CheckBoxFor(model => model.IsAtivo)
35 </div>
36
37 <p>
38 <input type="submit" value="Save" />
39 </p>
40 </fieldset>
41 }
42
43 <div>
44 @Html.ActionLink("Listagem de Editoras", "Index")
45 </div>
Para cada propriedade do nosso modelo Editora, definimos um Helper apropriado para gerar
www.k19.com.br 98
Camada de Apresentao (View)
o elemento HTML para a entrada de dados. Por exemplo, no caso da propriedade Nome e Email
utilizamos o Helper Text Box, j para a propriedade booleana IsAtivo utilizamos CheckBox.
Podemos utilizar o Helper Editor que define o Helper HTML apropriado de acordo com o
tipo da propriedade. Para propriedades e valores do tipo booleano, o helper utilizado ser o
Check Box, j para elementos do tipo string, o helper o Text Box.
99 K19 Treinamentos
Camada de Apresentao (View)
1 @model LivrariaVirtual.Models.Editora
2
3 @{
4 ViewBag.Title = "Edio de Editora";
5 }
6
7 <h2>Edio de Editora</h2>
8
9 @using (Html.BeginForm()) {
10 @Html.ValidationSummary(true)
11 <fieldset>
12 <legend>Editora</legend>
13
14 @Html.EditorFor(model => model.Id)
15
16 <div class="editor-label">
17 @Html.LabelFor(model => model.Nome)
18 </div>
19 <div class="editor-field">
20 @Html.EditorFor(model => model.Nome)
21 </div>
22
23 <div class="editor-label">
24 @Html.LabelFor(model => model.Email)
25 </div>
26 <div class="editor-field">
27 @Html.EditorFor(model => model.Email)
28 </div>
29
30 <div class="editor-label">
31 @Html.LabelFor(model => model.IsAtivo)
32 </div>
33 <div class="editor-field">
34 @Html.EditorFor(model => model.IsAtivo)
35 </div>
36
37 <p>
38 <input type="submit" value="Save" />
39 </p>
40 </fieldset>
41 }
42
43 <div>
44 @Html.ActionLink("Listagem de Editoras", "Index")
45 </div>
www.k19.com.br 100
Camada de Apresentao (View)
Podemos perceber que a tela ficou "parecida", porm para a propriedade Id foi definido
o Helper Text Box e o mais apropriado o Helper Hidden. O Helper Editor no consegue
definir em todos os casos, o Helper mais apropriado. Para casos especficos, o ASP .NET
MVC prov templates para definir o Helper mais apropriado para determinada propriedade do
nosso modelo.
Por exemplo, para a propriedade Id, devemos acrescentar uma anotao indicando que para
esta propriedade queremos utilizar o Helper Hidden.
1 using System.Collections.Generic;
2 using System.Web.Mvc;
3 namespace LivrariaVirtual.Models
4 {
5 public class Editora
6 {
7 [HiddenInput(DisplayValue = false)]
8 public int Id { get; set; }
9 public string Nome { get; set; }
10 public string Email { get; set; }
11 public bool IsAtivo { get; set; }
12 public virtual ICollection<Livro> Livros { get; set; }
13 }
14 }
Template Descrio
HiddenInput Utiliza o Helper Hidden
Text Utiliza o Helper Text
String Utiliza o Helper TextBox
Password Utiliza o Helper Password
MultilineText Utiliza o Helper TextArea
Boolean Utiliza o Helper CheckBox ou
DropDownList para nullable boo-
lean
Decimal Utiliza o Helper TextBox e formata
para duas casas decimais
Object Percorre as propriedades do objeto
e define o Helper apropriado para
cada uma
Collection Percorre atravs do IEnumerable e
define o Helper para cada elemento
www.k19.com.br 102
Camada de Apresentao (View)
1 @model LivrariaVirtual.Models.Editora
2
3 @{
4 ViewBag.Title = "Edio de Editora";
5 }
6
7 <h2>Edio de Editora</h2>
8
9 @using (Html.BeginForm()) {
10 @Html.ValidationSummary(true)
11 <fieldset>
12 <legend>Editora</legend>
13
14 @Html.EditorForModel()
15
16 <p>
17 <input type="submit" value="Save" />
18 </p>
19 </fieldset>
20 }
21
22 <div>
23 @Html.ActionLink("Listagem de Editoras", "Index")
24 </div>
6.5 Exerccios
1. Utilize o projeto LivrariaVirtual definido nos captulos anteriores.
2. Altere o mtodo da action Edit do controlador Editoras para enviar a informao da hora
do servidor.
1 //
2 // GET: /Editoras/Edit/5
3
4 public ActionResult Edit(int id)
5 {
6 Editora editora = editoraRepository.Busca(id);
7 ViewBag.Hora = DateTime.Now.ToShortTimeString();
8 return View(editora);
9 }
1 @model LivrariaVirtual.Models.Editora
2
3 @{
4 ViewBag.Title = "Edio de Editora";
5 }
6
7 <h2>Edio de Editora</h2>
8
9 @using (Html.BeginForm()) {
10 @Html.ValidationSummary(true)
11 <fieldset>
12 <legend>Editora</legend>
13
14 @Html.Hidden("Id")
15
16 <div class="editor-label">
17 @Html.Label("Nome")
18 </div>
19 <div class="editor-field">
20 @Html.TextBox("Nome")
21 </div>
22
23 <div class="editor-label">
24 @Html.Label("Email")
25 </div>
26 <div class="editor-field">
27 @Html.TextBox("Email")
28 </div>
29
30 <div class="editor-label">
31 @Html.Label("IsAtivo")
32 </div>
33 <div class="editor-field">
34 @Html.CheckBox("IsAtivo")
35 </div>
36
37 <p>
38 <input type="submit" value="Save" />
39 </p>
40 </fieldset>
41 }
42 <!-- Mostrando a hora atual -->
43 <div>
44 Hora atual: @ViewBag.Hora
45 </div>
46 <div>
47 @Html.ActionLink("Listagem de Editoras", "Index")
48 </div>
1 //
2 // GET: /Editoras/Edit/5
3
4 public ActionResult Edit(int id)
5 {
6 Editora editora = editoraRepository.Busca(id);
7 ViewBag.Hora = DateTime.Now.ToShortTimeString();
8 ViewBag.Nome = "Prioridade mais alta";
9 return View(editora);
10 }
www.k19.com.br 104
Camada de Apresentao (View)
1 @model LivrariaVirtual.Models.Editora
2
3 @{
4 ViewBag.Title = "Edio de Editora";
5 }
6
7 <h2>Edio de Editora</h2>
8
9 @using (Html.BeginForm()) {
10 @Html.ValidationSummary(true)
11 <fieldset>
12 <legend>Editora</legend>
13
14 @Html.EditorFor(model => model.Id)
15
16 <div class="editor-label">
17 @Html.LabelFor(model => model.Nome)
18 </div>
19 <div class="editor-field">
20 @Html.EditorFor(model => model.Nome)
21 </div>
22
23 <div class="editor-label">
24 @Html.LabelFor(model => model.Email)
25 </div>
26 <div class="editor-field">
27 @Html.EditorFor(model => model.Email)
28 </div>
29
30 <div class="editor-label">
31 @Html.LabelFor(model => model.IsAtivo)
32 </div>
33 <div class="editor-field">
34 @Html.EditorFor(model => model.IsAtivo)
35 </div>
36
37 <p>
38 <input type="submit" value="Save" />
39 </p>
40 </fieldset>
41 }
42 <!-- Mostrando a hora atual -->
43 <div>
44 Hora atual: @ViewBag.Hora
45 </div>
46 <div>
47 @Html.ActionLink("Listagem de Editoras", "Index")
48 </div>
7. Altere a classe Editora para que o Helper Editor defina o Helper Hidden para a proprie-
dade Id.
1 using System.Collections.Generic;
2 using System.Web.Mvc;
3 namespace LivrariaVirtual.Models
4 {
5 public class Editora
6 {
7 [HiddenInput(DisplayValue=false)]
8 public int Id { get; set; }
9 public string Nome { get; set; }
10 public string Email { get; set; }
11 public bool IsAtivo { get; set; }
12 public virtual ICollection<Livro> Livros { get; set; }
13 }
14 }
1 @model LivrariaVirtual.Models.Editora
2
3 @{
4 ViewBag.Title = "Edio de Editora";
5 }
6
7 <h2>Edio de Editora</h2>
8
9 @using (Html.BeginForm()) {
10 @Html.ValidationSummary(true)
11 <fieldset>
12 <legend>Editora</legend>
13
14 @Html.EditorForModel()
15
16 <p>
17 <input type="submit" value="Save" />
18 </p>
19 </fieldset>
20 }
21 <!-- Mostrando a hora atual -->
22 <div>
23 Hora atual: @ViewBag.Hora
24 </div>
25 <div>
26 @Html.ActionLink("Listagem de Editoras", "Index")
27 </div>
www.k19.com.br 106
Camada de Apresentao (View)
Alguns detalhes:
Estamos acrescentando @RenderBody() que indica onde o contedo das pginas ser
encaixado.
No title acrescentamos @ViewBag.Title, isto permitir que o title seja especfico a cada
pgina.
O prximo passo indicar quais pginas utilizaro essa Master Page. Por exemplo, po-
demos atualizar a pgina Edit.cshtml de Editoras para utilizar a LivrariaLayout.cshtml como
layout principal:
1 @model LivrariaVirtual.Models.Editora
2
3 @{
4 Layout = "~/Views/Shared/LivrariaLayout.cshtml";
5 //Define o title especfico desta pgina
6 ViewBag.Title = "Edio de Editora";
7 }
8
9 <h2>Edio de Editora</h2>
10
11 @using(Html.BeginForm()) {
12 <fieldset>
13 <legend>Editora</legend>
14
15 @Html.EditorForModel()
16
17 <p>
18 <input type="submit" value="Save" />
19 </p>
20 </fieldset>
21 }
O _ViewStart.cshtml permite definirmos um cdigo que ser executado antes de cada View
ser renderizada. Podemos definir, por exemplo, a propriedade Layout:
1 @{
2 Layout = "~/Views/Shared/LivrariaLayout.cshtml";
3 }
Como este cdigo executado no incio de cada view, no h mais necessidade de definir a
propriedade Layout em cada pgina.
6.6.2 Lacunas
Tambm podemos criar lacunas na Master Page para serem preenchidas com contedos
definidos nas pginas. Segue a pgina LivrariaLayout.cshtml:
www.k19.com.br 108
Camada de Apresentao (View)
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>@ViewBag.Title</title>
5 <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
6 <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript">-
</script>
7 </head>
8
9 <body>
10 <div id="header">
11 @Html.ActionLink("Editoras", "Index","Editoras")
12 @Html.ActionLink("Livros", "Index","Livros")
13 </div>
14 <div id="sidebar">Sidebar padro</div>
15 <div id="content">@RenderBody()</div>
16 <div id="footer">Livraria Virtual</div>
17
18 </body>
19 </html>
Para especificar uma lacuna em nosso layout, devemos utilizar o helper @RenderSec-
tion(string Nome Da Seo, bool Obrigatoriedade):
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>@ViewBag.Title</title>
5 <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
6 <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript">-
</script>
7 </head>
8
9 <body>
10 <div id="header">
11 @Html.ActionLink("Editoras", "Index","Editoras")
12 @Html.ActionLink("Livros", "Index","Livros")
13 </div>
14 <!-- Definindo a lacuna "Sidebar" e indicando que opcional (false) -->
15 <div id="sidebar">@RenderSection("sidebar",false)</div>
16 <div id="content">@RenderBody()</div>
17 <div id="footer">Livraria Virtual</div>
18
19 </body>
20 </html>
Para definir a seo Sidebar, devemos utilizar o cdigo @section. Segue a pgina Edit.cshtml
de Editoras:
www.k19.com.br 110
Camada de Apresentao (View)
1 @model LivrariaVirtual.Models.Editora
2
3 @{
4 Layout = "~/Views/Shared/LivrariaLayout.cshtml";
5 //Define o title especfico desta pgina
6 ViewBag.Title = "Edio de Editora";
7 }
8
9 <h2>Edio de Editora</h2>
10
11 @using(Html.BeginForm()) {
12 <fieldset>
13 <legend>Editora</legend>
14
15 @Html.EditorForModel()
16
17 @section Sidebar {
18
19 <p>Sidebar do cadastro de Edio de Editora</p>
20
21 }
22
23 <p>
24 <input type="submit" value="Save" />
25 </p>
26 </fieldset>
27 }
28 <div>
29 @Html.ActionLink("Listagem de Editoras", "Index")
30 </div>
Para no ficar este buraco, podemos definir um seo padro para casos em que as pgi-
nas no definiram uma seo especfica. Para isto, devemos fazer uma verificao na pgina
LivrariaLayout.cshtml atravs do mtodo IsSectionDefined():
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>@ViewBag.Title</title>
5 <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
6 <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript">-
</script>
7 </head>
8
9 <body>
10 <div id="header">
11 @Html.ActionLink("Editoras", "Index","Editoras")
12 @Html.ActionLink("Livros", "Index","Livros")
13 </div>
14 @if (IsSectionDefined("Sidebar"))
15 {
16 <div id="sidebar">@RenderSection("Sidebar", false)</div>
17 }
18 else
19 {
20 <div id="sidebar">Sidebar padro</div>
21 }
22
23 <div id="content">@RenderBody()</div>
24 <div id="footer">Livraria Virtual</div>
25
26 </body>
27 </html>
6.7 Exerccios
9. Utilize o projeto LivrariaVirtual para resolver os exerccios a seguir.
www.k19.com.br 112
Camada de Apresentao (View)
10. Crie uma pgina que servir de layout para a nossa aplicao.
11. Altere a pgina Edit.cshtml de Editoras para utilizar a pgina de layout definido no exer-
ccio anterior.
1 @model LivrariaVirtual.Models.Editora
2
3 @{
4 Layout = "~/Views/Shared/LivrariaLayout.cshtml";
5 ViewBag.Title = "Edio de Editora";
6 }
7
8 <h2>Edio de Editora</h2>
9
10 @using(Html.BeginForm()) {
11 <fieldset>
12 <legend>Editora</legend>
13
14 @Html.EditorForModel()
15
16 <p>
17 <input type="submit" value="Save" />
18 </p>
19 </fieldset>
20 }
13. Defina sees na pgina LivrariaLayout.cshtml. Para isto, acrescente ao arquivo Site.css
na pasta Content o trecho de cdigo a seguir:
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>@ViewBag.Title</title>
5 <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
6 <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript">-
</script>
7 </head>
8
9 <body>
10 <div id="header">
11 @Html.ActionLink("Editoras", "Index","Editoras")
12 @Html.ActionLink("Livros", "Index","Livros")
13 </div>
14
15 <div id="sidebar">SideBar Padro</div>
16 <div id="content">@RenderBody()</div>
17 <div id="footer">Livraria Virtual</div>
18
19 </body>
20 </html>
www.k19.com.br 114
Camada de Apresentao (View)
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>@ViewBag.Title</title>
5 <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
6 <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript">-
</script>
7 </head>
8
9 <body>
10 <div id="header">
11 @Html.ActionLink("Editoras", "Index","Editoras")
12 @Html.ActionLink("Livros", "Index","Livros")
13 </div>
14
15 <div id="sidebar">@RenderSection("Sidebar", required:false)</div>
16 <div id="content">@RenderBody()</div>
17 <div id="footer">Livraria Virtual</div>
18
19 </body>
20 </html>
1 @model LivrariaVirtual.Models.Editora
2
3 @{
4 ViewBag.Title = "Edio de Editora";
5 }
6
7 <h2>Edio de Editora</h2>
8
9 @using(Html.BeginForm()) {
10 <fieldset>
11 <legend>Editora</legend>
12
13 @Html.EditorForModel()
14
15 @section Sidebar {
16 <p>Sidebar do cadastro de Edio de Editora</p>
17 }
18
19 <p>
20 <input type="submit" value="Save" />
21 </p>
22 </fieldset>
23 }
16. Acrescente uma seo padro as pginas que no definiram a seo Sidebar.
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>@ViewBag.Title</title>
5 <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
6 <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript">-
</script>
7 </head>
8
9 <body>
10 <div id="header">
11 @Html.ActionLink("Editoras", "Index","Editoras")
12 @Html.ActionLink("Livros", "Index","Livros")
13 </div>
14 @if (IsSectionDefined("Sidebar"))
15 {
16 <div id="sidebar">@RenderSection("Sidebar", required: false)</div>
17 }
18 else
19 {
20 <div id="sidebar">Sidebar padro</div>
21 }
22
23 <div id="content">@RenderBody()</div>
24 <div id="footer">Livraria Virtual</div>
25
26 </body>
27 </html>
Quando necessrio utilizar uma classe ou interface nas pginas .cshtml, devemos acres-
centar a diretiva using adequada. Algumas classes e interfaces so utilizadas em muitas pgi-
nas. Para no ter que adicionar a diretiva de importao em todas as pginas, podemos alterar
o arquivo de configurao (Web.config) da pasta Views fazendo com que todas as pginas j
tenham acesso a determinados namespaces.
1 <system.web.webPages.razor>
2 <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version-
=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
3 <pages pageBaseType="System.Web.Mvc.WebViewPage">
4 <namespaces>
5 <add namespace="System.Web.Mvc" />
6 <add namespace="System.Web.Mvc.Ajax" />
7 <add namespace="System.Web.Mvc.Html" />
8 <add namespace="System.Web.Routing" />
9 <add namespace="System.Linq"/>
10 <add namespace="System.Collections.Generic"/>
11 <add namespace="LivrariaVirtual.Models"/>
12 </namespaces>
13 </pages>
14 </system.web.webPages.razor>
www.k19.com.br 116
Camada de Apresentao (View)
6.9 Exerccios
17. Edite o arquivo Web.config da pasta Views para fazer as importaes de bibliotecas au-
tomaticamente.
Quanto mais elaborada uma pgina web maior o seu cdigo. Quando o cdigo muito
extenso a sua legibilidade fica prejudicada. Para organizar melhor o cdigo, podemos dividir o
contedo de uma pgina web em vrios arquivos .cshtml.
Suponha que desejamos dividir o contedo de uma pgina em duas partes. Devemos criar
um arquivo para cada parte. Normalmente, esses arquivos possuem a exteso .ascx.
Por fim, devemos criar um arquivo .cshtml principal para agrupar as partes. Utilizaremos o
mtodo Partial para inserir o contedo dos arquivos secundrios no arquivo principal.
1 <html>
2 <head>
3 <title>Exemplo de partial</title>
4 </head>
5
6 <body>
7 Html.Partial("Parte1")
8 Html.Partial("Parte2")
9 </body>
10 </html>
www.k19.com.br 118
Camada de Apresentao (View)
6.11 Exerccios
18. Crie uma partial view para o formulrio de Editora.
19. Altere as pginas Create.cshtml e Edit.cshtml de Editoras para utilizar a partial view
_Form.cshtml.
www.k19.com.br 120
Captulo 7
Controle (Controller)
No ASP .NET MVC as URLs so mapeadas para classes que so chamadas de controllers.
Os controladores (controllers) processam as requisies, recebem dados enviados pelos usu-
rios, executam comandos para recuperar dados do modelo e chamam a view apropriada para
gerar o HTML para a requisio.
Os requisitos para uma classe ser considerada controller :
Raramente voc definir uma classe controller implementando a interface IController. Co-
mumente definiremos uma classe controller herdando de System.Web.Mvc.Controller.
7.1 Actions
Nas aplicaes ASP .NET que no utilizam MVC, as interaes do usurio em torno
das pginas, em torno de eventos vindos da pgina e de seus controles. No ASP .NET MVC
a interao do usurio em torno dos controllers e actions. Uma classe controller contm
mtodos que so as actions. Uma action utilizada para processar uma requisio HTTP e
ela pode conter 0 (zero) ou mais argumentos. Para criar uma action preciso definir o mtodo
como public e , na maioria das vezes, o valor de retorno ser uma instncia de uma classe que
deriva de ActionResult.
Quando o usurio faz uma requisio atravs do Browser, o ASP .NET MVC verifica na
tabela de rotas, definido no arquivo Global.asax, o controller que ir receber a requisio. O
controller ir definir o mtodo apropriado para processar a requisio. Por padro, as URLs
seguem a estrutura {NomeDoControlador}/{NomeDaAction}. Caso o usurio acesse a URL
http://www.exemplo.com/Editoras/Listagem, por padro, Editoras ser considerado como o
prefixo do nome do controller (EditorasController, o controlador termina com o sufixo Con-
troller) e Listagem como o nome da action. Ao acessar a url /Editoras/Alterar/1, por padro,
Alterar ser considerado uma action do controller EditorasController e 1 ser enviado como
parmetro para o mtodo Alterar.
Exemplo de uma classe controller que contm uma action HelloWorld:
121
Controle (Controller)
1 using System.Web.Mvc;
2
3 namespace LivrariaVirtual.Controllers
4 {
5 public class HomeController : Controller
6 {
7 //
8 // GET: /Home/HelloWorld
9
10 public ActionResult HelloWorld()
11 {
12 ViewBag.Mensagem = "Hello World!";
13 return View();
14 }
15
16 }
17 }
7.2 ActionResult
Aps o controller receber a requisio e process-la, ele devolve uma resposta para o usu-
rio. O controller responde basicamente de trs maneiras:
No ASP .NET MVC temos uma classe apropriada para cada tipo de retorno que derivada
de ActionResult.
www.k19.com.br 122
Controle (Controller)
7.3 Parmetros
Vimos que os parmetros enviados pelos usurios podem ser recuperados nos controladores
atravs da propriedade Request.
1 <html>
2 <head>
3 <title>Cadastro de Editora</title>
4 </head>
5 <body>
6 <form action="/Editoras/Salva" method="post">
7 Nome: <input type="text" name="nome"/>
8 Email: <input type="text" name="email"/>
9 <input type="submit" />
10 </form>
11 </body>
12 </html>
1 [HttpPost]
2 public ActionResult Salva(string nome, string email)
3 {
4 Editora editora = new Editora { Nome = nome, Email = email };
5 editoraRepository.Adiciona(editora);
6 return View();
7 }
1 [HttpPost]
2 public ActionResult Salva(Editora e)
3 {
4 editoraRepository.Adiciona(e);
5 return View();
6 }
As propriedades dos objetos recebidos como argumentos nos mtodos dos controladores
precisam ter os mesmos nomes dos parmetros HTTP.
7.4 Exerccios
1. Adicione no controlador Editoras do projeto LivrariaVirtual uma action para visualizar o
formulrio de cadastro.
www.k19.com.br 124
Controle (Controller)
1 <h2>Cadastro de Editoras</h2>
2
3 <form action="/Editoras/Salva">
4 Nome: <input name="nome" />
5 Email: <input name="email" />
6 <input type="submit" value="Enviar" />
7 </form>
3. Defina um mtodo para action Salva no controlador Editoras que ir receber os dados
enviados pelo usurio e adicionar uma editora ao banco de dados. Para receber os
dados, utilize a propriedade Request.
5. Altere o mtodo da action Salva para receber um objeto editora como parmetro.
7.5 TempData
Ao efetuar um redirecionamento, uma nova requisio efetuada pelo browser. Nesta nova
requisio no temos mais acesso aos dados e objetos da requisio anterior ao redireciona-
mento. Caso haja a necessidade de preservar os dados ao longo do redirecionamento podemos
utilizar o TempData.
Ao salvar uma Editora, por exemplo, efetuamos um redirecionamento para a tela de lista-
gem. Podemos acrescentar uma mensagem indicando que a operao foi efetuada com sucesso.
1 [HttpPost]
2 public ActionResult Create(Editora editora)
3 {
4 editoraRepository.Adiciona(editora);
5 TempData["mensagem"] = "Editora criada com sucesso!";
6 return RedirectToAction("Index");
7 }
7.6 Exerccios
6. Ao adicionar uma editora e redirecionar o usurio para a tela de listagem, mostre uma
mensagem ao usurio indicando que a operao foi realizada com sucesso.
1 //EditorasController.cs
2 [HttpPost]
3 public ActionResult Create(Editora editora)
4 {
5 editoraRepository.Adiciona(editora);
6 TempData["mensagem"] = "Editora criada com sucesso!";
7 return RedirectToAction("Index");
8 }
www.k19.com.br 126
Captulo 8
Rotas
Para acessar uma determinada ao da nossa aplicao, os usurios devem utilizar a URL
correspondente ao. Por exemplo, para acessar a listagem de categorias, necessrio digi-
tar na barra de endereo do navegador a seguinte url: http://localhost/Editoras/
Lista. Perceba que o padro concatenar o nome do controlador com o nome do mtodo
desejado. Esse padro definido por uma rota criada no arquivo Global.asax.
1 routes.MapRoute(
2 "Default", // Route name
3 "{controller}/{action}/{id}", // URL with parameters
4 new { controller = "Editoras", action = "Lista", id = UrlParameter.-
Optional } // Parameter defaults
5 );
A rota define um padro para URL e define como ela ser tratada.
127
Rotas
1 //parmetro editora
2 public ViewResult Index(string editora)
3 {
4 List<Livro> livros;
5 if (editora != null)
6 {
7 livros = livroRepository.BuscaPorEditora(editora);
8 }
9 else
10 {
11 livros = livroRepository.BuscaTodas();
12 }
13 return View(livros);
14 }
Ao definir parmetros opcionais, devemos utilizar parmetros do tipo nullable type nos
mtodos das actions. Pois quando no definimos o parmetro na URL, atribudo o valor null
ao parmetro do mtodo. No caso de int e double, por exemplo, devemos utilizar int?, double?.
8.3 Exerccios
1. Acrescente uma nova rota para acessarmos a lista de livros atravs da URL /Biblioteca.
www.k19.com.br 128
Rotas
1 //Global.asax
2 routes.MapRoute("Nova Rota", "Biblioteca",
3 new { controller = "Livros", action = "Index" });
4
5 routes.MapRoute(
6 "Default", // Route name
7 "{controller}/{action}/{id}", // URL with parameters
8 new { controller = "Editoras", action = "Index", id = UrlParameter.-
Optional } // Parameter defaults
9 );
1 //Global.asax
2 routes.MapRoute("Nova Rota", "Biblioteca/{editora}",
3 new { controller = "Livros", action = "Index" });
4
5 routes.MapRoute(
6 "Default", // Route name
7 "{controller}/{action}/{id}", // URL with parameters
8 new { controller = "Editoras", action = "Index", id = UrlParameter.-
Optional } // Parameter defaults
9 );
1 //Global.asax
2 routes.MapRoute("Nova Rota", "Biblioteca/{editora}",
3 new { controller = "Livros", action = "Index", editora = UrlParameter.-
Optional });
4
5 routes.MapRoute(
6 "Default", // Route name
7 "{controller}/{action}/{id}", // URL with parameters
8 new { controller = "Editoras", action = "Index", id = UrlParameter.-
Optional } // Parameter defaults
9 );
1 //LivrosController.cs
2 public ViewResult Index(string editora)
3 {
4 return View(livroRepository.BuscaTodas());
5 }
5. (opcional) Defina a lgica para listar os livros de acordo com o parmetro editora da
URL.
1 //EditorasController.cs
2 public ViewResult Index(string editora)
3 {
4 List<Livro> livros = (editora != null) ? livroRepository.BuscaPorEditora(editora) :-
livroRepository.BuscaTodas();
5 return View(livros);
6 }
1 //LivroRepository.cs
2 public List<Livro> BuscaPorEditora(string nomeEditora)
3 {
4 var consulta = from e in context.Livros
5 where e.Editora.Nome.StartsWith(nomeEditora)
6 select e;
7 return consulta.ToList();
8 }
www.k19.com.br 130
Captulo 9
Validao
9.1 Controller
O primeiro passo para implementar a validao dos parmetros enviados pelos usurios
definir a lgica de validao.
O segundo passo definir mensagens informativas para enviar aos usurios. O ASP.NET
possui um objeto especializado no armazenamento de mensagens de erros de validao (ModelState).
131
Validao
1 [HttpPost]
2 public ActionResult Create(Editora editora)
3 {
4 if (editora.Nome == null || editora.Nome.Trim().Length == 0)
5 {
6 // Erro de Validao
7 ModelState.AddModelError("Nome", "O preenchimento do campo Nome obrigatrio."-
);
8 }
9 if (ModelState.IsValid)
10 {
11 editoraRepository.Adiciona(editora);
12 TempData["mensagem"] = "Editora criada com sucesso!";
13 return RedirectToAction("Index");
14 }
15 else
16 {
17 return View();
18 }
19 }
9.2 View
As mensagens dos erros de validao podem ser acrescentadas na pgina web atravs do
mtodo ValidationSummary da propriedade Html. importante salientar que esse mtodo
adiciona todas as mensagens de erro.
www.k19.com.br 132
Validao
1 @model LivrariaVirtual.Models.Editora
2
3 @{
4 ViewBag.Title = "Cadastro de Editora";
5 }
6
7 <h2>Create</h2>
8
9 @using (Html.BeginForm()) {
10 @Html.ValidationSummary()
11 <fieldset>
12 <legend>Cadastro de Editora</legend>
13
14 <div class="editor-label">
15 @Html.LabelFor(model => model.Nome)
16 </div>
17 <div class="editor-field">
18 @Html.EditorFor(model => model.Nome)
19 </div>
20
21 <div class="editor-label">
22 @Html.LabelFor(model => model.Email)
23 </div>
24 <div class="editor-field">
25 @Html.EditorFor(model => model.Email)
26 </div>
27
28 <p>
29 <input type="submit" value="Create" />
30 </p>
31 </fieldset>
32 }
33 <div>
34 @Html.ActionLink("Listagem de Editoras", "Index")
35 </div>
1 @model LivrariaVirtual.Models.Editora
2
3 @{
4 ViewBag.Title = "Cadastro de Editora";
5 }
6
7 <h2>Create</h2>
8
9 @using (Html.BeginForm()) {
10 @Html.ValidationSummary(true)
11 <fieldset>
12 <legend>Cadastro de Editora</legend>
13
14 <div class="editor-label">
15 @Html.LabelFor(model => model.Nome)
16 </div>
17 <div class="editor-field">
18 @Html.EditorFor(model => model.Nome)
19 @Html.ValidationMessageFor(model => model.Nome)
20 </div>
21
22 <div class="editor-label">
23 @Html.LabelFor(model => model.Email)
24 </div>
25 <div class="editor-field">
26 @Html.EditorFor(model => model.Email)
27 @Html.ValidationMessageFor(model => model.Email)
28 </div>
29
30 <p>
31 <input type="submit" value="Create" />
32 </p>
33 </fieldset>
34 }
35 <div>
36 @Html.ActionLink("Listagem de Editoras", "Index")
37 </div>
9.3 Exerccios
1. Insira a validao dos campos nas editoras e livros da nossa aplicao. A editora deve
ter obrigatoriamente nome e email, e o livro deve ter o nome, preo e editora relaci-
onada. No caso do livro, o preo tambm no pode ser menor que zero. Voc deve
informar ao usurio o erro ocorrido atravs do mtodo Html.ValidationMessage ou
Html.ValidationMessageFor.
www.k19.com.br 134
Validao
1 // EditorasController.cs
2 //
3 // POST: /Editoras/Create
4
5 [HttpPost]
6 public ActionResult Create(Editora editora)
7 {
8 if (editora.Nome == null || editora.Nome.Trim().Length == 0)
9 {
10 // Erro de Validao
11 ModelState.AddModelError("Nome", "O preenchimento do campo Nome obrigatrio."-
);
12 }
13 if (editora.Email == null || editora.Email.Trim().Length == 0)
14 {
15 ModelState.AddModelError("Email", "O preenchimento do campo Email obrigatrio-
.");
16 }
17 if (ModelState.IsValid)
18 {
19 editoraRepository.Adiciona(editora);
20 return RedirectToAction("Index");
21 }
22 else
23 {
24 return View();
25 }
26 }
www.k19.com.br 136
Validao
1 // LivrosController.cs
2 //
3 // POST: /Livros/Create
4 [HttpPost]
5 public ActionResult Create(Livro livro)
6 {
7 if (livro.Titulo == null || livro.Titulo.Trim().Length == 0)
8 {
9 ModelState.AddModelError("Titulo", "O preenchimento do campo Ttulo -
obrigatrio.");
10 }
11 if (livro.Preco <= 0)
12 {
13 ModelState.AddModelError("Preco", "Preencha o campo Preo corretamente.");
14 }
15
16 if (ModelState.IsValid)
17 {
18 livroRepository.Adiciona(livro);
19 return RedirectToAction("Index");
20 }
21 else
22 {
23 return View();
24 }
25
26 }
9.4 Anotaes
As lgicas de validao mais utilizadas tambm podem ser implementadas atravs de ano-
taes 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 fluxo da execuo.
Para utilizar essas anotaes, necessrio adicionar uma dll na aplicao. O nome da dll :
System.ComponentModel.DataAnnotations.dll.
9.4.1 Required
Uma das validaes mais comuns a de campo obrigatrio. Ela pode ser realizada atravs
da anotao Required.
www.k19.com.br 138
Validao
1 [HttpPost]
2 public ActionResult Create(Editora editora)
3 {
4 if (ModelState.IsValid)
5 {
6 editoraRepository.Adiciona(editora);
7 return RedirectToAction("Index");
8 }
9 else
10 {
11 return View();
12 }
13 }
Range
ReqularExpression
StringLength
Nas verses anteriores do MVC para habilitar a validao no lado do cliente era necessrio
chamar explicitamente o mtodo Html.EnableClientValidation na View. No ASP .NET MVC
3 a validao no cliente est habilitada por padro.
Para funcionar corretamente a validao, voc deve acrescentar as referncias corretas das
bibliotecas javascript jQuery e jQuery Validation na View.
9.6 Exerccios
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5 using System.ComponentModel.DataAnnotations;
6
7 namespace LivrariaVirtual.Models
8 {
9 public class Editora
10 {
11 public int Id { get; set; }
12 [Required(ErrorMessage="O campo Nome obrigatrio.")]
13 public string Nome { get; set; }
14 [Required(ErrorMessage="O campo Email obrigatrio")]
15 public string Email { get; set; }
16 public virtual ICollection<Livro> Livros { get; set; }
17
18 }
19 }
www.k19.com.br 140
Validao
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.ComponentModel.DataAnnotations;
6
7 namespace LivrariaVirtual.Models
8 {
9 public class Livro
10 {
11 public int Id { get; set; }
12 [Required(ErrorMessage="O campo Ttulo obrigatrio.")]
13 public string Titulo { get; set; }
14 [Required(ErrorMessage = "O campo Preo obrigatrio.")]
15 public decimal Preco { get; set; }
16 [Required(ErrorMessage = "O campo EditoraId obrigatrio.")]
17 public int EditoraId { get; set; }
18 public virtual Editora Editora { get; set; }
19 }
20 }
1 //EditorasController.cs
2 //
3 // POST: /Editoras/Create
4 [HttpPost]
5 public ActionResult Create(Editora editora)
6 {
7 if (ModelState.IsValid)
8 {
9 editoraRepository.Adiciona(editora);
10 return RedirectToAction("Index");
11 }
12 else
13 {
14 return View();
15 }
16 }
1 //LivrosController.cs
2 //
3 // POST: /Livros/Create
4
5 [HttpPost]
6 public ActionResult Create(Livro livro)
7 {
8 if (ModelState.IsValid)
9 {
10 livroRepository.Adiciona(livro);
11 return RedirectToAction("Index");
12 }
13 else
14 {
15 ViewBag.Editoras = livroRepository.BuscaTodas();
16 return View();
17 }
18 }
www.k19.com.br 142
Validao
www.k19.com.br 144
Captulo 10
Sesso
Quando um cliente for fazer compras na nossa loja virtual ele pode ter, por exemplo, um
carrinho de compras, que uma informao gerada durante a navegao. A medida que ele vi-
sita as pginas, ele pode ir adicionando ou removendo itens do seu carrinho virtual. Porm isto
um problema, pois o protocolo HTTP no armazena estado (stateless) das pginas visitadas
anteriormente. Desse modo no podemos armazenar a informao entre uma pgina e outra.
10.1 Sesso
Nossa tarefa encontrar um modo de armazenar estes dados no servidor e deixar a informa-
o disponvel para diferentes pginas da aplicao. Para solucionar este problema, utilizado
o conceito de sesso. Uma sesso uma maneira de armazenar informaes geradas durante a
navegao no lado do servidor. Como o sistema pode ter vrios usurios navegando simultane-
amente, tambm devemos encontrar uma maneira de separar este conjunto de informaes por
usurio, para que no haja nehum tipo de conflito. Para isto precisamos identificar unicamente
cada usurio da nossa aplicao de maneira que cada um tenha sua prpria sesso.
Reescrita de URL Nesta maneira, o ID embutido nas prprias URLs da aplicao. Sendo
assim o ID pode ser reconhecido pela aplicao em todas as requisies. Uma desvanta-
gem que todas as pginas devem ser geradas dinamicamente para conter o ID em todos
os links e actions. Outro problema que este ID fica aparente na barra de navegao do
navegador facilitando o acesso de pessoas mal intencionadas que poderiam, por sua vez,
145
Sesso
obter informaes confidenciais. Uma vez que a URL no contm mais o identificador,
a aplicao considera que o usurio no tem uma sesso associada.
Cookies Cookie um arquivo criado pelo servidor no navegador do cliente. Uma de suas
funes persistir o ID da sesso. A cada requisio a aplicao consulta o ID da sesso
no cookie para recuperar as informaes do usurio. Esta a maneira mais utilizada.
A sesso pode ser encerrada com a retirada do cookie no navegador. Podemos fazer
explicitamente atravs de uma rotina de logout no servidor, ou podemos deix-la expirar
por tempo de inatividade, ou seja, caso o usurio fique um determinado tempo sem fazer
novas requisies, a sesso encerrada.
Voc pode adicionar qualquer tipo de valor na sesso. De forma anloga, para resgatar
a informao armazenada, basta acessar a chave correspondente no objeto Session, como no
exemplo a seguir:
www.k19.com.br 146
Sesso
InProc
StateServer
SQLServer
Custom
A diferena de cada modo a maneira com que a sesso armazenada. Cada um tem um
State Provider diferente.
No modo InProc todas as informaes da sesso so armazenadas na memria do servi-
dor. Esse o modo mais simples e utilizado, e vem configurado como o padro. Uma das
desvantagens desse modo, a possvel sobrecarga de memria, se forem armazenadas muitas
informaes na sesso. Por isso no indicado para sistemas muito grandes, com muitos usu-
rios navegando simultaneamente. Outro problema que o servidor no pode ser desligado, pois
a informao armazenada na memria ser perdida.
No modo StateServer as informaes so serializadas e enviadas para um servidor inde-
pendente do servidor da aplicao. Isto possibilita que o servidor de aplicao seja reiniciado
sem que as sesses seja perdidas. Uma desvantagem o custo de tempo de serializao e
desserializao.
No modo SQLServer as informaes so serializadas porm armazenadas em um banco
de dados. Este modo tambm permite que o servidor de aplicao seja reiniciado, alm disso
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 identificao de usurio e armazenamento de sesses
pode ser customizado.
Para selecionar algum dos modos disponveis basta adicionar a tag <sessionState> dentro
da tag <system.web>, no arquivo Web.Config.
1 <sessionState mode="InProc"/>
Outra possibilidade desabilitar o uso de cookie com o atributo cookieless. Neste caso ser
utilizada a reescrita de URL.
Se nenhum modo for selecionado o modo InProc ser utilizado por padro.
10.4 Exerccios
1. Para introduzirmos o conceito de sesso na nossa livraria virtual precisamos primeiro adi-
cionar uma entidade Cliente na nossa aplicao. Seguindo os moldes de Editora e Livros
crie a classe Cliente, a classe ClienteRepository, um controlador ClientesController (para
listar, buscar, atualizar, remover e adicionar) e todas as pginas cshtml relacionadas.
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5 using System.ComponentModel.DataAnnotations;
6 using System.Web.Mvc;
7
8
9 namespace LivrariaVirtual.Models
10 {
11 public class Cliente
12 {
13 public int Id { get; set; }
14 [Required(ErrorMessage="O campo Nome obrigatrio")]
15 public string Nome { get; set; }
16 [Required(ErrorMessage="O campo Usurio obrigatrio")]
17 public string Usuario { get; set; }
18 [DataType(DataType.Password)]
19 public string Senha { get; set; }
20 [NotMapped]
21 [DataType(DataType.Password)]
22 [Compare("Senha",ErrorMessage="A confirmao da senha est incorreta.")]
23 public string ComparaSenha { get; set; }
24 }
25 }
www.k19.com.br 148
Sesso
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5 using System.Data;
6
7 namespace LivrariaVirtual.Models
8 {
9 public class ClienteRepository
10 {
11 private LivrariaContext context = new LivrariaContext();
12 public void Adiciona(Cliente c)
13 {
14 context.Clientes.Add(c);
15 context.SaveChanges();
16 }
17
18 public void Atualiza(Cliente c)
19 {
20 context.Entry(c).State = EntityState.Modified;
21 context.SaveChanges();
22 }
23
24 public void Remove(Cliente c)
25 {
26 context.Entry(c).State = EntityState.Deleted;
27 context.SaveChanges();
28 }
29
30 public void Remove(int id)
31 {
32 Cliente c = context.Clientes.Find(id);
33 context.Clientes.Remove(c);
34 context.SaveChanges();
35 }
36
37 public Cliente Busca(int id)
38 {
39 return context.Clientes.Find(id);
40 }
41
42 public List<Cliente> BuscaTodas()
43 {
44 return context.Clientes.ToList();
45 }
46 }
47 }
1 using System;
2 using System.Collections.Generic;
3 using System.Data;
4 using System.Data.Entity;
5 using System.Linq;
6 using System.Web;
7 using System.Web.Mvc;
8 using LivrariaVirtual.Models;
9
10 namespace LivrariaVirtual.Controllers
11 {
12 public class ClientesController : Controller
13 {
14 private ClienteRepository clienteRepository = new ClienteRepository();
15
16 //
17 // GET: /Clientes/
18
19 public ViewResult Index()
20 {
21 return View(clienteRepository.BuscaTodas());
22 }
23
24 //
25 // GET: /Clientes/Details/5
26
27 public ViewResult Details(int id)
28 {
29 Cliente cliente = clienteRepository.Busca(id);
30 return View(cliente);
31 }
32
33 //
34 // GET: /Clientes/Create
35
36 public ActionResult Create()
37 {
38 return View();
39 }
40
41 //
42 // POST: /Clientes/Create
43
44 [HttpPost]
45 public ActionResult Create(Cliente cliente)
46 {
47 if (ModelState.IsValid)
48 {
49 clienteRepository.Adiciona(cliente);
50 return RedirectToAction("Index");
51 }
52
53 return View(cliente);
54 }
55
56 //
57 // GET: /Clientes/Edit/5
58
59 public ActionResult Edit(int id)
60 {
61 Cliente cliente = clienteRepository.Busca(id);
62 return View(cliente);
63 }
64
65 //
66 // POST: /Clientes/Edit/5
67
68 [HttpPost]
69 public ActionResult Edit(Cliente cliente)
70 {
71 if (ModelState.IsValid)
72 {
73 clienteRepository.Atualiza(cliente);
74 return RedirectToAction("Index");
75 }
76 return View(cliente);
77 }
78
79 //
80 // GET: /Clientes/Delete/5
81
82 public ActionResult Delete(int id)
83 {
84 Cliente cliente = clienteRepository.Busca(id);
85 return View(cliente);
86 }
87
88 //
89 // POST: /Clientes/Delete/5
90
www.k19.com.br 150
Sesso
91 [HttpPost, ActionName("Delete")]
92 public ActionResult DeleteConfirmed(int id)
93 {
94 clienteRepository.Remove(id);
95 return RedirectToAction("Index");
96 }
97 }
98 }
www.k19.com.br 152
Sesso
1 //~/Models/ClienteRepository.cs
2 public Cliente Busca(string usuario, string senha)
3 {
4 var consulta = from e in context.Clientes
5 where e.Usuario.Equals(usuario) && e.Senha.Equals(senha)
6 select e;
7 string query = consulta.ToString();
8 return consulta.First();
9 }
10
11 public bool Autentica(string usuario, string senha)
12 {
13 var consulta = from e in context.Clientes
14 where e.Usuario.Equals(usuario) && e.Senha.Equals(senha)
15 select e;
16 return consulta.ToList().Count >= 1;
17 }
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5 using System.Web.Mvc;
6 using LivrariaVirtual.Models;
7
8 namespace LivrariaVirtual.Controllers
9 {
10 public class LoginController : Controller
11 {
12 private ClienteRepository clienteRepository = new ClienteRepository();
13 //
14 // GET: /Login/
15
16 public ActionResult Index()
17 {
18 return View();
19 }
20
21 [HttpPost]
22 public ActionResult Index(string usuario, string senha)
23 {
24 if (clienteRepository.Autentica(usuario,senha))
25 {
26 Session["cliente"] = clienteRepository.Busca(usuario, senha);
27 return RedirectToAction("Index", "Editoras");
28 }
29 else
30 {
31 TempData["mensagem"] = "Usurio e senha incorretos";
32 return View();
33 }
34
35 }
36
37 public ActionResult Logout()
38 {
39 Session.Abandon();
40 return Redirect("/");
41 }
42
43 }
44 }
www.k19.com.br 154
Sesso
Este cdigo faz com que aparea o nome do cliente logado e um link para logout somente
se o cliente estiver logado. Note que podemos navegar no sistema sem que estejamos
logados. Este problema ser tratado no captulo de Filtros.
www.k19.com.br 156
Captulo 11
Filtros
Muitas vezes em um sistema queremos restringir o acesso determinadas reas, seja por
segurana ou por organizao.Por exemplo, na nossa aplicao poderamos definir que para
poder adicionar, alterar e remover tanto categorias quanto produtos, o usurio deve estar logado
no sistema. Caso contrrio, o usurio apenas pode listar as categorias e produtos.
No exemplo acima, caso um usurio tente adicionar uma categoria atravs do formulrio
de cadastro, o mtodo vai verificar se o usurio j est logado, atravs do uso da sesso visto
no captulo anterior. Seno estiver logado, ele ser redirecionado para a pgina de Login .
Apesar de funcionar, este cdigo apresenta uma inconvenincia. Temos que adicionar essa
lgica a todas as Actions que queremos que tenha o mesmo comportamento, ou seja, que apenas
permitam o acesso de usurios logados.
Em outros casos, podemos querer que algumas Actions executem alguma tarefa em comum.
Por exemplo, na nossa loja virtual, poderamos adicionar uma mensagem em um arquivo de Log
sempre que uma Action fosse realizada. Desse modo, poderamos guardar um histrico sobre
o que a aplicao mais realizou, qual foi a pgina mais visitada, etc. Mas novamente, teramos
que adicionar a mesma tarefa em todas as Actions da nossa aplicao.
Nesses casos, em que vrias Actions possuem um mesmo comportamento em comum, po-
demos utilizar o conceito de Filtros. Um filtro semelhante a um mtodo que executado antes
ou depois que uma Action realizada.
157
Filtros
esteja logado (autenticado) para acessar determinadas reas da aplicao. Para isso precisamos
adicionar o seguinte cdigo no nosso mtodo de login:
1 FormsAuthentication.SetAuthCookie(cliente.Usuario, false);
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 identifique). 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 realizar o seguinte cdigo no logout:
1 FormsAuthentication.SignOut();
Para adicionar o filtro, devemos incluir a anotao Authorize nas Actions em que deseja-
mos a autenticao:
1 [Authorize]
2 public ActionResult FormularioCadastro()
3 {
4 return base.View();
5 }
1 [Authorize]
2 public class CategoriaController : Controller
3 {
4 ...
5 }
Desse modo, todas as Actions presentes no controlador da categoria exigem que o usurio
esteja autenticado.
Quando o filtro de autenticao barra um usurio de acessar uma pgina, podemos redirecion-
lo para a pgina de login. Devemos incluir o seguinte cdigo dentro da tag <system.web>:
1 <authentication mode="Forms">
2 <forms loginUrl="~/Login" timeout="2880"/>
3 </authentication>
Para checar se a sesso est autenticada, podemos utilizar o atributo IsAuthenticated, como
a seguir:
1 if (User.Identity.IsAuthenticated)
2 {
3 ...
4 }
www.k19.com.br 158
Filtros
Isto ir pegar o nome que passamos como parmetro para o mtodo SetAuthCookie.
11.2 Exerccios
1. Altere a aplicao do captulo anterior para incluir autenticao nas Actions de adicionar,
alterar e remover de editoras e livros. Na Action de Login do LoginController, adicione
o cookie de autenticao como visto na seo anterior, passando o nome de usuario como
parmetro. No layout principal, altere a seo que mostra o nome do usurio, para utilizar
a informao do cookie de autenticao, e no mais da sesso. Caso o usurio no esteja
autenticado, e tente acessar uma das Actions acima, redirecione atravs do Web.Config
para a Action de Login.
O nome utilizado na classe o mesmo utilizado nas anotaes das Actions, excluindo o su-
fixo attribute. Por exemplo, para aplicar o filtro LogAttribute no mtodo que lista as categorias:
1 [Log]
2 public ActionResult Lista()
3 {
4 ...
5 }
Para fazer o filtro funcionar, deve ser implementado um ou mais dos seguintes mtodos:
OnActionExecuting(ActionExecutedContext filterContext);
OnActionExecuted(ActionExecutingContext filterContext);
OnResultExecuting(ResultExecutedContext filterContext);
OnResultExecuted(ResultExecutingContext filterContext);
Eles so executados na mesma ordem em que aparecem acima, sendo que todos so execu-
tados antes da renderizao da pgina. Logo, o nosso exemplo com o filtro de log poderia ficar
assim:
Sendo que a classe LogAttribute precisa ter um atributo ou propriedade com o mesmo
nome do parmetro passado.
11.4 Exerccios
2. Crie um filtro chamado LogAttribute, que grava mensagens em um arquivo de Log, cha-
mado log.txt sempre que uma Action chamada. A informao no log deve incluir
a data, horrio e pequena descrio da Action realizada. Aplique este filtro a todas as
Actions do sistema. (Dica: utilize a classe FileInfo e seu mtodo AppendText para criar
o arquivo de log e a classe StreamWriter para escrever, e passe um parmetro para o
filtro para identificar a ao que est sendo realizada).
www.k19.com.br 160
Captulo 12
Projeto
Nos captulos anteriores, vimos os recursos do ASP .NET MVC e do Entity Framework.
Agora, vamos solidificar os conhecimentos obtidos e, alm disso, mostraremos alguns padres
e conceitos relacionados ao desenvolvimento de aplicaes web.
Como exemplo de aplicao desenvolveremos uma aplicao de cadastro de jogadores e
selees de futebol.
12.1 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.
12.2 Exerccios
1. Crie um projeto do tipo ASP .NET MVC 3 Web Application chamado K19-CopaDoMundo
seguindo os passos vistos no exerccio do captulo 4.
1 namespace K19_CopaDoMundo.Models
2 {
3 public class Selecao
4 {
5 public string Pais { get; set; }
6 public string Tecnico { get; set; }
7 }
8 }
161
Projeto
1 namespace K19_CopaDoMundo.Models
2 {
3 public class Jogador
4 {
5 public string Nome { get; set; }
6 public string Posicao { get; set; }
7 public DateTime Nascimento { get; set; }
8 public double Altura { get; set; }
9 public Selecao Selecao { get; set; }
10
11 }
12 }
12.4 Exerccios
1 using System.ComponentModel.DataAnnotations;
2
3 namespace K19_CopaDoMundo.Models
4 {
5 [Table("Selecoes")]
6 public class Selecao
7 {
8 public int Id { get; set; }
9 public string Pais { get; set; }
10 public string Tecnico { get; set; }
11 public virtual ICollection<Jogador> Jogadores { get; set; }
12 }
13 }
www.k19.com.br 162
Projeto
1 using System.ComponentModel.DataAnnotations;
2
3 namespace K19_CopaDoMundo.Models
4 {
5 [Table("Jogadores")]
6 public class Jogador
7 {
8 public int Id { get; set; }
9 public string Nome { get; set; }
10 public string Posicao { get; set; }
11 public DateTime Nascimento { get; set; }
12 public double Altura { get; set; }
13 public int SelecaoId { get; set; }
14 [InverseProperty("Jogadores")]
15 public virtual Selecao Selecao { get; set; }
16
17 }
18 }
1 using System.Data.Entity;
2
3 namespace K19_CopaDoMundo.Models
4 {
5 public class CopaDoMundoContext : DbContext
6 {
7 public DbSet<Selecao> Selecoes { get; set; }
8 public DbSet<Jogador> Jogadores { get; set; }
9 }
10 }
12.6 Exerccios
4. Acrescente ao arquivo Web.config, que fica na raiz do projeto, a string de conexo.
1 <connectionStrings>
2 <add
3 name="CopaDoMundoContext" providerName="System.Data.SqlClient"
4 connectionString="Server=.\SQLEXPRESS;Database=copadomundo;
5 User Id=sa; Password=sa;Trusted_Connection=False;Persist Security Info=True;-
MultipleActiveResultSets=True"/>
6 </connectionStrings>
5. Altere a estratgia de criao do banco de dados. Para isto, acrescente ao mtodo Appli-
cation_Start definido no arquivo Global.asax o seguinte trecho de cdigo.
1 //Global.asax
2 protected void Application_Start()
3 {
4 AreaRegistration.RegisterAllAreas();
5 // Alterando a estratgia de criao do banco de dados
6 Database.SetInitializer(new DropCreateDatabaseIfModelChanges<K19_CopaDoMundo.Models-
.CopaDoMundoContext>());
7 RegisterGlobalFilters(GlobalFilters.Filters);
8 RegisterRoutes(RouteTable.Routes);
9 }
12.8 Exerccios
www.k19.com.br 164
Projeto
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5
6 namespace K19_CopaDoMundo.Models
7 {
8 public class SelecaoRepository : IDisposable
9 {
10 private bool disposed = false;
11
12 private CopaDoMundoContext context;
13
14 public SelecaoRepository(CopaDoMundoContext context)
15 {
16 this.context = context;
17 }
18
19 public void Adiciona(Selecao selecao)
20 {
21 context.Selecoes.Add(selecao);
22 }
23
24 public List<Selecao> Selecoes
25 {
26 get
27 {
28 return context.Selecoes.ToList();
29 }
30 }
31 public void Salva()
32 {
33 context.SaveChanges();
34 }
35
36 protected virtual void Dispose(bool disposing)
37 {
38 if (!this.disposed)
39 {
40 if (disposing)
41 {
42 context.Dispose();
43 }
44 }
45 this.disposed = true;
46 }
47
48 public void Dispose()
49 {
50 Dispose(true);
51 GC.SuppressFinalize(this);
52 }
53 }
54 }
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5
6 namespace K19_CopaDoMundo.Models
7 {
8 public class JogadorRepository : IDisposable
9 {
10 private bool disposed = false;
11 private CopaDoMundoContext context;
12
13 public JogadorRepository(CopaDoMundoContext context)
14 {
15 this.context = context;
16 }
17
18 public void Adiciona(Jogador jogador)
19 {
20 context.Jogadores.Add(jogador);
21 }
22
23 public List<Jogador> Jogadores
24 {
25 get { return context.Jogadores.ToList(); }
26 }
27
28 public void Salva()
29 {
30 context.SaveChanges();
31 }
32
33 protected virtual void Dispose(bool disposing)
34 {
35 if (!this.disposed)
36 {
37 if (disposing)
38 {
39 context.Dispose();
40 }
41 }
42 this.disposed = true;
43 }
44
45 public void Dispose()
46 {
47 Dispose(true);
48 GC.SuppressFinalize(this);
49 }
50 }
51 }
12.9 Exerccios
8. Crie uma classe UnitOfWork na pasta Models.
www.k19.com.br 166
Projeto
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5
6 namespace K19_CopaDoMundo.Models
7 {
8 public class UnitOfWork : IDisposable
9 {
10 private bool disposed = false;
11 private CopaDoMundoContext context = new CopaDoMundoContext();
12 private SelecaoRepository selecaoRepository;
13 private JogadorRepository jogadorRepository;
14
15
16 public JogadorRepository JogadorRepository
17 {
18 get
19 {
20 if (jogadorRepository == null)
21 {
22 jogadorRepository = new JogadorRepository(context);
23 }
24 return jogadorRepository;
25 }
26 }
27
28 public SelecaoRepository SelecaoRepository
29 {
30 get
31 {
32 if (selecaoRepository == null)
33 {
34 selecaoRepository = new SelecaoRepository(context);
35 }
36 return selecaoRepository;
37 }
38 }
39
40 public void Salva()
41 {
42 context.SaveChanges();
43 }
44
45 protected virtual void Dispose(bool disposing)
46 {
47 if (!this.disposed)
48 {
49 if (disposing)
50 {
51 context.Dispose();
52 }
53 }
54 this.disposed = true;
55 }
56
57 public void Dispose()
58 {
59 Dispose(true);
60 GC.SuppressFinalize(this);
61 }
62 }
63 }
12.11 Exerccios
9. Na pasta Content, altere o arquivo Site.css acrescentando algumas regras CSS.
1 .logo{
2 vertical-align: middle;
3 }
4
5 .botao {
6 background-color: #064D83;
7 margin: 0 0 0 20px;
8 color: white;
9 text-decoration: none;
10 font-size: 20px;
11 line-height: 20px;
12 padding: 5px;
13 vertical-align: middle;
14 }
15
16 .botao:hover{
17 background-color: #cccccc;
18 color: #666666;
19 }
20
21 .formulario fieldset{
22 float: left;
23 margin: 0 0 20px 0;
24 border: 1px solid #333333;
25 }
26
27 .formulario fieldset legend{
28 color: #064D83;
29 font-weight: bold;
30 }
31
32 .botao-formulario{
33 background-color: #064D83;
34 color: #ffffff;
35 padding: 5px;
36 vertical-align: middle;
37 border: none;
38 }
39
40 .titulo {
41 color: #064D83;
42 clear: both;
43 }
44
45 .tabela{
46 border: 1px solid #064D83;
47 border-collapse: collapse;
48 }
49
50 .tabela tr th{
51 background-color: #064D83;
52 color: #ffffff;
53 }
54
55 .tabela tr th,
56 .tabela tr td{
www.k19.com.br 168
Projeto
10. Copie o arquivo k19-logo.png da pasta K19-Arquivos da sua rea de Trabalho para a
pasta Content.
11. Agora altere o arquivo _Layout.cshtml.
Na tela de selees, vamos adicionar um formulrio para cadastrar novas selees e uma
tabela para apresentar as j cadastradas. Aplicaremos regras de validao especficas para ga-
rantir que nenhum dado incorreto seja armazenado no banco de dados.
12.13 Exerccios
1 using System;
2 using System.Collections.Generic;
3 using System.Data;
4 using System.Data.Entity;
5 using System.Linq;
6 using System.Web;
7 using System.Web.Mvc;
8 using K19_CopaDoMundo.Models;
9
10 namespace K19_CopaDoMundo.Controllers
11 {
12 public class SelecoesController : Controller
13 {
14 private UnitOfWork unitOfWork = new UnitOfWork();
15
16 public ActionResult Create()
17 {
18 return View();
19 }
20
21 protected override void Dispose(bool disposing)
22 {
23 unitOfWork.Dispose();
24 base.Dispose(disposing);
25 }
26 }
27 }
13. Vamos criar uma tela Create.cshtml para cadastrar as selees. Adicione o arquivo a
pasta Views/Selecoes com o seguinte contedo.
www.k19.com.br 170
Projeto
14. O prximo passo definir a action que ir salvar a seleo no nosso banco de dados.
Devemos tambm acrescentar as validaes a nossa entidade.
1 //SelecoesController.cs
2 [HttpPost]
3 public ActionResult Create(Selecao selecao)
4 {
5 if (ModelState.IsValid)
6 {
7 unitOfWork.SelecaoRepository.Adiciona(selecao);
8 unitOfWork.Salva();
9 return RedirectToAction("Index");
10 }
11 return View(selecao);
12 }
1 //Selecao.cs
2 using System.ComponentModel.DataAnnotations;
3
4 namespace K19_CopaDoMundo.Models
5 {
6 [Table("Selecoes")]
7 public class Selecao
8 {
9 public int Id { get; set; }
10 [Required(ErrorMessage="O campo Pais obrigatrio.")]
11 public string Pais { get; set; }
12 [Required(ErrorMessage="O campo Tecnico obrigatrio.")]
13 public string Tecnico { get; set; }
14 public virtual ICollection<Jogador> Jogadores { get; set; }
15 }
16 }
1 //SelecoesController.cs
2 public ActionResult Index()
3 {
4 return View(unitOfWork.SelecaoRepository.Selecoes);
5 }
16. Vamos definir a tela de listagem de Selees como a pgina principal do nosso site. Altere
a rota padro no arquivo Global.asax.
www.k19.com.br 172
Projeto
1 //Global.asax
2 routes.MapRoute(
3 "Default", // Route name
4 "{controller}/{action}/{id}", // URL with parameters
5 new { controller = "Selecoes", action = "Index", id = UrlParameter.Optional } -
// Parameter defaults
6 );
12.15 Exerccios
17. Acrescente uma coluna na tabela de listagem de selees.
18. Defina um mtodo Busca na classe SelecaoRepository que retorna uma entidade seleo
a partir de um parmetro id.
1 //SelecaoRepository.cs
2 public Selecao Busca(int id)
3 {
4 return context.Selecoes.Find(id);
5 }
19. Defina uma action Delete que ir mostrar a tela de confirmao de remoo da entidade.
1 //SelecoesController.cs
2 public ActionResult Delete(int id)
3 {
4 Selecao selecao = unitOfWork.SelecaoRepository.Busca(id);
5 return View(selecao);
6 }
21. Defina um mtodo na classe SelecaoRepository que remove uma entidade seleo a
partir de um parmetro id.
1 //SelecaoRepository.cs
2 public void Remove(int id)
3 {
4 Selecao selecao = Busca(id);
5 context.Selecoes.Remove(selecao);
6 }
www.k19.com.br 174
Projeto
1 //SelecoesController.cs
2 [HttpPost]
3 [ActionName("Delete")]
4 public ActionResult DeleteConfirmed(int id)
5 {
6 unitOfWork.SelecaoRepository.Remove(id);
7 unitOfWork.Salva();
8 return RedirectToAction("Index");
9 }
12.17 Exerccios
23. Para cadastrar o jogador, devemos definir o controlador.
1 using System;
2 using System.Collections.Generic;
3 using System.Data;
4 using System.Data.Entity;
5 using System.Linq;
6 using System.Web;
7 using System.Web.Mvc;
8 using K19_CopaDoMundo.Models;
9
10 namespace K19_CopaDoMundo.Controllers
11 {
12 public class JogadoresController : Controller
13 {
14 private UnitOfWork unitOfWork = new UnitOfWork();
15
16 public ActionResult Create()
17 {
18 ViewBag.SelecaoId = new SelectList(unitOfWork.SelecaoRepository.Selecoes, "-
Id", "Pais");
19 return View();
20 }
21
22 protected override void Dispose(bool disposing)
23 {
24 unitOfWork.Dispose();
25 base.Dispose(disposing);
26 }
27 }
28 }
24. Vamos criar uma tela Create.cshtml para cadastrar os jogadores. Adicione o arquivo a
pasta Views/Jogadores com o seguinte contedo.
25. O prximo passo definir a action que ir salvar o jogador no nosso banco de dados.
Devemos tambm acrescentar as validaes a nossa entidade.
www.k19.com.br 176
Projeto
1 //JogadoresController.cs
2 [HttpPost]
3 public ActionResult Create(Jogador jogador)
4 {
5 if (ModelState.IsValid)
6 {
7 unitOfWork.JogadorRepository.Adiciona(jogador);
8 unitOfWork.Salva();
9 }
10 ViewBag.SelecaoId = new SelectList(unitOfWork.SelecaoRepository.Selecoes, "-
Id", "Pais");
11 return View();
12 }
1 using System.ComponentModel.DataAnnotations;
2
3 namespace K19_CopaDoMundo.Models
4 {
5 [Table("Jogadores")]
6 public class Jogador
7 {
8 public int Id { get; set; }
9 [Required(ErrorMessage="O campo Nome obrigatrio.")]
10 public string Nome { get; set; }
11 [Required(ErrorMessage = "O campo Posicao obrigatrio.")]
12 public string Posicao { get; set; }
13 [Required(ErrorMessage = "O campo Nascimento obrigatrio.")]
14 [DataType(DataType.Date)]
15 public DateTime Nascimento { get; set; }
16 [Required(ErrorMessage = "O campo Altura obrigatrio.")]
17 public double Altura { get; set; }
18 public int SelecaoId { get; set; }
19 [InverseProperty("Jogadores")]
20 public virtual Selecao Selecao { get; set; }
21
22 }
23 }
1 //JogadoresController.cs
2 public ActionResult Index()
3 {
4 return View(unitOfWork.JogadorRepository.Jogadores);
5 }
12.19 Exerccios
27. Acrescente uma coluna na tabela de listagem de jogadores.
www.k19.com.br 178
Projeto
28. Defina um mtodo Busca na classe JogadorRepository que retorna uma entidade joga-
dor a partir de um parmetro id.
1 //JogadorRepository.cs
2 public Jogador Busca(int id)
3 {
4 return context.Jogadores.Find(id);
5 }
29. Defina uma action Delete que ir mostrar a tela de confirmao de remoo da entidade.
1 //JogadoresController.cs
2 public ActionResult Delete(int id)
3 {
4 Jogador jogador = unitOfWork.JogadorRepository.Busca(id);
5 return View(jogador);
6 }
31. Defina um mtodo na classe JogadorRepository que remove uma entidade jogador a
partir de um parmetro id.
1 //JogadorRepository.cs
2 public void Remove(int id)
3 {
4 Jogador jogador = context.Jogadores.Find(id);
5 context.Jogadores.Remove(jogador);
6 }
www.k19.com.br 180
Projeto
1 //JogadoresController.cs
2 [HttpPost]
3 [ActionName("Delete")]
4 public ActionResult DeleteConfirmed(int id)
5 {
6 unitOfWork.JogadorRepository.Remove(id);
7 unitOfWork.Salva();
8 return RedirectToAction("Index");
9 }
Na maioria dos casos, as aplicaes devem controlar o acesso dos usurios. Vamos imple-
mentar um mecanismo de autenticao na nossa aplicao utilizando filtro e Membership. As
requisies feitas pelos usurios passaro pelo filtro. A funo do filtro verificar se o usu-
rio est logado ou no. Se estiver logado o filtro autoriza o acesso. Caso contrrio, o filtro
redirecionar o usurio para a tela de login.
12.21 Exerccios
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web.Mvc;
5 using System.ComponentModel.DataAnnotations;
6
7 namespace K19_CopaDoMundo.Models
8 {
9
10 public class ChangePasswordModel
11 {
12 [Required]
13 [DataType(DataType.Password)]
14 [Display(Name = "Senha")]
15 public string OldPassword { get; set; }
16
17 [Required]
18 [StringLength(100, ErrorMessage = "O {0} deve ter no mnimo {2} caracteres.", -
MinimumLength = 6)]
19 [DataType(DataType.Password)]
20 [Display(Name = "Nova senha")]
21 public string NewPassword { get; set; }
22
23 [DataType(DataType.Password)]
24 [Display(Name = "Confirmao de senha")]
25 [Compare("NewPassword", ErrorMessage = "A senha e a confirmao no conferem.")-
]
26 public string ConfirmPassword { get; set; }
27 }
28
29 public class LogOnModel
30 {
31 [Required]
32 [Display(Name = "Usurio")]
33 public string UserName { get; set; }
34
35 [Required]
36 [DataType(DataType.Password)]
37 [Display(Name = "Senha")]
38 public string Password { get; set; }
39
40 [Display(Name = "Lembrar?")]
41 public bool RememberMe { get; set; }
42 }
43
44 public class RegisterModel
45 {
46 [Required]
47 [Display(Name = "Usurio")]
48 public string UserName { get; set; }
49
50 [Required]
51 [DataType(DataType.EmailAddress)]
52 [Display(Name = "Email")]
53 public string Email { get; set; }
54
55 [Required]
56 [StringLength(100, ErrorMessage = "O {0} deve ter no mnimo {2} caracteres.", -
MinimumLength = 6)]
57 [DataType(DataType.Password)]
58 [Display(Name = "Senha")]
59 public string Password { get; set; }
60
61 [DataType(DataType.Password)]
62 [Display(Name = "Confirmao de senha")]
63 [Compare("Password", ErrorMessage = "A senha e a confirmao no conferem.")]
64 public string ConfirmPassword { get; set; }
65 }
66
67 }
www.k19.com.br 182
Projeto
www.k19.com.br 184
Projeto
131 }
132 else
133 {
134 ModelState.AddModelError("", "A senha atual ou a confirmao est -
incorreta.");
135 }
136 }
137
138
139 return View(model);
140 }
141
142 //
143 // GET: /Usuario/ChangePasswordSuccess
144
145 public ActionResult ChangePasswordSuccess()
146 {
147 return View();
148 }
149
150 #region Status Codes
151 private static string ErrorCodeToString(MembershipCreateStatus createStatus)
152 {
153 // See http://go.microsoft.com/fwlink/?LinkID=177550 for
154 // a full list of status codes.
155 switch (createStatus)
156 {
157 case MembershipCreateStatus.DuplicateUserName:
158 return "Este nome de usurio j existe. Defina outro usurio.";
159
160 case MembershipCreateStatus.DuplicateEmail:
161 return "Este email j foi cadastrado. Defina outro email.";
162
163 case MembershipCreateStatus.InvalidPassword:
164 return "Senha incorreta.";
165
166 case MembershipCreateStatus.InvalidEmail:
167 return "Email invlido.";
168
169 case MembershipCreateStatus.InvalidAnswer:
170 return "Resposta invlida para recuperar a senha.";
171
172 case MembershipCreateStatus.InvalidQuestion:
173 return "Questo invlida para recuperar a senha.";
174
175 case MembershipCreateStatus.InvalidUserName:
176 return "Usurio invlido.";
177
178 case MembershipCreateStatus.ProviderError:
179 return "Ocorreu um erro durante a autenticao. Se o problema -
persistir, contate o administrador.";
180
181 case MembershipCreateStatus.UserRejected:
182 return "O cadastro do usurio foi cancelado. Se o problema -
persistir, contate o administrador.";
183
184 default:
185 return "Um erro inesperado ocorreu. Se o problema persistir, -
contate o administrador.";
186 }
187 }
188 #endregion
189 }
190
191 }
35. Crie uma pasta Usuario na pasta Views e acrescente os quatro arquivos abaixo.
www.k19.com.br 186
Projeto
www.k19.com.br 188
Projeto
Antes de definir o filtro Authorize nos controladores de nosso site, vamos criar um usurio
com acesso. A maneira mais fcil de criar o usurio atravs do ASP .NET Configuration.
12.22 Exerccios
37. Isto executar um ambiente de configurao. Abra a aba Security e clique no link
Enable roles.
www.k19.com.br 190
Projeto
12.23 Exerccios
42. Altere o filtro de autenticao no Web.config para redirecionar o usurio para a action
LogOn do controlador Usuario.
43. Acrescente a seguinte string de conexo no arquivo Web.config para definir o local que
as informaes dos usurios sero armazenadas (No nosso caso, teremos duas strings de
conexo).
44. Defina o provedor padro que ser utilizado. No nosso caso, utilizaremos o provedor
padro SqlMembershipProvider.
www.k19.com.br 192
Projeto
1 //SelecoesController.cs
2 [Authorize(Roles="Administrador")]
3 public class SelecoesController : Controller
1 //JogadoresController.cs
2 [Authorize(Roles="Administrador")]
3 public class JogadoresController : Controller
12.25 Exerccios
46. Acrescente ao arquivo Web.config a tag customErrors para especificar a pgina de erro
padro. A tag customErrors fica dentro da tag system.web.
1 <system.web>
2 <!-- ... -->
3 <customErrors mode="On" defaultRedirect="~/Erro/Desconhecido">
4 <error statusCode="404" redirect="~/Erro/PaginaNaoEncontrada"/>
5 </customErrors>
6 <!-- ... -->
7 </system.web>
47. Defina o controlador Erro e as pginas de erros padro. As pginas de erro padro sero
criadas dentro da pasta Views numa subpasta Erro.
1 namespace K19_CopaDoMundo.Controllers
2 {
3 public class ErroController : Controller
4 {
5 //
6 // GET: /Erro/Desconhecido
7
8 public ActionResult Desconhecido()
9 {
10 return View();
11 }
12
13 //
14 // GET: /Erro/PaginaNaoEncontrada
15 public ActionResult PaginaNaoEncontrada()
16 {
17 return View();
18 }
19
20 }
21 }
48. Altere o mtodo de listagem de jogadores para criar um erro em nosso site.
1 //JogadoresController.cs
2 // GET: /Jogadores
3 public ActionResult Index()
4 {
5 //return View(unitOfWork.JogadorRepository.Jogadores);
6 return View();
7 }
12.27 Exerccios
49. Altere a tela de erro adicionando um formulrio para o usurio escrever uma mensagem
para os administradores da aplicao.
www.k19.com.br 194
Projeto
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 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5 using System.Web.Mvc;
6 using System.Web.Helpers;
7
8 namespace K19_CopaDoMundo.Controllers
9 {
10 public class EmailController : Controller
11 {
12
13 public EmailController()
14 {
15 WebMail.SmtpServer = "smtp.gmail.com";
16 WebMail.EnableSsl = true;
17 WebMail.SmtpPort = 587;
18 WebMail.From = "USUARIO@gmail.com";
19 WebMail.UserName = "USUARIO@gmail.com";
20 WebMail.Password = "SENHA";
21 }
22 //
23 // POST: /Email/Envia
24 [HttpPost]
25 public ActionResult Envia(string mensagem)
26 {
27
28 WebMail.Send("EMAIL", "Copa do Mundo - Erro", mensagem);
29 return View();
30 }
31
32 }
33 }
51. Crie uma pgina Envia.cshtml para mostrar ao usurio que a mensagem foi enviada com
sucesso e acrescente um link para a pgina inicial do site.
www.k19.com.br 196