Buscar

.netcore mvc

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 234 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 234 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 234 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

.
1
25
28
Sumário
1	Introdução	ao	ASP.NET	Core
1.1	Um	breve	resumo	sobre	o	modelo	de	comunicação	na	Web 2
1.2	Criando	um	projeto	ASP.NET	Core	MVC	com	o	Visual	Studio	(Windows	ou	MacOS) 4
1.3	Criando	um	projeto	ASP.NET	Core	MVC	em	outros	ambientes 6
1.4	A	estrutura	de	uma	aplicação	ASP.NET	Core	MVC 6
1.5	Página	inicial	e	convenções	do	ASP.NET	MVC 7
1.6	Rodando	a	aplicação 9
1.7	O	sistema	de	roteamento	do	ASP.NET	Core	MVC 9
1.8	Exercícios 24
1.9	Criando	tela	de	listagem	de	posts 12
1.10	Geração	dinâmica	da	tabela	a	partir	dos	posts	do	blog 13
1.11	Exercícios 24
1.12	Outra	maneira	de	enviar	informações	para	a	view 17
1.13	Exercícios 24
1.14	Incluindo	um	post	através	de	um	formulário	HTML 19
1.15	Exercícios 24
1.16	Descobrindo	os	métodos	das	requisições	HTTP 22
1.17	Exercícios 24
1.18	O	que	vem	pela	frente? 24
1.19	Conclusão 24
2	Código	de	qualidade	com	o	padrão	MVC
2.1	Exercícios 27
3	Persistindo	posts	em	um	Banco	de	Dados
3.1	Identificando	unicamente	um	post 29
3.2	Abrindo	a	conexão	com	o	ADO.NET 29
3.3	Isolando	a	string	de	conexão 30
3.4	Isolando	a	conexão	em	sua	própria	classe 31
3.5	Exercícios 41
SumárioCaelum
43
56
66
79
3.6	Listando	os	posts	do	banco 34
3.7	DAO	-	Data	Access	Object 36
3.8	Exercícios 41
3.9	Inclusão	do	post	no	banco	de	dados 37
3.10	Exercícios 41
3.11	Prevenindo	problemas	de	segurança 40
3.12	Exercícios 41
3.13	Conclusão 42
4	Facilitando	o	acesso	ao	banco	com	o	Entity	Framework
4.1	O	que	é	uma	ferramenta	de	mapeamento	objeto-relacional? 43
4.2	Entity	Framework	Core 44
4.3	Lendo	e	gravando	informações	através	do	DbSet 47
4.4	Exercícios 54
4.5	Buscando	posts	de	uma	categoria 48
4.6	Exercícios 54
4.7	Finalizando	o	cadastro	de	um	post 51
4.8	Exercícios 54
4.9	Conclusão 55
5	Evoluindo	o	modelo	com	Code	First	Migrations
5.1	Gerenciando	as	mudanças	no	banco	de	dados 56
5.2	Evoluindo	o	modelo 59
5.3	Exercícios 63
5.4	Modificando	a	aplicação	para	refletir	as	mudanças	no	modelo 61
5.5	Exercícios 63
5.6	Saiba	mais:	aplicando	as	migrations	fora	do	ambiente	local 64
5.7	Conclusão 65
6	Validação
6.1	Mantendo	os	valores	preenchidos	em	caso	de	erro	de	validação 71
6.2	Exercícios 77
6.3	Validando	o	formulário	no	navegador 74
6.4	Exercícios 77
6.5	Conclusão 78
7	Facilidades	do	ASP.NET	MVC	para	melhorar	e	tornar	mais	seguro	o	código	das	views
7.1	Alterando	a	view	de	listagem	para	utilizar	os	Html	helpers 81
7.2	Exercícios 93
7.3	Alterando	os	formulários	de	inclusão	e	alteração 83
CaelumSumário
100
124
131
7.4	Mas	e	como	ficam	os	outros	integrantes	do	seu	time? 86
7.5	Exercícios 93
7.6	Criando	um	formulário	único	para	o	cadastro	de	posts 91
7.7	Exercícios 93
7.8	Para	saber	mais:	Usando	Ajax	para	criar	uma	funcionalidade	de	autocomplete 94
7.9	Exercícios	opcionais 97
7.10	Conclusão 99
8	Identidade	única	na	aplicação	com	Bootstrap	e	Layout	Pages
8.1	Definindo	a	identidade	da	aplicação	com	o	Razor 100
8.2	Exercícios 119
8.3	Aplicando	um	tema	ao	blog 108
8.4	Exercícios 119
8.5	Para	saber	mais:	Implementando	o	formulário	de	busca 115
8.6	Exercícios	opcionais 116
8.7	Separando	o	blog	em	áreas	Pública	e	Administrativa 116
8.8	Exercícios 119
8.9	Conclusão 123
9	Implantando	melhores	práticas	no	projeto	usando	padrões	e	frameworks
9.1	Melhorando	o	gerenciamento	da	conexão	com	injeção	de	dependências 124
9.2	Exercícios 130
9.3	Facilitando	a	Injeção	de	Dependências	com	o	ASP.NET	Core 127
9.4	Exercícios 130
10	Filtros	para	Autenticação	de	Usuários
10.1	Autenticando	usuários	com	a	session 131
10.2	Exercícios 147
10.3	Criando	o	Usuário	do	blog 134
10.4	Buscando	usuário	no	banco 135
10.5	A	comunicação	sem	estado	do	HTTP 137
10.6	Aplicando	autenticação	com	Cookies	e	Sessões 137
10.7	Exercícios 147
10.8	Autorização	com	filtros 140
10.9	Exercícios 147
10.10	Autor	no	post 143
10.11	Exercícios 147
10.12	Concluindo	o	cadastro	de	usuários 145
10.13	Exercícios 147
SumárioCaelum
150
165
182
187
194
201
10.14	Cadastro	de	posts	com	autor 146
10.15	Exercícios 147
10.16	Para	saber	mais:	Extension	method	para	trabalhar	com	a	ISession 147
11	Construindo	uma	web	API	com	ASP.NET	Core
11.1	Integração	com	Web	Services 150
11.2	Construindo	uma	Web	API	com	ASP.NET	Core 152
11.3	Exercícios 164
11.4	Criando	cadastro	de	um	post	pela	API 158
11.5	Exercícios 164
11.6	Finalizando	o	CRUD	com	a	atualização	e	a	remoção 162
11.7	Exercícios 164
12	Apêndice	-	Começando	com	testes	de	unidade
12.1	Menu	lateral	do	blog 165
12.2	Exercícios 180
12.3	Testando	a	sua	aplicação 173
12.4	Exercícios 180
12.5	O	que	aconteceu? 173
12.6	xUnit.net 177
12.7	Exercícios 180
13	Apêndice	-	Testando	o	que	realmente	é	necessário
13.1	Exercícios 186
14	Apêndice	-	Praticando	Test-Driven	Development	(TDD)
14.1	Desafio	matemático 187
14.2	Implementando	a	sequência	estranha 188
14.3	Exercícios 192
15	Apêndice	-	Requisições	elegantes	com	AJAX
15.1	A	funcionalidade	de	publicação	de	posts 194
15.2	Declarando	o	bloco	de	código	javascript 195
15.3	Ajax	com	jQuery 195
15.4	Alterando	o	conteúdo	da	tela	com	javascript 196
15.5	Executando	uma	função	com	a	resposta	do	servidor 197
15.6	Gerando	a	url	com	o	UrlHelper 198
15.7	Resposta	vazia	no	controller 198
15.8	Exercícios 199
16	Apêndice	-	Publicando	a	aplicação	nas	nuvens	com	o	App	Harbor
CaelumSumário
207
217
16.1	Primeiros	passos 201
16.2	SQL	Server	no	App	Harbor 202
16.3	Publicando	a	aplicação	no	App	Harbor 203
17	Apêndice	-	Implementando	segurança	no	blog	com	o	Identity
17.1	Aplicando	autenticação	e	autorização	com	o	Identity 207
17.2	Exercícios 216
17.3	Proibindo	acesso	anônimo	à	área	administrativa 213
17.4	Exercícios 216
17.5	Cadastro	de	posts	com	autor 215
17.6	Exercícios 216
17.7	Conclusão 216
18	Apêndice	-	Tópicos	Adicionais
18.1	Facilitando	o	uso	da	View	Model	com	o	AutoMapper 217
18.2	Exercício 220
18.3	Classificando	posts	com	tags 221
18.4	Exercícios 225
18.5	Incluindo	tags	no	cadastro	de	posts 224
18.6	Transformando	as	tags	com	o	AutoMapper 224
18.7	Exercícios 225
Versão:	22.7.28
SumárioCaelum
CAPÍTULO	1
Ao	final	deste	capítulo	você	vai:
conhecer	as	características	do	modelo	Requisição-Resposta	do	protocolo	HTTP
conhecer	a	estrutura	de	um	projeto	ASP.NET	Core	MVC
entender	o	sistema	de	roteamento	de	requisições	do	ASP.NET	Core	MVC
diferenciar	os	meios	de	enviar	informações	do	controlador	para	a	view
descobrir	como	enviar	parâmetros	HTTP	para	o	servidor
aprender	sobre	o	processo	de	Model	Binding	do	ASP.NET	Core	MVC
distinguir	os	métodos	de	requisição	HTTP	GET	e	POST
Existem	 muitos	 programadores	 que	 desenvolvem	 aplicativos	 web	 para	 o	 sistema	 operacional
Windows.	Muitos	deles	já	desenvolveram	utilizando	o	ASP.NET	WebForms	ou	então	o	ASP.NET	MVC,
todos	do	que	hoje	conhecemos	como	o	.NET	Framework.
O	WebForms,	 em	 sua	 época,	 revolucionou	 a	maneira	 de	 se	 programar	 para	Web.	 Programar	 com
WebForms	parecia	programar	com	Visual	Basic	ou	Delphi!	Ou	 seja,	os	 componentes	eram	arrastados
pro	 formulário	 e	 o	 programador	 podia	 colocar	 ações	 em	 eventos	 desses	 componentes,	 como,	 por
exemplo,	imprimir	uma	mensagem	na	tela	quando	houvesse	um	clique	no	botão.
Como	 muita	 gente	 na	 época	 vinha	 desse	 tipo	 de	 programação	 de	 aplicativos	 Desktop,	 aprender
WebForms	era	relativamente	fácil.	Sem	contar	a	sensação	de	produtividade,	já	que	os	componentes	que
existiam	faziam	as	mais	diversas	coisas,	como	exibir	dados	de	um	banco	de	dados	de	maneira	elegante,
separando	em	páginas.
Contudo,	códigos	e	aplicações	feitos	com	WebForms	ficaram	difíceis	de	manter.	O	motivo?	Apesar
de	ser	altamente	produtivo,	não	existe	separação	entre	o	código	que	lida	com	interface,	do	código	que
lida	com	regra	de	negócio,	do	código	que	lida	com	banco	de	dados	e	assim	por	diante...	Na	prática,	os
códigos	WebForms	são	"macarrônicos",	ou	seja,	são	grandes	e	fazem	muita	coisa	diferente.
No	 fim,	 o	 problema	 é	 que	 o	 WebForms	 não	 "obriga"	 o	 desenvolvedor	 a	 usar	 boas	 práticas	 de
programação.	Percebendo	isso,	a	Microsoft	resolveu	criar	oASP.NET	MVC!	O	MVC	é	um	padrão	de
desenvolvimento	muito	utilizado	no	mundo	web	e	conhecido	por	"forçar"	o	programador	a	separar	as
responsabilidades.	Ou	seja,	código	de	 interface	 fica	separado	do	código	de	 regra	de	negócio,	que	 fica
separado	do	código	de	banco	de	dados	e	assim	por	diante.	Isso	facilitava	a	manutenção	do	projeto	e	seu
INTRODUÇÃO	AO	ASP.NET	CORE
.
1	INTRODUÇÃO	AO	ASP.NET	CORE	 1
ciclo	de	vida	fica	maior!
Além	do	MVC,	dentro	da	plataforma	do	.NET	Framework	tínhamos	disponíveis	outras	bibliotecas
que	 aceleravam	o	processo	de	desenvolvimento	da	 aplicação.	Por	 exemplo,	o	Entity	Framework	para
bancos	de	dados	e	o	Identity	para	autenticação	e	autorização.	No	entanto,	o	 .NET	tinha	a	restrição	de
obrigar	quem	programava	a	ter	o	sistema	operacional	Windows.
Até	que	em	2014,	com	a	entrada	do	seu	novo	CEO	Satya	Nadella,	a	Microsoft	passou	a	investir	mais
em	projetos	open	source.	Inclusive,	decidindo	abrir	o	código	do	próprio	.NET.
Nesta	 época,	 um	 grupo	 de	 engenheiros	 da	Microsoft	 começou	 a	 trabalhar	 na	 próxima	 versão	 do
ASP.NET.	A	ideia	era	que	este	projeto	estaria	alinhado	desde	o	começo	com	a	nova	diretriz	da	empresa
de	ser	open	source.
Esta	nova	versão	veio	a	ser	o	que	conhecemos	hoje	como	o	 .NET	Core,	que	além	de	ter	o	código
aberto	 também	 é	 multiplataforma.	 Esta	 nova	 plataforma	 é	 um	 redesign	 da	 versão	 clássica	 do	 .NET
Framework,	mas	arquitetada	para	ser	mais	modular.
Esse	 curso	 abordará	 o	 framework	 ASP.NET	 Core	 MVC	 e	 seus	 recursos.	 Como	 aplicação,	 será
implementado	o	modelo	de	um	blog	cujo	tema	são	críticas	de	filmes,	livros	e	álbuns	de	música.	Para	ver
o	resultado	final	do	blog	que	será	implementado,	acesse	o	endereço:
http://blog1.apphb.com
Antes	de	abordar	os	detalhes	da	tecnologia	ASP.NET	Core	MVC,	é	preciso	conhecer	mais	a	fundo	o
modelo	de	comunicação	Web.
1.1	UM	BREVE	RESUMO	SOBRE	O	MODELO	DE	COMUNICAÇÃO	NA
WEB
.
2	 1.1	UM	BREVE	RESUMO	SOBRE	O	MODELO	DE	COMUNICAÇÃO	NA	WEB
http://blog1.apphb.com
Quando	 alguma	 página	 na	 internet	 é	 acessada,	 utiliza-se	 um	 navegador	 como	 Google	 Chrome,
Mozilla	 Firefox	 ou	 o	Microsoft	 Edge.	 Os	 dados	 são	 enviados	 através	 de	 uma	 rede	 gigante	 chamada
Internet.	O	navegador	 representa	nessa	comunicação	o	cliente	e	a	página	 requisitada	é	 fornecida	pelo
servidor.	 O	 cliente	 pede	 informações	 e	 o	 servidor	 responde.	 Esse	 modelo	 de	 comunicação,	 ou	 essa
arquitetura,	é	chamado	de	Cliente-Servidor,	em	inglês	Client-Server.
Em	 qualquer	 comunicação	 tem	 que	 existir	 algumas	 regras	 e	 vocabulário.	 Por	 exemplo,	 o	 que
acontece	quando	acessamos	alguma	página	que	não	existe	em	determinado	site?	O	servidor	não	saberá	a
resposta	e	precisará	indicar	para	o	navegador	que	não	conseguiu	carregar	os	dados.	Esse	comportamento
deve	 estar	 definido	 em	 algum	 lugar.	 É	 por	 isso	 que	 foi	 criado	 um	 idioma	 próprio,	 ou	 melhor,	 um
protocolo	próprio	que	possui	um	vocabulário	e	gramática	específica.	Este	protocolo	é	quem	define	as
regras	de	comunicação	entre	cliente	e	servidor!	O	principal	protocolo	usado	na	internet	é	o	HTTP.
Em	resumo,	HTTP	é	um	protocolo	que	define	as	regras	de	comunicação	entre	cliente	(em	geral	o
navegador)	e	servidor	na	internet.	Todo	desenvolvedor	de	aplicações	Web	deve	conhecer	como	funciona
esse	protocolo.
No	 mundo	 HTTP,	 a	 mensagem	 enviada	 pelo	 navegador	 para	 o	 servidor	 é	 chamada	 de	 HTTP
REQUEST.	Essa	mensagem	é	empacotada	e	enviada	pela	rede	como	texto.	Esse	pacote,	chamado	HTTP
REQUEST,	é	dividido	em	duas	partes,	cabeçalho	e	corpo.	O	principal	elemento	contido	no	cabeçalho
deste	pacote	é	o	endereço	para	onde	a	requisição	deverá	ser	enviada.	Você	já	conhece	esse	endereço.	É	o
mesmo	 que	 utiliza	 para	 acessar	 sites	 como	 o	 site	 da	Caelum	 (	http://www.caelum.com.br	)	 ou	 do
Alura	 (	http://www.alura.com.br	).	 Esse	 endereço	 identifica	 unicamente	 o	 servidor	 que	 irá	 tratar
aquela	requisição.
Repare	o	endereço	do	site	da	Caelum.	Veja	que	depois	do	nome	do	protocolo	vem	://	seguido	pelo
nome	do	site		www.caelum.com.br	.	No	vocabulário	de	um	desenvolvedor	o		www.caelum.com.br		é	o
domínio	(ou	domain).
Quando	usamos	o	endereço		http://www.alura.com.br	,	abrimos	uma	conexão	com	o	servidor	que
roda	em	algum	lugar	na	internet.	Um	servidor	é	como	uma	casa:	para	entrar	nela	existem	várias	portas
disponíveis.	Qual	porta	é	utilizada	para	o	protocolo	HTTP?
A	porta	 reservada	para	o	protocolo	HTTP	possui	código	padrão		80	,	 que	o	próprio	navegador	 se
encarrega	de	colocar.
O	protocolo	HTTP
HTTP	REQUEST
URLs	-	Endereços	da	Web
.
1.1	UM	BREVE	RESUMO	SOBRE	O	MODELO	DE	COMUNICAÇÃO	NA	WEB	 3
Observe	o	seguinte	endereço:		http://www.caelum.com.br/cursos-dotnet	.	Além	do	protocolo,
do	domínio	e	da	porta	(omitida,	porque	o	navegador	utilizará	a		80	,	padrão	para	o	HTTP),	ainda	existe
outra	informação.
O		cursos-dotnet		é	um	recurso	(resource)	do	site	que	gostaríamos	de	acessar,	no	caso	a	página	de
cursos	 .NET.	 Além	 dele,	 existem	 vários	 outros	 recursos	 na	 Caelum,	 como	 a	 página	 de	 contatos
(	/contato	),	ou	o	calendário	de	turmas	(	/calendario	).	O	importante	é	que	cada	recurso	possua	o	seu
nome	único.
Navegando	 em	 outros	 sites,	 percebemos	 que	 entre	 o	 domínio	 e	 o	 recurso	 podem	 vir	 outras
informações.	 Ou	 seja,	 para	 acessarmos	 um	 recurso,	 usamos	 um	 caminho	 intermediário.	 Há	 vários
exemplos	no	site	da	Alura	(	http://www.alura.com.br	)	que	usam	caminhos	para	chegar	ao	 recurso
concreto,	 como	 por	 exemplo		/discussion/mine		 ou	 	/user/45		 e	 navegando	 na	 Alura	 você	 pode
encontrar	outros.
Uma	 tarefa	 fundamental	 no	 cotidiano	 do	 desenvolvedor	Web	 é	 definir	 esses	 nomes	 e	 o	 que
deveria	 acontecer	 quando	 o	usuário	 for	 acessá-los.	Neste	 curso,	 vamos	 executar	muito	 essa	 tarefa
quando	estivermos	implementando	o	blog.
Em	resumo,	o	endereço	que	aparece	no	cabeçalho	de	uma	HTTP	REQUEST	é	formado	pelas	partes
protocolo://dominio:porta/caminho/recurso,	 e	a	esse	endereço	damos	o	nome	de	URL,	ou	Uniform
Resource	Locator.
O	tratamento	da	requisição	pelo	servidor	é	chamado	de	HTTP	RESPONSE.	Essa	resposta	também	é
um	pacote	 e	 é	 enviado	 no	 sentido	 servidor	 ->	 cliente.	Assim	 como	 a	HTTP	REQUEST,	 ela	 também
possui	cabeçalho	e	corpo.	Quando	a	resposta	chegar	no	destino,	ela	será	lida	e	interpretada.	Em	grande
parte	destas	respostas,	seu	corpo	é	formado	por	texto	em	linguagem	HTML.
CURSO	DE	HTTP	NA	ALURA	Para	aprofundar	seu	estudo	sobre	o	protocolo	HTTP,	faça	o	curso	de
HTTP	na	Alura!	https://cursos.alura.com.br/course/fundamentos-http
Uma	aplicação	MVC	faz	uso	do	modelo	Requisição-Resposta	do	protocolo	HTTP	para	 tratar	suas
lógicas	 de	 negócio.	 Para	 aprofundar	 nessa	 ideia,	 vamos	 criar	 um	 projeto	 ASP.NET	MVC	 no	 Visual
Studio	e	estudar	seus	detalhes.
HTTP	RESPONSE
1.2	 CRIANDO	 UM	 PROJETO	 ASP.NET	 CORE	 MVC	 COM	 O	 VISUAL
STUDIO	(WINDOWS	OU	MACOS)
.
4	 1.2	CRIANDO	UM	PROJETO	ASP.NET	CORE	MVC	COM	O	VISUAL	STUDIO	(WINDOWS	OU	MACOS)
https://cursos.alura.com.br/course/fundamentos-http
Caso	 você	 esteja	 trabalhando	 com	 o	 sistema	 operacional	Windows	 ou	MacOS,	 é	 comum	 usar	 o
editor	do	Visual	Studio	para	desenvolver	sua	aplicação	.NET	Core.	Quando	for	criar	um	novo	projeto
neste	editor,	basta	escolher	a	opção		ASP.NET	Core	Web	Application	,	utilizando	a	linguagem		Visual
C#	.	A	nossa	aplicação	se	chamará		Blog	:
Para	 que	 o	 projeto	 seja	 um	 MVC,	 na	 próxima	 janela	 precisamos	 escolher	 	Web	 Application
(Model-View-Controller)	:
.
1.2	CRIANDO	UM	PROJETO	ASP.NET	CORE	MVC	COM	O	VISUAL	STUDIO	(WINDOWS	OU	MACOS)	 5
Com	isso	criamos	a	nossa	primeira	aplicação	ASP.NET	Core	MVC	com	o	Visual	Studio.
Se	 você	 estiver	 trabalhando	 com	 outros	 sistemas	 operacionais	 de	 distribuição	 Linux,	 como	 o
Ubuntu,	 por	 enquanto	 ainda	 não	 temos	 o	 Visual	 Studio	 disponível.	 Nestes	 casos,	 é	 comum	 usarmos
como	editor	o	Visual	Studio	Code	(	https://code.visualstudio.com/	).
No	entanto,	o	VS	Code	é	apenas	um	editor,você	ainda	precisará	instalar	na	sua	máquina	a	SDK	do
.NET	 Core,	 que	 se	 encontra	 neste	 link	 	 https://www.microsoft.com/net/learn/get-
started/linux	.
Agora	 para	 criar	 o	Blog,	 primeiro	 precisamos	 de	 uma	 pasta	 onde	 ficará	 toda	 esta	 estrutura.	Você
pode	abrir	o	gerenciador	de	arquivos	e	criar	uma	pasta		Caelum		em	algum	lugar	do	seu	computador	de
sua	preferência.	Esta	pasta	servirá	como	a	solução/Solution	dos	projetos.
Só	que	para	tornar	esta	pasta		Caelum		em	uma	solução	e	criar	nosso	projeto	de		Blog		dentro	dela,
precisamos	trabalhar	com	o	 .NET	Core	command-line	 interface	(CLI).	Abra	o	seu	terminal	e	navegue
até	a	pasta		Caelum	.	Dentro	dela,	execute	o	comando:
dotnet	new	sln
Com	a	solução	criada,	vamos	gerar	um	projeto	no	padrão	MVC	usando	a	linguagem	C#.	Para	isso,
ainda	dentro	da	pasta		Caelum		faça	o	comando:
dotnet	new	mvc	--name	Blog	-lang	C#
Note	que	foi	criada	uma	pasta	Blog	com	a	estrutura	do	MVC.	Mas	ela	ainda	não	faz	parte	da	solução
de	fato,	você	ainda	precisará	rodar	o	comando:
dotnet	sln	Caelum.sln	add	Blog\Blog.csproj
Pronto,	como	toda	a	estrutura	foi	criada	podemos	dar	uma	olhada	no	projeto	MVC	gerado	pelo	.NET
Core	CLI.
COMANDOS	DO	.NET	CORE	CLI
Para	ver	todos	os	comandos	que	conseguimos	efetuar	com	o	.NET	Core	CLI,	você	pode	acessar
sua	documentação	em	https://docs.microsoft.com/en-us/dotnet/core/tools
1.3	 CRIANDO	 UM	 PROJETO	 ASP.NET	 CORE	 MVC	 EM	 OUTROS
AMBIENTES
1.4	A	ESTRUTURA	DE	UMA	APLICAÇÃO	ASP.NET	CORE	MVC
.
6	 1.3	CRIANDO	UM	PROJETO	ASP.NET	CORE	MVC	EM	OUTROS	AMBIENTES
https://docs.microsoft.com/en-us/dotnet/core/tools
Projetos	ASP.NET	Core	MVC	possuem	uma	estrutura	de	pastas	típica:
Dentre	essas	pastas	temos:
	Controllers		-	é	nela	que	são	guardadas	as	classes	responsáveis	por	tratar	as	requisições	HTTP
que	vem	do	navegador,	transformando-as	em	lógicas	referentes	a	alguma	funcionalidade	específica
da	aplicação.
	Views		 -	 pasta	 onde	 são	 colocados	 os	 arquivos	 que	 serão	 utilizados	 para	 renderizar	 a	 resposta
HTTP	para	o	usuário.	Será	necessário	algum	conhecimento	de	HTML	para	escrever	esses	arquivos.
	Models		-	pasta	onde	ficam	as	classes	que	representarão	o	modelo	da	aplicação,	ou	seja,	as	classes
que	representam	o	negócio	e	suas	regras.
Além	 dessas	 pastas,	 o	 projeto	web	 possui	 outras	 pastas	 e	 arquivos	 de	 configurações,	 com	 alguns
deles	escritos	no	formato	JSON	e	outras	feitas	em	classes.	Como	pode-se	observar,	além	da	linguagem
C#,	o	desenvolvedor	Web	precisará	ter	conhecimentos	de	HTML	para	entregar	seus	produtos	na	Web.
Vamos	desenvolver	a	página	inicial	da	aplicação	que,	quando	acessada	no	navegador,	mostrará	uma
lista	com	os	posts	do	blog.	Uma	página	inicial	é	acessada	quando	algum	usuário	digita	o	endereço	do
domínio	da	aplicação	na	barra	de	endereços	do	navegador,	sem	que	haja	necessidade	de	colocar	outros
recursos	no	endereço.
Por	padrão,	o	ASP.NET	Core	MVC	encaminha	a	requisição	de	página	inicial	para	uma	instância	da
1.5	PÁGINA	INICIAL	E	CONVENÇÕES	DO	ASP.NET	MVC
.
1.5	PÁGINA	INICIAL	E	CONVENÇÕES	DO	ASP.NET	MVC	 7
classe	chamada		HomeController	.	Todas	as	requisições	de	uma	aplicação	ASP.NET	Core	MVC	devem
ser	tratadas	em	classes	que	estendem	uma	classe	especial	do	framework	chamada		Controller	.	 Para
organizar	melhor	as	classes	dentro	do	projeto,	existe	uma	pasta	denominada		Controllers	,	onde	ficará
a	classe		HomeController	.
Todo	método	público	de	um	controller	é	chamado	action	pelo	ASP.NET	Core	MVC.	As	actions	são
responsáveis	 por	 tratar	 uma	 determinada	 requisição	 Web,	 e	 devem	 retornar	 uma	 instância	 de
	IActionResult	.	Para	atender	a	requisição	de	página	inicial,	o	ASP.NET	Core	MVC	cria	uma	instância
de	HomeController,	e	executa	o	método	chamado		Index	.
using	Microsoft.AspNetCore.Mvc;
namespace	Blog.Controllers
{
				public	class	HomeController	:	Controller
				{
								//GET:	Home
								public	IActionResult	Index()
								{
												return	View();
								}
				}
}
A	INTERFACE	IACTIONRESULT
A	interface		IActionResult		é	a	interface	base	para	todos	os	resultados	gerados	pelas	actions.
O	resultado	mais	comum	é	o	gerado	através	do	método		View()	,	que	cria	uma	instância	da	classe
	ViewResult	,	responsável	por	representar	uma	página	web	a	ser	renderizada	pelo	servidor.	Ela	é
filha	da	classe		ActionResult		que	implementa	a		IActionResult	.
Existem	diversas	outras	classes	que	implementam	a	IActionResult,	cada	uma	com	um	propósito
específico.	Por	exemplo	RedirectResult,	RedirectToActionResult,	RedirectToPageResult,	etc.
Mais	 detalhes	 sobre	 a	 interface	 IActionResult	 no	 MSDN:	 https://docs.microsoft.com/pt-
br/dotnet/api/microsoft.aspnetcore.mvc.iactionresult
Por	 enquanto	 essa	 action	 não	 precisa	 implementar	 nenhuma	 regra	 de	 negócio.	 Seu	 objetivo	 será
apenas	mostrar	 o	HTML	 devolvido	 para	 o	 navegador	 como	 resposta	 da	 requisição.	 Esse	HTML	 fica
armazenado	em	um	arquivo	dentro	da	pasta	Views	e	 representa	a	 resposta	da	 requisição	enviada	pelo
navegador.	Para	executar	o	código	da	view,	a	action	deve	devolver	o	resultado	de	um	método	herdado	da
classe		Controller		chamado		View	.
Isto	 significa	 dizer	 que	 será	 executada	 a	 camada	 de	 visualização	 da	 aplicação.	 O	 componente
responsável	 pela	 camada	 de	 visualização	 no	 ASP.NET	 Core	 MVC	 é	 a	 	 View	 Engine	 ,	 e	 a
.
8	 1.5	PÁGINA	INICIAL	E	CONVENÇÕES	DO	ASP.NET	MVC
https://docs.microsoft.com/pt-br/dotnet/api/microsoft.aspnetcore.mvc.iactionresult
implementação	utilizada	é	o	Razor.
O	arquivo	com	o	HTML	que	implementa	a	visualização	de	uma	determinada	action	precisa	cumprir
a	seguinte	convenção	do	ASP.NET	Core	MVC:
precisa	ser	colocado	dentro	da	pasta		Views	
deve	 ficar	 em	 uma	 pasta	 com	 o	 mesmo	 nome	 do	 controller.	 No	 caso,	 as	 views	 do
	HomeController		ficam	dentro	da	pasta		Views/Home	
quando	o	método	View	é	chamado	sem	argumentos,	o	arquivo	deve	ter	o	mesmo	nome	da	action
com	a	extensão		cshtml		(para	o	Razor).	Então,	no	código	da	action		Index		do		HomeController	,
o	 método	 	View	 	 sem	 argumentos	 criará	 uma	 instância	 de	 ActionResult	 a	 partir	 do	 arquivo
	Views/Home/Index.cshtml	.
Por	enquanto,	vamos	apenas	fazer	nossa	versão	de		Olá	mundo		em	nosso	arquivo		Index.cshtml	:
<html>
<head></head>
<body>
				<h2>Olá	mundo	com	ASP.NET	MVC</h2>
</body>
</html>
Por	enquanto,	o	arquivo	possui	apenas	HTML	.
Se	você	estiver	usando	o	Visual	Studio,	para	rodar	a	aplicação	basta	apertar	o	botão		F5	.	Caso	esteja
trabalhando	com	o	.NET	Core	CLI,	o	comando	de	terminal	é:
dotnet	run
Por	padrão,	o	servidor	subirá	no	endereço		http://localhost:5000	.
Como	acessar,	a	partir	do	navegador,	o	código	que	acabou	de	ser	criado?
Como	vimos,	 uma	 requisição	 do	 navegador	 é	 disparada	 para	 uma	URL.	Depois	 que	 o	 servidor	 é
encontrado,	 a	 aplicação	 é	 chamada	 para	 descobrir	 qual	 componente	 responderá	 pela	 parte
caminho/recurso	da	URL.	O	framework	ASP.NET	MVC,	no	qual	nossa	aplicação	se	baseia,	possui	um
módulo	responsável	por	mapear	cada	requisição	em	uma	action	disponível	na	aplicação.	Este	módulo	é
o	sistema	de	roteamento	do	ASP.NET	Core	MVC.
Quando	uma	aplicação	ASP.NET	Core	MVC	é	criada,	ela	já	está	configurada	para	usar	o	roteamento
configurado.	 Esta	 configuração	 é	 feita	 na	 classe	 presente	 no	 arquivo	 	Startup.cs	 ,	 no	 método
1.6	RODANDO	A	APLICAÇÃO
1.7	O	SISTEMA	DE	ROTEAMENTO	DO	ASP.NET	CORE	MVC
.
1.6	RODANDO	A	APLICAÇÃO	 9
	Configure	:
public	class	Startup
{
				//...
				public	void	Configure(IApplicationBuilder	app,	IHostingEnvironment	env)
				{
								//...
								app.UseMvc(routes	=>
												{
																routes.MapRoute(
																				name:	"default",
																				template:	"{controller=Home}/{action=Index}/{id?}");
												}
								);
				}
}
O	método		MapRoute		 adiciona	uma	única	 rota	 chamada	default	 à	 tabela	 de	 rotas.	A	 rota	Default
mapeia	o	primeiro	segmento	de	uma	URL	para	o	nome	de	um	controlador,	o	segundo	argumento	de	uma
URL	para	uma	actiondo	controlador,	e	o	terceiro	argumento	para	um	parâmetro	chamado	id.
Imagine	que	a	seguinte	URL	foi	informada	na	barra	de	endereços	do	navegador:
	http://<dominio:porta>/Home/Index/3	
A	rota	Default	mapeia	o	recurso		Home/Index/3		para	os	seguintes	componentes:
controller	=	Home
action	=	Index
id	=	3
Por	 exemplo,	 quando	 uma	 requisição	 com	 a	 URL	 	http://<dominio:porta>/Home/Index/3		 é
feita,	o	seguinte	código	é	executado:
HomeController.Index(3)
Além	disso,	a	rota	Default	inclui	valores	padrão	para	os	três	segmentos	(controller,	action	e	id).	Se
um	controller	não	for	especificado	na	URL,	então	o	parâmetro	será	o	do	valor	padrão		Home	.	 Se	uma
action	 não	 for	 especificada,	 então	 o	 parâmetro	 da	 action	 será	 o	 do	 valor	 padrão		Index	.	 Da	mesma
forma,	se	um	id	não	for	especificado,	o	parâmetro		id		será	o	de	uma	string	vazia.
Ou	 seja,	 os	 três	 endereços	 abaixo	 serão	 mapeados	 para	 o	 mesmo	 código
	HomeController.Index()	:
	http://<dominio:porta>	
	http://<dominio:porta>/Home	
	http://<dominio:porta>/Home/Index	
.
10	 1.7	O	SISTEMA	DE	ROTEAMENTO	DO	ASP.NET	CORE	MVC
Recapitulando,	 o	 modelo	 Requisição-Resposta	 do	 protocolo	 HTTP	 é	 tratado	 por	 uma	 aplicação
ASP.NET	Core	MVC	através	do	seguinte	fluxo:
1.	 O	cliente	envia	um	pacote	HTTP	REQUEST	para	a	web
2.	 Servidor	e	aplicação	são	encontrados	através	da	primeira	parte	da	URL	da	requisição,	composta	pelo
protocolo	e	domínio
3.	 A	 segunda	 parte	 da	 URL,	 composta	 pelo	 recurso	 e	 opcionalmente	 pelo	 caminho,	 é	 tratada	 pelo
sistema	de	roteamento,	que	é	responsável	por	encontrar	uma	action	disponível	em	um	controller
4.	 Após	ser	encontrado,	uma	instância	do	controller	é	criada	e,	em	seguida,	o	método	correspondente	à
action	é	executado
5.	 A	action	retorna	uma	instância	de	IActionResult,	que	será	renderizada	pelo	motor	de	visualização	e
enviada	como	um	pacote	HTTP	RESPONSE	de	volta	para	o	cliente
1.	 A	primeira	coisa	que	 faremos	é	escolher	uma	pasta	onde	 ficarão	 todos	os	nossos	projetos.	Abra	o
gerenciador	de	arquivos	do	seu	computador	e	crie	uma	pasta	chamada		Caelum		em	algum	lugar	de
preferência	na	sua	máquina.
2.	 Agora	precisamos	tornar	esta	pasta	uma	solução.	Para	isso,	abra	o	terminal	do	computador	e	através
do	comando		cd		navegue	pelas	pastas	até	entrar	no	diretório		Caelum		que	você	criou.	Dentro	dele,
execute	o	comando:
dotnet	new	sln
3.	 Ainda	dentro	desta	pasta		Caelum	,	precisamos	criar	um	novo	projeto	do	tipo		ASP.NET	Core	MVC	
chamado		Blog		utilizando	a	 linguagem		Visual	C#	.	E	depois	 adicioná-lo	na	 solução		Caelum	.
Para	isso	execute	os	comandos:
	dotnet	new	mvc	--name	Blog	-lang	C#
	dotnet	sln	Caelum.sln	add	Blog\Blog.csproj
4.	 Se	 notar,	 dentro	 do	 projeto	 já	 foram	 criadas	 algumas	 coisas	 por	 conta	 dos	 seus	 templates.	 Como
queremos	 começar	 nosso	 projeto	 do	 zero,	 vamos	 apagar	 estas	 coisas	 que	 o	 editor	 criou
automaticamente	para	a	gente.	Mas	não	se	preocupe,	vamos	refazer	muitas	dessas	coisas	mais	para
frente	no	curso	quando	elas	fizerem	sentido	no	projeto.	Então	apague	todos	os	arquivos	e	diretórios
dentro	 das	 pastas	 	Controllers	,	 	Models		 e	 	Views	,	 mas	 não	 apague	 estas	 3	 pastas	 em	 si.
Precisaremos	delas	para	o	nosso	sistema	MVC.
5.	 Agora	que	o	projeto	está	limpo,	vamos	adicionar	o	controller	inicial	da	aplicação.	Dentro	da	pasta
	Controllers		 do	 projeto,	 crie	 um	 arquivo	 	HomeController.cs	.	 Esta	 classe	 deverá	 herdar	 de
	Controller		e	ter	método	de	action		Index	,	que	servirá	para	mostrar	a	página	inicial	da	aplicação.
	using	Microsoft.AspNetCore.Mvc;
	namespace	Blog.Controllers
	{
1.8	EXERCÍCIOS
.
1.7	O	SISTEMA	DE	ROTEAMENTO	DO	ASP.NET	CORE	MVC	 11
					public	class	HomeController	:	Controller
					{			
									public	IActionResult	Index()
									{
													return	View();
									}
					}
	}
6.	 Para	completarmos	a	página	 inicial,	dentro	da	pasta		Views		 crie	 uma	pasta	 chamada		Home	.	Em
seguida,	 crie	 um	 novo	 arquivo	 chamado	 	Index.cshtml		 dentro	 da	 pasta	 	Views/Home/	.	 Neste
arquivo		Index.cshtml	,	coloque	o	código	HTML:
	<html>
	<head></head>
	<body>
					<h2>Olá	mundo	com	ASP.NET	Core	MVC</h2>
	</body>
	</html>
7.	 Agora	 vamos	 testar	 a	 aplicação.	 No	 terminal,	 para	 subir	 o	 servidor	 basta	 entrar	 no	 diretório	 do
projeto	e	dar	o	comando		run	:
	cd	Blog
	dotnet	run
8.	 Abra	 o	 navegador	 e	 acesse	 a	 página	 	http://localhost:5000/Home/Index	.	 Verifique	 que	 ela
possui	o	texto	de	boas	vindas.
9.	 Ainda	no	browser,	retire	do	final	do	texto	o		/Index		da	URL	e	aperte	Enter.	Verifique	que	a	mesma
página	será	exibida.
10.	 Retire	do	fim	do	texto		/Home		da	URL	e	aperte	Enter.
11.	 Para	interromper	o	servidor,	no	terminal	aperte	o	comando		Ctrl+C	.	Agora	você	já	está	pronto	para
listar	os	posts	na	próxima	seção!
Agora	que	já	temos	uma	home	page	do	sistema,	vamos	começar	a	trabalhar	com	todas	as	telas	que
vão	 gerenciar	 os	 posts	 do	 blog.	 Como	 ainda	 não	 conseguimos	 saber	 quais	 posts	 foram	 cadastrados,
vamos	começar	criando	uma	tela	em	que	veremos	artigos	escritos	no	site.	Para	isso,	podemos	criar	uma
tabela	HTML	com	um	post	 por	 linha.	O	exemplo	 abaixo	mostra	o	HTML	de	uma	 tabela	 com	quatro
posts:
<table>
				<thead>
								<tr>
												<th>Título</th>
												<th>Resumo</th>
												<th>Categoria</th>
								</tr>
				</thead>
				<tbody>
1.9	CRIANDO	TELA	DE	LISTAGEM	DE	POSTS
.
12	 1.9	CRIANDO	TELA	DE	LISTAGEM	DE	POSTS
								<tr>
												<td>Harry	Potter	1</td>
												<td>Pedra	Filosofal</td>
												<td>Filme,	Livro</td>
								</tr>
								<tr>
												<td>Cassino	Royale</td>
												<td>007</td>
												<td>Filme</td>
								</tr>
								<tr>
												<td>Monge	e	o	Executivo</td>
												<td>Romance	sobre	Liderança</td>
												<td>Livro</td>
								</tr>
								<tr>
												<td>New	York,	New	York</td>
												<td>Sucesso	de	Frank	Sinatra</td>
												<td>Música</td>
								</tr>
				</tbody>
</table>
Quando	a	aplicação	executar	este	HTML,	o	visitante	veria	uma	 tabela	com	4	posts	 relacionados	a
filmes,	livros	e	músicas.
Contudo,	o	propósito	de	um	blog	é	ser	algo	dinâmico,	vivo,	com	atualizações	constantes,	e	do	jeito
que	 foi	 implementado,	 ele	 não	 vai	 atender	 esse	 objetivo.	 Sempre	 que	 a	 página	 for	 exibida,	 serão
mostrados	 os	mesmos	 quatro	 posts.	 Extremamente	 chato!	 O	 blog	 dificilmente	 receberá	 novas	 visitas
seguindo	esse	comportamento.
Para	que	a	 lista	de	posts	seja	dinâmica,	a	 tabela	HTML	não	deve	 ter	 linhas	com	valores	fixos.	As
linhas	 devem	 ser	 geradas	 conforme	 a	 quantidade	 de	 posts	 do	 blog.	 Como	 gerar	 automaticamente	 as
linhas	sem	conhecimento	prévio	do	total?
Neste	 caso,	 é	 necessário	 gerar	 uma	 linha	 (	tr	)	para	 cada	 post	 do	 blog.	 Para	 implementar	 esse
comportamento	precisamos	fazer	um	loop	onde,	a	cada	rodada,	será	criada	a	linha	desejada.	Esse	loop
deverá	ser	executado	no	servidor	antes	da	resposta	ser	enviada	para	o	cliente.
Mas	como	diferenciar,	no	próprio	arquivo		cshtml	,	o	código	que	é	executado	no	servidor	(no	caso,
escrito	em	C#)	do	código	que	vai	para	o	cliente	num	pacote	HTTP	RESPONSE	(no	caso,	HTML)?
A	 maneira	 que	 o	 Razor	 tem	 para	 diferenciar	 um	 código	 HTML	 de	 um	 código	 C#	 é	 através	 do
símbolo	arroba	(	@	).	Neste	caso	o	código	que	estiver	após	o		@		será	executado	no	servidor.
Uma	 alternativa	 de	 código	 que	 podemos	 usar	 para	 executar	 o	 loop	 é	 o	 	foreach	.	 Coloca-se	 o
	foreach		logo	após	o		@	.	Assim:
1.10	 GERAÇÃO	 DINÂMICA	 DA	 TABELA	 A	 PARTIR	 DOS	 POSTS	 DO
BLOG
.
1.10	GERAÇÃO	DINÂMICA	DA	TABELA	A	PARTIR	DOS	POSTS	DO	BLOG	 13
@foreach	(var	p	in	??????)
{
				<tr>
								<td>	???	</td>
								<td>	???	</td>
								<td>	???	</td>
				</tr>
}
De	qual	lista	serão	extraídos	os	posts	para	alimentar	o	foreach?
Anteriormente	 aprendemos	 que,	 no	 fluxo	 de	 tratamento	 de	 uma	 requisição	 pelo	 ASP.NET	 Core
MVC,	o	códigocontido	numa	action	de	um	controller	é	executado	antes	do	processo	de	renderização	da
view.	Então	vamos	criar	um	novo		PostController		em	que	faremos	estas	lógicas	de	gerenciamento	do
post.	Neste	controller	podemos	adicionar	uma	action	de		Index		 que	 será	 responsável	 por	 fornecer	 a
lista	para	nossa	view	que	ficará	em	.
namespace	Blog.Controllers
{
				public	class	PostController	:	Controller
				{
								public	IActionResult	Index()
								{
												var	lista	=	??????;
												return	View();
								}
				}
}
O	problema	é	que	o	escopo	da	variável		lista		 existe	apenas	dentro	da	action.	Para	que	o	Razor
consiga	enxergar	essa	variável,	ela	precisa	existir	e	estar	visível	no	escopo	de	execução	da	renderização
da	view.	Para	isso,	faremos	uso	de	uma	propriedade	das	classes		Controller		e		ViewResult	.
Já	vimos	que	o	método	View	cria	uma	 instância	de	ViewResult,	classe	 filha	de	ActionResult,	que
será	 usada	 para	 o	 processo	 de	 geração	 do	HTML.	A	 classe	ViewResult	 possui	 algumas	 propriedades
cujo	objetivo	é	transportar	informação	entre	o	controlador	e	a	view.	Uma	delas	é	a		ViewBag	.	Ela	será
utilizada	para	transportar	a	variável		lista		do	controlador	até	a	view.
Então	o	código	do	controlador	é	alterado	para:
public	IActionResult	Index()
{
				ViewBag.Posts	=	??????;
				return	View();
}
.
14	 1.10	GERAÇÃO	DINÂMICA	DA	TABELA	A	PARTIR	DOS	POSTS	DO	BLOG
COMO	ASSIM
Peraí,	existe	uma	propriedade	chamada	Posts	dentro	de	ViewBag?	A	resposta	é	não	e	sim.	Em
tempo	de	compilação,	ou	seja,	no	momento	em	que	a	propriedade	ViewBag	foi	compilada,	ela	não
tinha	uma	declaração	para	Posts.	Contudo,	no	momento	da	execução	da	linha		ViewBag.Posts	,	ela
assume	a	propriedade	 como	 sua.	Esse	 comportamento	dinâmico	é	possível	porque	 a	propriedade
	 ViewBag	 	 é	 um	 objeto	 dinâmico,	 um	 recurso	 da	 linguagem	 .NET	 para	 permitir	 que	 o
desenvolvedor	crie	objetos	para	 representar	estruturas	dinâmicas,	como	por	exemplo	a	hierarquia
de	objetos	(DOM)	em	uma	página	HTML.
Como	criamos	o	nosso		PostController		 e	 definimos	 a	action	 com	a	 lista,	 agora	podemos	 criar
nosso		cshtml		 com	 o	 	foreach		 no	 arquivo		Views/Post/Index.cshtml	.	 E	 para	 chamar	 a	 nossa
	ViewBag		para	recuperar	a	lista	de	posts	basta	escrever:
@foreach	(var	p	in	ViewBag.Posts)
{
				<tr>
								<td>	???	</td>
								<td>	???	</td>
								<td>	???	</td>
				</tr>
}
Agora	que	a	action		Index		fornece	a	lista	de	posts	em	ViewBag.Posts,	precisamos	entender	como
essa	lista	será	populada.
public	IActionResult	Index()
{
				ViewBag.Posts	=	??????;
				return	View();
}
Essa	 lista	 será	populada	a	partir	dos	posts	do	blog.	Porém,	ainda	não	existe	em	nossa	aplicação	o
conceito	de	post.	Será	necessário	criar	uma	classe	que	representará	esse	conceito.	Essa	classe	fará	parte
do	nosso	modelo.	Sendo	assim	 será	 criada	dentro	da	pasta		Models	.	 Inicialmente	 essa	 classe	 terá	 as
propriedades		Titulo	,		Resumo		e		Categoria	.
namespace	Blog.Models
{
				public	class	Post
				{
								public	string	Titulo	{	get;	set;	}
								public	string	Resumo	{	get;	set;	}
								public	string	Categoria	{	get;	set;	}
				}
}
E	assim	a	 lista	poderá	ser	criada	a	partir	de	uma	quantidade	arbitrária	de	posts.	O	código	final	do
.
1.10	GERAÇÃO	DINÂMICA	DA	TABELA	A	PARTIR	DOS	POSTS	DO	BLOG	 15
controller	fica	assim:
namespace	Blog.Controllers
{
				public	class	PostController	:	Controller
				{
								public	IActionResult	Index()
								{
												var	listaDePosts	=	new	List<Post>()
												{
																new	Post()	{	Titulo	=	"Harry	Potter	1",	Resumo	=	"Pedra	Filosofal",	Categoria	=	"Film
e,	Livro"	},
																new	Post()	{	Titulo	=	"Cassino	Royale",	Resumo	=	"007",	Categoria	=	"Filme"	},
																new	Post()	{	Titulo	=	"Monge	e	o	Executivo",	Resumo	=	"Romance	sobre	Liderança",	Cate
goria	=	"Livro"	},
																new	Post()	{	Titulo	=	"New	York,	New	York",	Resumo	=	"Sucesso	de	Frank	Sinatra",	Cate
goria	=	"Música"	}
												};
												ViewBag.Posts	=	listaDePosts;
												return	View();
								}
				}
}
Falta	ainda	completar	a	view	para	mostrar	as	propriedades	dos	posts:	Título,	Resumo	e	Categoria.	O
foreach	 define	 uma	 variável	 para	 guardar	 o	 objeto	 que	 representa	 o	 item	 da	 lista	 na	 rodada	 atual.
Usaremos	 essa	 variável	 para	mostrar	 as	 informações	 de	 cada	 post.	 Como	 é	 um	 código	 que	 deve	 ser
avaliado	no	servidor,	o	prefixamos	com	o	símbolo	arroba	(	@	).	A	tabela	da	view	deve	ficar	parecida	com
a	seguinte:
<table>
				<thead>
								<tr>
												<th>Título</th>
												<th>Resumo</th>
												<th>Categoria</th>
								</tr>
				</thead>
				<tbody>
								@foreach	(var	p	in	ViewBag.Posts)
								{
												<tr>
																<td>@p.Titulo</td>
																<td>@p.Resumo</td>
																<td>@p.Categoria</td>
												</tr>
								}
				</tbody>
</table>
1.	 Crie	uma	nova	classe		Post		na	pasta	Models	para	representar	um	post.	Assim,	seu	namespace	será
	Blog.Models	.
2.	 Dentro	da	classe,	crie	as	propriedades	de	um	post,		Titulo	,		Resumo		e		Categoria	,	todas	do	tipo
1.11	EXERCÍCIOS
.
16	 1.10	GERAÇÃO	DINÂMICA	DA	TABELA	A	PARTIR	DOS	POSTS	DO	BLOG
string.
3.	 Crie	um	novo	controller	chamado		PostController	.	Em	sua	action		Index	,	gere	uma	lista	de	posts
e	a	transporte	para	a	view	através	da	propriedade		ViewBag	.
4.	 Crie	 a	 view	 	 Views/Post/Index.cshtml	 	 que	 representará	 a	 tabela	 de	 posts	 enviados	 pelo
controller.
5.	 Na	sua		View	,	use	um	foreach	na	lista	de		ViewBag.Posts		para	criar	uma	tabela	de	posts.
Na	seção	anterior,	utilizamos	a	propriedade		ViewBag		para	transportar	a	lista	de	posts	do	controller
para	a	view.	Existem	outras	maneiras	de	fazer	isso,	e	uma	delas	é	injetando	a	variável	lista	diretamente
no	método		View()		da	action		Index	.
public	ActionResult	Index()
{
				//código	anterior...
				return	View(listaDePosts);
}
Veja	o	nome	do	argumento	na	assinatura	desta	sobrecarga	do	método	View	na	classe		Controller	:
public	virtual	ViewResult	View(object	model);
Esta	sobrecarga	do	método	View	cria	um	objeto	do	tipo		ViewResult		usando	um	modelo	que	será
renderizado	 na	 resposta	 representada	 pela	 view.	 No	 nosso	 caso,	 o	 modelo	 na	 qual	 a	 view
	Views/Home/Index.cshtml		 se	 baseia	 é	 uma	 lista	 de	posts.	A	vantagem	de	usar	 essa	 alternativa	 em
relação	à	ViewBag	é	que	temos	o	poder	do	IntelliSense	a	nossa	disposição	ao	gerarmos	o	HTML.	Para
isso,	será	necessário	declarar	qual	 tipo	do	modelo	será	utilizado	na	view,	através	da	diretiva		@model	
(em	letras	minúsculas).
1.12	OUTRA	MANEIRA	DE	ENVIAR	INFORMAÇÕES	PARA	A	VIEW
.
1.12	OUTRA	MANEIRA	DE	ENVIAR	INFORMAÇÕES	PARA	A	VIEW	 17
No	nosso	exemplo	(Index.cshtml),	vamos	declarar	que	a	view	usa	uma	lista	de	posts:
@model	IList<Blog.Models.Post>
E	o	foreach	precisará	ser	alterado	para	substituir	a	chamada	à	ViewBag	pela	chamada	do	modelo.
Para	fazer	isso	escrevemos:
@foreach	(var	p	in	Model)
{
				<tr>
								<td>@p.Titulo</td>
								<td>@p.Resumo</td>
								<td>@p.Categoria</td>
				</tr>
}
A	propriedade		Model		representa	uma	instância	do	tipo	definido	na	diretiva		@model		e	conterá	os
valores	enviados	através	do	método		View	.
Quando	escrevemos	o	ponto	depois	da	variável		p	,	o	recurso	de	IntelliSense	do	Visual	Studio	nos
ajuda	a	preencher	as	propriedades	corretamente.
Quando	uma	view	usa	essa	abordagem,	isto	é,	a	de	declarar	qual	o	tipo	de	modelo	será	usado	para
renderizar	as	informações,	dizemos	que	estamos	usando	views	fortemente	tipadas.	Essa	é	a	abordagem
recomendada	nas	aplicações	ASP.NET	Core	MVC.
Existem	outras	vantagens	de	utilizar	as	views	fortemente	tipadas.	Elas	serão	vistas	mais	à	frente	no
curso,	quando	formos	simplificar	o	código	das	views.
Concluindo,	para	gerar	a	resposta	de	uma	requisição	HTTP,	o	ASP.NET	Core	MVC	usa	uma	página
modelo,	chamada	view,	composta	de	tags	HTML	e	regiões	C#	executáveis	(definidas	por		@	).	Os	dados
usados	 nestas	 regiões	 são	 transportadospara	 a	 view	 através	 de	 duas	 alternativas:	 ViewBag	 ou	 view
fortemente	tipada.
Podemos	 resumir	 a	 ideia	 do	 parágrafo	 anterior	 na	 seguinte	 fórmula:	 TEMPLATE	 +	 DADOS	 =
RESPOSTA	HTTP
1.	 Na	 action	 	 Index	 	 do	 	 PostController	 ,	 remova	 a	 chamada	 para	 	 ViewBag	 	 e	 coloque
	listaDePosts		como	argumento	do	método		View	.
2.	 Inclua	 na	 primeira	 linha	 da	 view	 	 Views/Post/Index.cshtml	 	 o	 código	 	 @model
IList<Blog.Models.Post>	,	para	indicar	que	esta	view	é	fortemente	tipada.
3.	 Ainda	na	View,	troque	o		ViewBag.Posts		por		Model		no		foreach	.
4.	 Teste	a	aplicação.	Tudo	deverá	estar	funcionando	normalmente.
1.13	EXERCÍCIOS
.
18	 1.12	OUTRA	MANEIRA	DE	ENVIAR	INFORMAÇÕES	PARA	A	VIEW
Apesar	 de	 montarmos	 dinamicamente	 a	 view	 com	 o	 loop	 	foreach	,	 o	 blog	 ainda	 está	 muito
paradão.	 A	 aplicação	 precisa	 fornecer	 uma	 maneira	 dos	 autores	 do	 blog	 cadastrarem	 seus	 textos
diretamente	 no	 site.	 Com	 esse	 objetivo	 em	 vista,	 essa	 seção	 irá	 implementar	 a	 funcionalidade	 de
inclusão	de	um	post.
Para	realizar	o	cadastro,	é	necessário	um	formulário	que	capture	os	dados	do	novo	post.
O	código	do	formulário	HTML	está	listado	abaixo:
<form	action="/Post/Adiciona">
			<label>
								Título:	<input	name="titulo"	/>
				</label>
				<label>
								Resumo:	<input	name="resumo"	/>
				</label>
				<label>
								Categoria:	<input	name="categoria"/>
				</label>
				<button	type="submit">Cadastrar</button>
</form>
Esse	 formulário	 faz	 parte	 da	 camada	 de	 visualização	 do	 ASP.NET	 Core	 MVC.	 Para	 chegar	 na
camada	de	visualização,	precisamos	de	uma	action.	Logo,	é	preciso	criar	um	método	no	controller	que
redireciona	 para	 o	 formulário.	 Para	 isso	 será	 adicionado	 um	 método	 chamado	 	Novo	 	 dentro	 do
	PostController	.
public	IActionResult	Novo()
{
				return	View();
}
Desta	maneira	 é	 criada	 uma	 rota	 que	 atende	 a	 requisição	 cujo	 recurso	 da	URL	 é	 	/Post/Novo	.
Quando	esse	endereço	for	disparado	no	navegador,	o	formulário	será	exibido	como	resposta.	Depois	que
o	usuário	preencher	os	dados,	ele	vai	submeter	o	form.	O	que	vai	acontecer	quando	o	botão	Cadastrar
for	clicado?
A	tag		form		possui	um	atributo	chamado		action	.	Esse	atributo	montará	a	URL	da	requisição	que
submeterá	 o	 formulário	 ao	 servidor	 (cujo	 recurso	 no	 caso	 é	 	 /Post/Adiciona	 ).	 Portanto,	 será
necessária	 uma	 nova	 action	 em	 	PostController	 	 para	 atender	 tal	 requisição.	 Essa	 action	 será
responsável	por	incluir	o	post	na	lista.
public	IActionResult	Adiciona()
{
				return	View();
}
Mas	como	obter	os	valores	do	post	na	action?	Observe	que	no	formulário	HTML	existem	três	tags
1.14	INCLUINDO	UM	POST	ATRAVÉS	DE	UM	FORMULÁRIO	HTML
.
1.14	INCLUINDO	UM	POST	ATRAVÉS	DE	UM	FORMULÁRIO	HTML	 19
	input		com	um	atributo		name	,	justamente	com	o	nome	das	propriedades	de	um	post,	a	saber:	titulo,
resumo	e	categoria.
A	aplicação	precisará	transportar	o	valor	que	foi	digitado	no	campo	do	formulário	para	aquele	ponto
do	código.	Como	isso	será	feito?	Através	do	próprio	HTTP.	O	protocolo	prevê	que	o	valor	de	campos	do
tipo		input		 sejam	colocados	em	entradas	do	 tipo	chave/valor	dentro	da	 requisição.	Desta	maneira,	 a
requisição	que	chega	no	servidor	 já	possui	 tais	parâmetros.	A	chave	de	cada	parâmetro	é	determinada
pelo	atributo		name		do	campo	input.
Para	transportar	os	parâmetros	de	uma	requisição	para	determinada	action,	o	ASP.NET	Core	MVC
utiliza	um	processo	chamado	Model	Binding.	Em	determinado	momento	no	 fluxo	de	atendimento	da
requisição,	 o	Model	 Binding	 coleta	 dados	 da	 requisição	 e	 os	 injeta	 diretamente	 na	 action	 como	 um
argumento	 de	 entrada	 no	 método	 que	 representa	 a	 action.	 No	 exemplo	 do	 formulário	 acima,	 será
necessário	 alterar	 a	 assinatura	do	método	Adiciona	para	 incluir	parâmetros	de	 entrada	com	o	mesmo
nome	que	os	atributos	name	do	input.
public	IActionResult	Adiciona(string	titulo,	string	resumo,	string	categoria)
{
				//...resto	do	código	aqui...
}
Mas	a	definição	de	um	post	possui	justamente	as	propriedades		Titulo	,		Resumo		e		Categoria	.
Neste	 caso,	 o	 Model	 Binding	 consegue	 injetar	 os	 valores	 dos	 parâmetros	 da	 requisição	 diretamente
numa	instância	de	Post.	Basta	que	a	assinatura	da	action	informe	essa	necessidade.
public	IActionResult	Adiciona(Post	post)
{
				//...resto	do	código	aqui...
}
Por	 fim,	basta	 incluirmos	o	post	 informado	pelo	usuário	no	 formulário	na	 lista	de	posts.	Porém	a
variável		lista	,	que	contém	os	posts,	está	definida	na	action		Index		e	não	está	acessível	no	método
Adiciona.
Para	 resolver	 essa	 questão,	 tornamos	 a	 lista	 um	 campo	 privado	 da	 classe	 	PostController		 e	 a
populamos	com	os	4	posts	originais	no	seu	construtor.
				public	class	PostController	:	Controller
				{
								private	IList<Post>	lista;
								public	PostController()
								{
												this.lista	=	new	List<Post>	()	{
																new	Post	()	{	Titulo	=	"Harry	Potter	1",	Resumo	=	"Pedra	Filosofal",	Categoria	=	"Fil
me,	Livro"	},
																new	Post	()	{	Titulo	=	"Cassino	Royale",	Resumo	=	"007",	Categoria	=	"Filme"	},
																new	Post	()	{	Titulo	=	"Monge	e	o	Executivo",	Resumo	=	"Romance	sobre	Liderança",	Cat
egoria	=	"Livro"	},
																new	Post	()	{	Titulo	=	"New	York,	New	York",	Resumo	=	"Sucesso	de	Frank	Sinatra",	Cat
.
20	 1.14	INCLUINDO	UM	POST	ATRAVÉS	DE	UM	FORMULÁRIO	HTML
egoria	=	"Música"	}
												};
								}
								//	resto	das	actions	aqui...
				}
Assim,	a	lista	fica	acessível	na	action	Adiciona.
public	IActionResult	Adiciona(Post	p)
{
				lista.Add(p);
				return	View();
}
A	 resposta	 da	 requisição	 	Post/Adiciona		 pode	 ser	 a	 própria	 listagem	 de	 posts	 indicada	 pelo
arquivo	 	Views/Post/Index.cshtml	 .	 Já	 sabemos	 que	 quando	 o	 método	 View()	 é	 chamado	 sem
argumentos,	 será	 procurado	 um	 arquivo	 de	 mesmo	 nome	 que	 a	 action.	 Nossa	 necessidade	 agora	 é
diferente:	queremos	que	um	arquivo	já	usado	em	outra	action	seja	reutilizado	numa	segunda	action.	Para
essa	necessidade,	o	ASP.NET	MVC	previu	uma	sobrecarga	do	método	View()	que	recebe	um	argumento
de	entrada	com	o	nome	da	view	desejada.	No	nosso	caso,	Index.	Assim	modificamos	nosso	código	para
usar	a	sobrecarga	deste	método:
public	IActionResult	Adiciona(Post	p)
{
				lista.Add(p);
				return	View("Index");
}
Quando	 executamos	 a	 aplicação	 e	 cadastramos	 um	 post,	 acontece	 um	 erro	 do	 tipo
	 System.NullReferenceException	 .	 Isso	 se	 deve	 ao	 fato	 de	 que	 a	 propriedade	 Model,	 que	 é
referenciada	no	 foreach	da	view,	não	está	 instanciada!	Mas	é	claro,	 esquecemos	de	 transportar	a	 lista
para	a	view!	Vamos	fazer	isso	então:
public	IActionResult	Adiciona(Post	p)
{
				lista.Add(p);
				return	View("Index",	lista);
}
1.	 Crie	uma	nova	action	chamada		Novo		no		PostController	.	Coloque	o	código	abaixo:
	public	IActionResult	Novo()
	{
					return	View();
	}
2.	 Crie	uma	view	a	partir	da	action		Novo		e	coloque	o	formulário	HTML	dentro	da	tag		body	
	<form	action="/Post/Adiciona">
					<label>
									Título:	<input	name="titulo"	/>
1.15	EXERCÍCIOS
.
1.14	INCLUINDO	UM	POST	ATRAVÉS	DE	UM	FORMULÁRIO	HTML	 21
					</label>
					<label>
									Resumo:	<input	name="resumo"	/>
					</label>
					<label>
									Categoria:	<input	name="categoria"/>
					</label>
					<button	type="submit">Cadastrar</button>
	</form>
3.	 Crie	 um	campo	privado	na	 classe		PostController		 para	 armazenar	 a	 lista	 de	posts.	 Inicialize	 a
variável	 com	 o	 código	 extraído	 da	 action	 Index	 no	 construtor	 da	 classe.	 O	 código	 deverá	 ficar
conforme	abaixo:
	public	class	PostController	:	Controller
	{
					private	IList<Post>	lista;
					public	PostController()
					{
									this.lista	=	new	List<Post>
									{
													new	Post	{	Titulo	=	"Harry	Potter	1",	Resumo	=	"Pedra	Filosofal",	Categoria	=	"Filme,
	Livro"	},
													new	Post	{	Titulo	=	"Cassino	Royale",	Resumo	=	"007",Categoria	=	"Filme"	},
													new	Post	{	Titulo	=	"Monge	e	o	Executivo",	Resumo	=	"Romance	sobre	Liderança",	Catego
ria	=	"Livro"	},
													new	Post	{	Titulo	=	"New	York,	New	York",	Resumo	=	"Sucesso	de	Frank	Sinatra",	Catego
ria	=	"Música"	}
									};
					}
	}
4.	 Crie	uma	nova	action	chamada		Adiciona		no		PostController	.	Coloque	o	código	abaixo:
	public	IActionResult	Adiciona(Post	post)
	{
					lista.Add(post);
					return	View("Index",	lista);
	}
5.	 Teste	sua	aplicação,	 inserindo	um	novo	post	através	da	 rota		/Post/Novo	.	 Se	 tudo	 correr	 bem,	 a
lista	de	posts	aparecerá	com	o	post	recém	incluído.	Mantenha	esta	página	aberta	para	discutirmos	a
próxima	seção.
Repare	no	endereço	inserido	no	navegador	após	o	clique	do	botão	Cadastrar.	Por	exemplo,	para	um
post	com	título	"Harry	Potter	3",	resumo	"Prisioneiro	de	Askaban"	e	categoria	"Filme",	a	parte	final	do
endereço	ficaria	mais	ou	menos	assim:
/Post/Adiciona?titulo=Harry+Potter+3&resumo=Prisioneiro+de+Askaban&categoria=Filme
As	informações	que	foram	preenchidas	no	formulário	estão	no	endereço	do	navegador.
1.16	DESCOBRINDO	OS	MÉTODOS	DAS	REQUISIÇÕES	HTTP
.
22	 1.16	DESCOBRINDO	OS	MÉTODOS	DAS	REQUISIÇÕES	HTTP
Isso	aconteceu	pois,	por	padrão,	o	navegador	envia	as	informações	de	um	formulário	utilizando	um
método	de	envio	chamado		GET	.	Esse	método	coloca	todos	os	parâmetros	da	requisição	no	endereço	do
navegador.	Com	isso,	qualquer	um	pode	ler	o	que	foi	preenchido	no	formulário.	Isso	é	legal?
Pensando	bem,	em	algumas	situações,	pode	não	ser	interessante	mostrar	essas	informações	na	URL
do	navegador.	Por	exemplo,	quando	fazemos	um	login	em	alguma	aplicação.	Neste	caso,	é	importante
usar	uma	alternativa	que	esconda	esses	dados.
Para	 esconder	 as	 informações	do	 formulário,	 deve-se	utilizar	 um	novo	método	de	 envio	 chamado
	POST	.	Este	método	esconde	as	informações	do	formulário	dentro	do	corpo	da	requisição.	Os	métodos
de	envio		GET		e		POST		fazem	parte	da	especificação	do	protocolo	HTTP.
Para	fazer	com	que	um	formulário	HTML	envie	seus	dados	por		POST	,	basta	mudar	a	declaração	da
tag		form		incluindo	o	atributo		method		com	o	valor		"post"	.
<form	action="/Post/Adiciona"	method="post">
				<!--	Declaração	dos	campos	do	formulário	-->
</form>
Com	 essa	 modificação,	 os	 dados	 do	 formulário	 serão	 enviados	 por	 post.	 No	 lado	 do	 servidor,	 a
action	do	controller	aceita	tanto	requisições	feitas	por		GET		quanto	por		POST	.	Para	 limitar	o	 tipo	de
requisição	que	uma	determinada	action	pode	atender,	é	necessário	fazer	uma	configuração	no	ASP.NET
Core	MVC.	Essa	configuração	é	feita	através	dos		Attributes		do	C#	(durante	o	texto,	os		Attributes	
serão	chamados	de	anotações	para	evitar	confusão	com	os	atributos	de	um	objeto).
A	 anotação	 que	 limita	 o	 tipo	 de	 requisição	 que	 uma	 action	 pode	 receber	 para	 	 POST	 	 é	 a
	HttpPostAttribute	:
[HttpPostAttribute]
public	IActionResult	Adiciona(Post	p)
{
				//	Implementação	do	método
}
Mas	 no	 C#,	 por	 convenção,	 todas	 as	 anotações	 possuem	 o	 sufixo	 	Attribute	.	 Por	 isso,	 não	 é
necessário	 colocá-lo	 no	 código,	 o	 C#	 gentilmente	 abrevia	 a	 anotação	 para	 o	 prefixo	 antes	 de
	Attribute	.	Então	a	declaração	do		Adiciona		ficaria	da	seguinte	forma:
[HttpPost]
public	IActionResult	Adiciona(Post	p)
{
				//	Implementação	do	método
}
Da	mesma	forma	que	temos	o		HttpPostAttribute		para	limitar	as	requisições	para	o	tipo		POST	,
também	temos	o		HttpGetAttribute		para	limitar	as	requisições	para	o	tipo		GET	.
.
1.16	DESCOBRINDO	OS	MÉTODOS	DAS	REQUISIÇÕES	HTTP	 23
1.	 Modifique	a	action	para	só	aceitar	requisições	que	forem	enviadas	através	do	método		POST	.	 Para
isso,	anote	a	action	Adiciona	com		[HttpPost]	
2.	 Teste	a	inclusão	do	post	(usando	a	rota		/Post/Novo	).	Sua	aplicação	deverá	enviar	uma	página	de
erro	indicando	recurso	não	encontrado	(404).	Porque	isso	aconteceu?
3.	 Modifique	o	formulário	para	enviar	as	informações	do	post	através	do	método		POST	
4.	 Teste	novamente	sua	aplicação.	Agora	tudo	deve	voltar	ao	normal!
5.	 (opcional)	 Pesquise	 na	 internet	 outras	 limitações	 da	 utilização	 do	 método	 	GET		 em	 formulários
HTML.	Discuta	em	pares.
Execute	a	aplicação	algumas	vezes	e	perceberá	que	a	lista	inicial	de	quatro	posts	só	é	incrementada
uma	única	vez!	Por	que	isso	acontece?
Isso	se	deve	ao	fato	de	que	o	controller	PostController	é	instanciado	toda	vez	que	uma	requisição	for
enviada	por	um	cliente.	Abra	o	código	do	controlador	e	 repare	que	a	 lista	é	criada	e	populada	no	seu
construtor.	Isto	é,	toda	vez	que	o	controlador	for	instanciado,	uma	lista	com	quatro	itens	será	gerada!	Na
requisição	de	 inclusão	de	post,	a	 lista	com	quatro	posts	 teve	mais	um	adicionado	e	passou	para	cinco
itens.	 Contudo,	 quando	 enviarmos	 nova	 requisição,	 a	 lista	 será	 reinicializada,	 perdendo	 o	 quinto
elemento.
A	causa	desse	problema	é	que	não	podemos	usar	a	memória	da	aplicação	para	persistir	os	objetos	do
domínio.	Esse	 tipo	de	memória	 é	 volátil.	É	necessário	 usar	 outras	 estratégias	 de	persistência.	A	mais
comum	e	utilizada	nas	aplicações	web	é	o	banco	de	dados	relacional.
Mais	para	frente	no	curso	vamos	discutir	como	persistir	posts	usando	algum	banco	de	dados.
Neste	 capítulo	 inicial	 você	 conheceu	 a	 solução	Microsoft	 para	 projetos	Web	 utilizando	 o	 famoso
padrão	arquitetural	MVC,	o	ASP.NET	Core	MVC.	Além	disso,	conheceu	mais	a	fundo	a	especificação
do	 protocolo	 HTTP,	 a	 saber,	 o	 modelo	 Requisição-Resposta,	 como	 parâmetros	 são	 enviados	 nas
requisições,	e	dois	métodos	de	envio	de	requisições,		GET		e		POST	.	Dentro	do	ASP.NET	Core	MVC,
você	conheceu	 seu	 sistema	de	 roteamento,	usando	controllers	e	actions,	 e	 seu	 sistema	de	 captura	 das
informações	 vindas	 das	 requisições,	 chamado	Model	Binding.	 Por	 fim,	 conheceu	 as	 alternativas	 de
transporte	de	dados	entre	controllers	e	views	com	a		ViewBag		e	as	views	fortemente	tipadas.
1.17	EXERCÍCIOS
1.18	O	QUE	VEM	PELA	FRENTE?
1.19	CONCLUSÃO
.
24	 1.8	EXERCÍCIOS
CAPÍTULO	2
Muitos	 sistemas	 tornam-se	 difíceis	 de	 manter	 porque	 existem	 trechos	 de	 código	 que	 tem	 muita
responsabilidade,	 ou	 seja,	 fazem	muitas	 coisas.	 Aplicações	 desktop	 são	 um	 exemplo	 empírico	 desse
problema.	Muitos	códigos	legados	em	VB	ou	Delphi	são	difíceis	de	manter	porque	um	mesmo	trecho	de
código	 é	 responsável	 por:	 capturar	 dados	 do	 usuário	 (através	 de	 caixas	 de	 texto,	 botões,	 etc),	 tomar
ações	a	partir	desses	dados	(por	exemplo,	alterar	uma	tabela	no	banco	de	dados)	e	alterar	a	interface	do
usuário	para	mostrar	que	o	programa	reagiu	da	maneira	esperada	(exibindo	uma	mensagem	de	sucesso).
O	problema	da	falta	de	divisão	de	responsabilidades	não	ocorre	apenas	no	desktop.	Na	web,	temos
páginas	ASP	que	contém,	além	de	código	HTML	(para	a	apresentação	do	resultado),	código	VBScript
com	a	 lógica	de	negócio	e	código	SQL	acessando	o	banco	de	dados.	Tudo	 isso	é	difícil	de	manter.	O
código	fica	espalhado	e,	muitas	vezes,	repetido.
Uma	possível	solução	para	o	problema	é	tentar	separar	as	diversas	tarefas	citadas	acima,	da	seguinte
forma:
Quando	um	usuário	interage	com	o	sistema,	ele	executa	uma	ação	e	obtém	visualmente	o	resultado
da	mesma.	 Isto	 é,	 primeiro	 uma	 regra	 de	 negócios	 é	 executada	 (como	 adicionar,	 atualizar	 ou	 buscar
algo)	e	depois	informações	são	mostradas	na	tela.
Isso	forma	três	componentes:	O		Model		é	responsável	somente	pelas	regras	de	negócio;	a		View		é
responsável	unicamente	por	exibir	os	dados	para	o	usuário	final;	por	fim,	o		Controller		é	responsável
por	receber	as	ações	feitas	pelos	usuários	na		View		e	convertê-las	em	chamadas	de	negócio	dentro	do
	Model	.	 O	 padrão	 conhecido	 por	 MVC	 (Model-View-Controller)	 sugere	 que	 o	 programador	 faça
exatamente	essa	separação	no	código.
Veja	o	desenho	abaixo:
CÓDIGO	DE	QUALIDADE	COM	O
PADRÃO	MVC
.
2	CÓDIGO	DE	QUALIDADE	COM	O	PADRÃO	MVC	 25
Todo	sistema	possui	regras	de	negócios,	que	podem	ser	simples	ou	complexas.Todas	elas	devem
estar	 separadas	 em	 classes	 que	 tem	 essa	 regras	 como	 única	 responsabilidade.	 Ou	 seja,	 toda	 e
qualquer	ação	de	regra	de	negócio	deve	ser	realizada	por	exclusivamente	esse	conjunto	de	classes.
Interfaces	de	usuário	 também	devem	ser	 isoladas.	Códigos	de	 interface	 tendem	a	ser	grandes	e	a
sofrerem	 mudanças	 constantes.	 Por	 esse	 motivo,	 toda	 parte	 responsável	 pela	 exibição	 das
informações	para	o	usuário	devem	estar	isoladas	em	outro	ponto	do	sistema.
Para	conectar	as	ações	que	o	usuário	realiza	na	interface	e	fazer	com	que	essas	ações	resultem	em
execuções	de	regra	de	negócio,	é	necessário	que	um	outro	componente	faça	essa	tarefa.	Ou	seja,	ele
recebe	informações	da		View		e	as	transforma	em	invocações	de	regras	de	negócio.
O	padrão	MVC	tem	se	mostrado	uma	maneira	adequada	de	separar	esses	componentes	e	por	isso	sua
utilização	é	crescente	no	mercado.	Muitos	frameworks,	inclusive	de	outras	linguagens	de	programação,
como	é	o	caso	do		Ruby	on	Rails		(do	mundo	Ruby)	e		VRaptor		 (do	mundo	Java),	adotam	o	MVC
como	solução	para	separar	responsabilidades.
O	 ASP.NET	 Core	 MVC,	 como	 o	 próprio	 nome	 diz,	 segue	 o	 padrão	 MVC.	 Veja	 que	 os	 nomes
adotados	pelo	MVC	são	idênticos	aos	do	padrão	MVC.	Suas	regras	de	negócio	devem	ficar	em	classes
C#	convencionais	dentro	da	pasta		/Models	.	O	código	responsável	apenas	pela	interface	do	usuário	é
salvo	na	pasta		/Views	.	Por	 fim,	 as	 classes	 controladoras	 são	 salvas	no	diretório		/Controllers	,	 e
conectam	a	view	com	os	modelos.
Perceba	a	separação!	Não	há	mistura	de	código!	Isso	faz	do	MVC	um	dos	padrões	mais	populares
para	desenvolvimento	de	aplicações!
Leia	 um	 pouco	 mais	 sobre	 o	 MVC	 no	 site	 do	 Martin	 Fowler	 no	 site
.
26	 2	CÓDIGO	DE	QUALIDADE	COM	O	PADRÃO	MVC
http://martinfowler.com/eaaCatalog/modelViewController.html
1.	 Quais	os	motivos	para	não	colocar	código	de	lógica	junto	com	o	código	HTML?
2.	 Já	que	o	MVC	é	um	padrão	e	é	você	quem	escreve	os	Controllers,	os	Models	e	as	Views,	aonde	o
framework	ASP.NET	Core	MVC	te	ajuda?
3.	 Quando	uma	requisição	chega	ao	servidor,	qual	a	ordem	de	execução	comum?
Invoca	o	controller,	que	executa	alguma	lógica	no	Model	e,	ao	fim,	redireciona	para	uma	view
Renderiza	a	view	e	depois	executa	uma	lógica
Mostra	a	view,	que	invoca	o	model,	que	por	sua	vez	invoca	o	controller
4.	 E	caso	precisássemos	executar	 alguma	outra	 tarefa	 antes	de	 todas	as	 lógicas,	 como,	por	 exemplo,
abrir	uma	conexão	com	o	banco	de	dados?	Você	repetiria	esse	código	em	todos	as	suas	actions?	Qual
seria	o	problema	disso?
5.	 Explique	agora,	com	as	suas	palavras,	o	que	é	o	padrão	MVC	e	o	porquê	dele	ser	útil.
2.1	EXERCÍCIOS
.
2.1	EXERCÍCIOS	 27
http://martinfowler.com/eaaCatalog/modelViewController.html
CAPÍTULO	3
Ao	final	deste	capítulo	você	vai:
conhecer	o	componente	ADO.NET	e	sua	responsabilidade
aprender	a	abrir	uma	conexão	com	um	banco	de	dados
descobrir	como	enviar	comandos	SQL	para	o	banco
ler	o	resultado	de	um	SELECT
reconhecer	partes	de	código	em	sua	aplicação	que	podem	ser	isoladas
conhecer	a	camada	arquitetural	de	acesso	aos	dados	chamada	Data	Access	Object
Ainda	existe	o	problema	do	blog	com	posts	estáticos.	A	única	maneira	de	tornar	o	blog	dinâmico	é
persistir	os	posts	em	outra	área	de	memória,	separada	da	memória	da	aplicação.	Desta	forma,	quando	a
aplicação	sair	do	ar,	os	posts	continuam	registrados	nesta	outra	memória.	Como	alternativas	para	estas
outras	memórias,	existem	arquivos	XML,	bancos	de	dados,	outros	serviços	Web,	dentre	outros.
O	banco	de	dados	normalmente	é	uma	aplicação	separada	que	está	sendo	executada	em	uma	rede	de
computadores,	 por	 exemplo	 na	 rede	 local	 da	 sua	 empresa.	 Existem	 diversos	 bancos	 de	 dados	 no
mercado:	MySQL,	 SQL	 Server,	 Oracle	 e	 Postgre	 SQL.	 Neste	 curso	 vamos	 usar	 o	 SQL	 Server	 para
persistir	os	posts	do	blog.
Como	recuperar	os	posts	do	blog	do	banco?
A	 aplicação	 precisará	 substituir	 o	 código	 que	 popula	 a	 lista	 de	 posts	 arbitrariamente	 por	 alguma
instrução	 que	 retorne	 os	 posts	 do	 banco	 de	 dados.	 Além	 disso,	 precisará	 mudar	 o	 código	 da	 action
	Adiciona		 para	 efetivamente	 armazenar	 o	 post	 no	 banco	 de	 dados.	 A	 linguagem	 utilizada	 para	 a
comunicação	com	os	bancos	de	dados	relacionais	é	o		SQL	.	Por	exemplo,	para	consultar	todos	os	posts
existentes	numa	tabela	chamada		Posts		o	seguinte	SQL	é	usado:
select	*	from	Posts
E	para	incluir	um	registro	na	mesma	tabela	com	colunas	iguais	às	propriedades	da	classe	Post:
insert	into	Posts	(Titulo,	Resumo,	Categoria)	values	('Harry	Potter	4',	'Cálice	de	Fogo',	'Filmes')
Para	enviar	estes	comandos,	é	preciso	inicialmente	abrir	uma	conexão	que	será	utilizada	para	toda
PERSISTINDO	POSTS	EM	UM	BANCO	DE
DADOS
.
28	 3	PERSISTINDO	POSTS	EM	UM	BANCO	DE	DADOS
comunicação	com	o	banco	de	dados.	Para	abrí-la,	é	preciso	comunicar-se	com	uma	aplicação	da	rede.
Isto	pode	ser	feito	através	de	sockets	dentro	da	aplicação,	porém	toda	a	comunicação	feita	com	o	banco
de	dados	através	dos	sockets	precisa	ser	feita	através	de	um	protocolo	proprietário	que	muda	de	acordo
com	o	banco	de	dados	utilizado.
Para	 facilitar	 este	 trabalho,	 a	Microsoft	 criou	 o	ADO.NET,	 que	 fornece	Drivers	 específicos	 que
implementam	o	protocolo	proprietário	de	comunicação	com	cada	banco.	Esses	drivers	são	conhecidos
como	Data	Providers.
O	Data	Provider	é	o	componente	que	cuida	da	tradução	dos	comandos	da	aplicação	para	o	banco	de
dados	 e	 também	da	 tradução	da	 resposta	 devolvida	 pelo	 banco	de	 dados	 para	 objetos	 que	 podem	 ser
utilizados	pela	aplicação.
Um	dos	principais	conceitos	dos	bancos	relacionais	é	a	existência	de	uma	chave	primária,	que	é	um
subconjunto	 de	 colunas	 de	 uma	 tabela	 que	 identifica	 unicamente	 um	 registro	 armazenado	 em	 uma
tabela.	Quais	colunas	usaremos	para	representar	a	chave	primária	de	um	post?	No	nosso	modelo	atual,
podemos	ter	posts	com	resumos	e	categorias	iguais,	mas	dificilmente	teremos	posts	com	títulos,	resumos
E	 categorias	 iguais.	 Apesar	 destas	 propriedades	 serem	 candidatas	 a	 comporem	 a	 chave	 primária	 da
tabela	de	posts,	em	geral	criamos	uma	coluna	 interna	específica	com	esse	propósito.	Por	esse	motivo,
iremos	adicionar	uma	nova	propriedade,	do	tipo	inteiro,	no	modelo	de	Post	chamada		Id	.
public	class	Post
{
				public	int	Id	{	get;	set;	}
				public	string	Titulo	{	get;	set;	}
				public	string	Resumo	{	get;	set;	}
				public	string	Categoria	{	get;	set;	}
}
Uma	 conexão	 com	 o	 SQL	 Server	 exige	 uma	 instância	 de	 	SqlConnection	.	 Para	 utilizar	 essa
conexão,	 é	 necessário	 passar	 as	 informações	 do	 servidor	 desejado.	 Essas	 informações	 são	 chamadas
strings	 de	 conexão	 e	 podem	 ser	 enviadas	 como	 argumento	 do	 construtor	 de	 	SqlConnection	.	 No
exercício	será	informado	como	recuperar	as	informações	de	conexão	para	a		ConnectionString	.
var	stringConexao	=	????
SqlConnection	conexao	=	new	SqlConnection(stringConexao);
Essa	variável		conexao		representa	uma	conexão	que	ainda	não	está	aberta	com	o	banco	de	dados.
Para	abrir	a	conexão	com	o	banco	de	dados,	o	método		Open		 é	 utilizado.	Para	 terminar	 de	utilizar	 a
conexão,	fecha-se	com	o		Close	:
3.1	IDENTIFICANDO	UNICAMENTE	UM	POST
3.2	ABRINDO	A	CONEXÃO	COM	O	ADO.NET
.
3.1	IDENTIFICANDO	UNICAMENTE	UM	POST	 29
//	Abre	a	conexão:
conexao.Open();
//	Operações	que	utilizam	a	conexão
//	Fecha	a	conexão:
conexao.Close();
Como	a		SqlConnection		implementa	a	interface		IDisposable	,	é	possível	gerenciar	o	 tempo	de
vida	de	uma	conexão	com	o		using		do	C#:
var	stringConexao	=	????;
using(SqlConnection	conexao	=	new	SqlConnection(stringConexao))
{
				//	Inicializa	a	string	de	conexão
				conexao.Open();
				//	usa	a	conexão
				//	não	é	necessário	chamar	o	close	pois	ao	sair	do	bloco
				//	a	conexão	será	automaticamente	fechada.
}
A	abordagem	acima	consegue	facilmente	criar	uma	nova	conexão	com	o	banco	de	dados,	mas	deixa
a	 string	 de	 conexão	 diretamente	 no	 código	 daaplicação.	 Em	muitas	 aplicações,	 a	 string	 de	 conexão
utilizada	durante	o	desenvolvimento	é	diferente	de	quando	a	aplicação	é	publicada.	Nesse	caso,	deixar	a
string	de	conexão	no	código	da	aplicação	não	é	uma	boa	ideia.
Uma	 solução	 melhor	 é	 colocar	 a	 string	 de	 conexão	 em	 algum	 arquivo	 de	 configuração,	 o
	appsettings.json	.	Assim,	na	publicação	basta	 simplesmente	modificar	a	configuração	ao	 invés	de
modificar	todo	o	código.
Dentro	do		appsettings.json		utilizamos	uma	chave	de		ConnectionStrings		para	listar	as	strings
de	conexão	da	aplicação.	Para	adicionar	uma	nova	connection	string,	basta	adicionar	mais	uma	chave	da
	ConnectionStrings	:
{
				//...
				"ConnectionStrings":	{
								"Blog":	"string	de	conexao"
				}
}
Para	o	caso	do	SQL	Server,	sua	string	de	conexão	deverá	ficar	parecido	com	esta:
{
				//...
				"ConnectionStrings":	{
								"Blog":	"Data	Source=<nome	do	host>;Database=Blog;Integrated	Security=True"
				}
}
3.3	ISOLANDO	A	STRING	DE	CONEXÃO
.
30	 3.3	ISOLANDO	A	STRING	DE	CONEXÃO
Para	recuperar	a	string	de	conexão	do	arquivo	de	configuração,	precisamos	de	uma	nova	interface	do
C#	chamada		IConfiguration		que	será	gerada	pela	classe		ConfigurationBuilder	.	A	 instância	 de
	IConfiguration		tem	um	dicionário	com	as	strings	que	foram	configuradas	no	json,	sendo	que	um	dos
métodos	 é	 o	 	 GetConnectionString	 	 responsável	 por	 recuperar	 chaves	 dentro	 da
	ConnectionStrings	.	Agora	basta	informar	pelo		ConfigurationBuilder		que	queremos	ler	o	arquivo
	appsettings.json	:
var	builder	=	new	ConfigurationBuilder()
																.SetBasePath(Directory.GetCurrentDirectory())
																.AddJsonFile("appsettings.json",	optional:	false,	reloadOnChange:	true)
																.AddEnvironmentVariables();
IConfiguration	configuration	=	builder.Build();
string	stringConexao	=	configuration.GetConnectionString("Blog");
using	(SqlConnection	conexao	=	new	SqlConnection(stringConexao))
{
				//	Inicializa	a	string	de	conexão
				conexao.Open();
				//	usa	a	conexão
				//	não	é	necessário	chamar	o	close	pois	ao	sair	do	bloco
				//	a	conexão	será	automaticamente	fechada.
}
Agora	 que	 conectamos	 com	 o	 banco,	 precisaríamos	 usar	 os	 métodos	 	Index		 e	 	Adiciona		 do
	PostController		para	executar	suas	responsabilidades.	O	código	para	abrir	a	conexão	é	duplicado	nos
dois	métodos:
public	class	PostController	:	Controller	{
				public	IActionResult	Index()	{
								var	builder	=	new	ConfigurationBuilder()
																.SetBasePath(Directory.GetCurrentDirectory())
																.AddJsonFile("appsettings.json",	optional:	false,	reloadOnChange:	true)
																.AddEnvironmentVariables();
								IConfiguration	configuration	=	builder.Build();
								string	stringConexao	=	configuration.GetConnectionString("Blog");
								using	(SqlConnection	conexao	=	new	SqlConnection(stringConexao))
								{
												conexao.Open();
											//...busca	todos	os	posts...
								}
				}
				public	IActionResult	Adiciona(Post	post)	{
								var	builder	=	new	ConfigurationBuilder()
																.SetBasePath(Directory.GetCurrentDirectory())
																.AddJsonFile("appsettings.json",	optional:	false,	reloadOnChange:	true)
																.AddEnvironmentVariables();
								IConfiguration	configuration	=	builder.Build();
								string	stringConexao	=	configuration.GetConnectionString("Blog");
								using	(SqlConnection	conexao	=	new	SqlConnection(stringConexao))
3.4	ISOLANDO	A	CONEXÃO	EM	SUA	PRÓPRIA	CLASSE
.
3.4	ISOLANDO	A	CONEXÃO	EM	SUA	PRÓPRIA	CLASSE	 31
								{
												conexao.Open();
											//...salva	post	no	banco...
								}
				}
}
É	muito	 comum	 abrir	 uma	 conexão	 com	o	 banco	 de	 dados	 dentro	 de	 vários	 pontos	 diferentes	 da
aplicação.	Deste	modo	seria	necessário	copiar	o	código	de	criação	da	conexão	para	cada	ponto.	Como	já
vimos,	todo	código	repetido	é	fonte	de	problemas	de	manutenção.
Por	exemplo,	o	que	aconteceria	 se	o	nome	da	string	de	conexão	 fosse	modificado	de		Blog		 para
	ConexaoBlog		no		appsettings.json	?
Ou	 se	 a	 string	 de	 conexão	 passasse	 a	 ser	 obtida	 não	mais	 através	 do		appsettings.json		 e	 sim
através	de	outro	método	qualquer?
Nesses	casos,	seria	preciso	mudar	o	código	de	abertura	de	conexões	em	todos	os	locais.	E	o	risco	de
esquecermos	algum	seria	proporcional	a	quantidade	de	arquivos	que	precisariam	ser	alterados.
Para	evitar	esse	problema,	uma	solução	é	isolar	esse	código	dentro	de	uma	nova	classe	especializada
apenas	em	criar	conexões:
public	class	CriadorDeConexoes
{
				public	static	SqlConnection	CriaConexaoAberta()
				{
								var	builder	=	new	ConfigurationBuilder()
																.SetBasePath(Directory.GetCurrentDirectory())
																.AddJsonFile("appsettings.json",	optional:	false,	reloadOnChange:	true)
																.AddEnvironmentVariables();
								IConfiguration	configuration	=	builder.Build();
								string	stringConexao	=	configuration.GetConnectionString("Blog");
								SqlConnection	conexao	=	new	SqlConnection(stringConexao);
								conexao.Open();
								return	conexao;
				}
}
Uma	 vez	 que	 não	 precisamos	 de	 qualquer	 informação	 da	 classe	CriadorDeConexoes,	 tornamos	 o
método	estático	(palavra	chave	static).	Além	disso,	já	retornamos	a	conexão	aberta.
Com	 isso,	 todos	 os	 pontos	 da	 aplicação	 que	 precisarem	 de	 uma	 conexão	 com	 o	 banco	 podem
simplesmente	chamar	o		CriaConexaoAberta	:
SqlConnection	conexao	=	CriadorDeConexoes.CriaConexaoAberta();
Classes	que	 têm	a	responsabilidade	de	criar	objetos,	 implementam	um	padrão	de	projeto	chamado
Factory	Method.	Classes	que	implementam	o		Factory	Method		geralmente	 seguem	uma	convenção
de	nomes	para	facilitar	o	entendimento	do	código.	O	nome	da	classe	fica	com	o	nome	do	objeto	que	será
.
32	 3.4	ISOLANDO	A	CONEXÃO	EM	SUA	PRÓPRIA	CLASSE
criado,	seguido	do	sufixo		Factory	.	No	nosso	caso,	vamos	adotar	o	nome		ConnectionFactory	.
1.	 O	 primeiro	 passo	 será	 criar	 o	 seu	 banco	 de	 dados	 do	Blog	 no	 SQL	 Server.	Você	 pode	 usar	 uma
ferramenta	como	o	Microsoft	SQL	Server	Management	Studio	caso	você	ainda	não	tenha	uma	base
para	o	blog.	Ou	então,	em	seu	terminal,	execute	o	comando
	sqlcmd
que	 abrirá	 o	 utilitário	 de	 linha	 de	 comando	 do	 SQL	 Server.	Nele	 podemos	 executar	 os	 seguintes
comandos	para	criar	nossa	base	de	dados	do		Blog	
	create	database	Blog
	GO
	use	Blog
	GO
Depois	devemos	criar	uma	tabela	de		Posts		nesta	base,	executando	o	comando	de		CREATE	TABLE	
a	seguir:
	CREATE	TABLE	[dbo].[Posts]
	(
					[Id]	INT	NOT	NULL	PRIMARY	KEY	IDENTITY(1,1),
					[Titulo]	VARCHAR(50),
					[Resumo]	VARCHAR(500),
					[Categoria]	VARCHAR(50)
	)
	GO
Para	não	ficar	vazio,	insira	alguns	posts	nesta	base	através	do	comando	de	insert:
	insert	into	Posts(Titulo,	Resumo,	Categoria)	
	values	('Título	do	post',	'Resumo	do	post',	'Categoria	do	post')
	GO
2.	 Modifique	a	classe		Post		para	adicionar	a	propriedade		Id	,	do	tipo	int,	que	será	a	chave	primária
da	tabela	de	posts.
3.	 Agora	 vamos	 configurar	 a	 string	 de	 conexão.	 Abra	 o	 arquivo	 	appsettings.json		 e	 adicione	 a
chave		ConnectionStrings	.	Dentro	dela	você	adicionará	a	chave		Blog		com	as	configurações	do
seu	banco	de	dados	SQL	Server,	parecido	com	o	código	a	seguir:
	{
					//...
					"ConnectionStrings":	{
									"Blog":	"Data	Source=<nome	do	host>;Database=Blog;Integrated	Security=True"
					}
	}
4.	 Crie	 uma	 pasta	 chamada	 	 Infra	 	 e	 crie	 a	 classe	 	 ConnectionFactory	 	 com	 o	 método
	CriaConexaoAberta	.
3.5	EXERCÍCIOS
.
3.4	ISOLANDO	A	CONEXÃO	EM	SUA	PRÓPRIA	CLASSE	 33
	namespace	Blog.Infra
	{
					public	class	ConnectionFactory
					{
									public	static	SqlConnection	CriaConexaoAberta()
									{
													var	builder	=	new	ConfigurationBuilder()
																									.SetBasePath(Directory.GetCurrentDirectory())
																									.AddJsonFile("appsettings.json",	optional:	false,	reloadOnChange:	true).AddEnvironmentVariables();
													IConfiguration	configuration	=	builder.Build();
													string	stringConexao	=	configuration.GetConnectionString("Blog");
													SqlConnection	conexao	=	new	SqlConnection(stringConexao);
													conexao.Open();
													return	conexao;
									}
					}
	}
No		PostController	,	vamos	substituir	o	código	que	adiciona	posts	arbitrários	na	lista	de	posts,	por
registros	que	vêm	do	banco	de	dados.
Como	vimos	anteriormente,	para	selecionar	todos	os	registros	da	tabela	de	posts,	fazemos:
select	*	from	Posts
Para	enviar	esse	comando	SQL	para	o	banco	de	dados	é	necessário	uma	instância	de		SqlCommand	,
que	é	obtida	a	partir	de	uma	conexão	aberta	com	o	banco	de	dados,	representada	por	uma	instância	de
	SqlConnection	.	Para	 informar	o	SQL	desejado	usa-se	a	propriedade		CommandText	.	O	 código	que
realiza	essa	tarefa	fica	deste	jeito:
using	(SqlConnection	cnx	=	ConnectionFactory.CriaConexaoAberta())
{
		SqlCommand	comando	=	cnx.CreateCommand();
		comando.CommandText	=	"select	*	from	Posts";
}
Para	 rodar	 o	 comando	 no	 banco	 de	 dados,	 utiliza-se	 o	 método	 	ExecuteReader	.	 Este	 método
executa	o	comando	SQL	no	banco	de	dados	e	devolve	um	objeto	que	representa	o	resultado	da	busca	no
banco.	Esse	objeto	devolvido	é	uma	instância	de		SqlDataReader	:
SqlDataReader	leitor	=	comando.ExecuteReader();
O		SqlDataReader		lê	linha	a	linha	o	resultado	da	consulta	no	banco	de	dados.	Para	avançar	para	a
próxima	 linha,	 usa-se	 o	método	 	Read	.	 Quando	 esse	método	 consegue	 avançar	 com	 sucesso	 para	 a
próxima	linha,	ele	devolve		true	.	Caso	contrário,	devolve		false	.
Enquanto		Read		devolver		true	,	o	código	continuará	lendo	o	próximo	registro:
while(leitor.Read())
3.6	LISTANDO	OS	POSTS	DO	BANCO
.
34	 3.6	LISTANDO	OS	POSTS	DO	BANCO
{
				//	lê	as	informações	do	registro
}
O	 	SqlDataReader		 também	 funciona	 como	 um	 dicionário,	 que	 pode	 ser	 utilizado	 para	 ler	 as
informações	do	registro	atual.	Nesse	dicionário,	as	chaves	são	os	nomes	das	colunas	do	banco	de	dados
e	os	valores	são	as	informações	armazenadas	em	cada	coluna.	Por	exemplo,	para	recuperar	o		titulo	
do	post,	usa-se	o	seguinte	código:
leitor["titulo"];
Porém,	o	valor	devolvido	é	de	um	tipo	definido	pelo	banco	de	dados.	Para	fazer	a	conversão	do	tipo
devolvido	pelo		SqlDataReader		para	um	tipo	do	C#,	utiliza-se	a	classe		Convert	:
string	titulo	=	Convert.ToString(leitor["titulo"]);
As	 informações	 devolvidas	 pela	 query	 pertencem	 a	 um	 post.	Nada	mais	 natural	 do	 que	 criar	 um
objeto	do	tipo		Post		para	armazenar	as	informações	devolvidas.	Para	completar	o	código,	basta	apenas
guardar	os	posts	dentro	da	lista	do	C#:
var	listaDePosts	=	new	List<Post>();
while(leitor.Read())
{
				Post	post	=	new	Post()	{
						Id	=	Convert.ToInt32(leitor["id"]),
						Titulo	=	Convert.ToString(leitor["titulo"]),
						Resumo	=	Convert.ToString(leitor["resumo"]),
						Categoria	=	Convert.ToString(leitor["categoria"])
				};
				listaDePosts.Add(post);
}
Por	fim,	o	código	completo	da	action		Index		ficaria	assim:
public	IActionResult	Index()
{
				IList<Post>	lista	=	new	List<Post>();
				using	(SqlConnection	cnx	=	ConnectionFactory.CriaConexaoAberta())
				{
								SqlCommand	comando	=	cnx.CreateCommand();
								comando.CommandText	=	"select	*	from	Posts";
								SqlDataReader	leitor	=	comando.ExecuteReader();
								while	(leitor.Read())
								{
												Post	post	=	new	Post()
												{
																Id	=	Convert.ToInt32(leitor["id"]),
																Titulo	=	Convert.ToString(leitor["titulo"]),
																Resumo	=	Convert.ToString(leitor["resumo"]),
																Categoria	=	Convert.ToString(leitor["categoria"])
												};
												lista.Add(post);
								}
				}
				return	View(lista);
}
.
3.6	LISTANDO	OS	POSTS	DO	BANCO	 35
Já	foi	possível	sentir	que	colocar	código	SQL	dentro	de	suas	classes	de	lógica	é	algo	nem	um	pouco
elegante	e	muito	menos	viável	quando	você	precisa	manter	o	seu	código.
Quantas	vezes	você	não	ficou	bravo	com	o	programador	responsável	por	aquele	código	ilegível?
A	ideia	a	seguir	é	remover	o	código	de	acesso	ao	banco	de	dados	de	suas	classes	de	lógica	e	colocá-
lo	em	uma	classe	responsável	pelo	acesso	aos	dados.	Assim	o	código	de	acesso	ao	banco	de	dados	fica
em	um	lugar	só,	tornando	mais	fácil	a	manutenção.
Que	tal	se	pudéssemos	chamar	um	método	que	lista	todos	os		Posts		do	banco?
Em	outras	palavras	quero	que	o	código	a	seguir	funcione:
//	lista	os	posts	do	banco
Misterio	bd	=	new	Misterio();
IList<Post>	lista	=	bd.ListaPosts();
Tentaremos	chegar	ao	código	anterior:	seria	muito	melhor	e	mais	elegante	poder	chamar	um	único
método	responsável	pela	listagem,	certo?
public	IActionResult	Index()
{
				Misterio	bd	=	new	Misterio();
				//	método	elegante
				IList<Post>	lista	=	bd.ListaPosts();
				return	View(lista);
}
O	código	anterior	já	mostra	o	poder	que	alcançaremos:	através	de	uma	única	classe	seremos	capazes
de	acessar	o	banco	de	dados	e,	mais	ainda,	somente	através	dessa	classe	será	possível	acessar	os	dados.
Esta	ideia,	inocente	à	primeira	vista,	é	capaz	de	isolar	todo	o	acesso	a	banco	em	classes	bem	simples,
cuja	instância	é	um	objeto	responsável	por	acessar	os	dados.	Da	responsabilidade	deste	objeto	surgiu	o
nome	de	Data	Access	Object	ou	simplesmente	DAO,	um	dos	mais	famosos	padrões	de	projeto	(design
pattern).
Vamos	isolar	o	código	que	lista	numa	classe	chamada		PostDAO		com	um	método		Lista	:
				public	class	PostDAO	{
								public	IList<Post>	Lista()
								{
												var	lista	=	new	List<Post>();
												using	(SqlConnection	cnx	=	ConnectionFactory.CriaConexaoAberta())
												{
																SqlCommand	comando	=	cnx.CreateCommand();
																comando.CommandText	=	"select	*	from	Posts";
																SqlDataReader	leitor	=	comando.ExecuteReader();
																while	(leitor.Read())
																{
																				Post	post	=	new	Post()
3.7	DAO	-	DATA	ACCESS	OBJECT
.
36	 3.7	DAO	-	DATA	ACCESS	OBJECT
																				{
																								Id	=	Convert.ToInt32(leitor["id"]),
																								Titulo	=	Convert.ToString(leitor["titulo"]),
																								Resumo	=	Convert.ToString(leitor["resumo"]),
																								Categoria	=	Convert.ToString(leitor["categoria"])
																				};
																				lista.Add(post);
																}
												}
												return	lista;
								}
				}
Agora,	no		PostController		podemos	usar	a	classe		PostDAO		da	seguinte	forma:
public	IActionResult	Index()
{
				PostDAO	dao	=	new	PostDAO();
				//	método	elegante
				IList<Post>	lista	=	dao.Lista();
				return	View(lista);
}
1.	 Crie	uma	nova	pasta		/DAO		e	adicione	a	classe		PostDAO		com	o	método	que		Lista		todos	os	posts.
Este	método	deve	pegar	uma	conexão	aberta	usando	a		ConnectionFactory	,	 fazer	 a	 consulta	 de
todos	os	posts	cadastrados	no	banco	e	retornar	a	lista	de	posts,	utilizando	o	código	da	seção	anterior.
2.	 Modifique	a	action		Index		no		PostController		para	utilizar	os	registros	de	posts	salvos	no	banco
de	dados	criado	no	exercício	anterior	ao	invés	dos	objetos	gerados	manualmente	dentro	da	action.
3.	 Teste	a	aplicação.	Agora	a	tabela	HTML	está	sendo	populada	pelos	registros	do	banco	de	dados	que
criamos.
O	blog	 já	mostra	 a	 listagem	de	posts	 recuperada	do	banco	de	dados.	Porém,	nosso	 formulário	 de
inclusão	ainda	inclui	o	post	em	memória	(na	lista).	Precisamos	modificar	o	código	da	action		Adiciona	
para	que	o	post	seja	incluído	no	banco	de	dados.	Atualmente	o	código	da	action	está	assim:
public	IActionResult	Adiciona(Post	post)
{
				lista.Add(p);	<<==	CÓDIGO	A	SER	SUBSTITUÍDO!
				return	View("Index",	lista);
}
Precisamos	substituir	o	código	da	primeira	linha	pelo	código	que	insere	o	post	no	banco	de	dados.
Vimos	no	capítulo	anterior	que	enviamos	comandos	para	um	banco	de	dados	SQL	Server	através	de
instâncias	 da	 classe	 SqlCommand.	 O	 comando	 SQL	 responsável	 pela	 inclusão

Continue navegando