1
04 - INTERFACE DO USUÁRIO E NAVEGAÇÃO.......................................................................................................... 42
O QUE VOCÊ VAI APRENDER:..............................................................................................................................................42
MODIFICAR A INTERFACE DO USUÁRIO.................................................................................................................................42
@Page Directiva......................................................................................................................................................44
Controles de servidor Web......................................................................................................................................44
Código do servidor..................................................................................................................................................45
Atualizando a página mestra.................................................................................................................................45
Páginas mestras.......................................................................................................................................................49
Adicionando arquivos de imagem....................................................................................................................................49
Baixe do site de exemplos do MSDN:...............................................................................................................................49
Adicionando páginas...............................................................................................................................................51
Atualizando o Bootstrap.........................................................................................................................................52
Modificando o padrão de navegação....................................................................................................................54
Adicionando um controle de dados para exibir dados de navegação...............................................................55
Vinculando o controle de dados para o banco de dados....................................................................................56
Executando o aplicativo e criando o banco de dados..........................................................................................57
Revendo o banco de dados.....................................................................................................................................58
RESUMO........................................................................................................................................................................ 61
05 - EXIBIR ITENS DE DADOS E DETALHES................................................................................................................ 63
O QUE VOCÊ VAI APRENDER:..............................................................................................................................................63
Estes são os recursos introduzidos no tutorial:.....................................................................................................63
ADICIONANDO UM CONTROLE DE DADOS PARA EXIBIR OS PRODUTOS.........................................................................................63
Usando um controle de fonte de dados para vincular a dados..........................................................................63
Codificação manual para vincular dados.............................................................................................................63
Usando o modelo de ligação para ligar dados.....................................................................................................64
EXIBINDO PRODUTOS........................................................................................................................................................64
Adicionar código para exibir os produtos.............................................................................................................67
Executando o aplicativo..........................................................................................................................................69
Adicionando um controle de dados para exibir detalhes do produto................................................................71
Executando o aplicativo..........................................................................................................................................74
RESUMO........................................................................................................................................................................ 75
06 - CARRINHO DE COMPRAS................................................................................................................................. 76
O QUE VOCÊ VAI APRENDER:..............................................................................................................................................76
CARACTERÍSTICAS DO CÓDIGO NESTE TUTORIAL:.....................................................................................................................76
CRIANDO UM CARRINHO DE COMPRAS.................................................................................................................................76
Adicionar CartItem como uma classe de modelo................................................................................................77
Atualizar o contexto do produto............................................................................................................................79
Gerenciando a lógica de negócios do carrinho compras....................................................................................80
Criando a classe carrinho de compras..............................................................................................................................81
Criando a funcionalidade de adicionar ao carrinho............................................................................................84
Para criar o Add To Cart funcionalidade:..........................................................................................................................84
Criando a interface do usuário do carrinho de compras.....................................................................................86
Recuperando os itens do carrinho de compras...............................................................................................................88
Adicionando produtos ao carrinho de compras...................................................................................................89
Teste do carrinho de compras................................................................................................................................92
Calcular e exibir o Total do pedido........................................................................................................................94
Modificar a exibição de carrinho compras............................................................................................................97
Testar o Total carrinho compras............................................................................................................................99
Adicionando botões de Checkout e atualização para o carrinho de compras................................................100
2
Atualizar e remover itens do carrinho de compras............................................................................................105
Adicionar um contador de carrinho de compras...............................................................................................111
TESTE CONCLUÍDO O CARRINHO DE COMPRAS........................................................................................................................115
RESUMO...................................................................................................................................................................... 116
07 - CHECK-OUT E PAGAMENTO COM PAYPAL...................................................................................................... 117
O QUE VOCÊ VAI APRENDER:............................................................................................................................................117
RASTREAMENTO DE ORDEM DE ADIÇÃO..............................................................................................................................117
Adicionar as classes de modelo Order e OrderDetail........................................................................................118
ADICIONAR O ACESSO DE CHECKOUT.................................................................................................................................121
Adicionar uma pasta de Checkout e páginas.....................................................................................................121
Adicionar um arquivo Web. config......................................................................................................................124
HABILITAR LOGONS DE OUTROS SITES USANDO OAUTH E OPENID..........................................................................................125
Modificar a funcionalidade de Login...................................................................................................................127
MIGRANDO O CARRINHO DE COMPRAS..............................................................................................................................130
Atualizando a conexão de banco de dados........................................................................................................137
INTEGRAÇÃO PAYPAL.....................................................................................................................................................137
Criar contas de teste PaylPal................................................................................................................................137
Adicionar a classe de PayPal e credenciais de API............................................................................................140
Atualizar o número da porta de LocalHost na classe de PayPal......................................................................150
Adicione o botão do PayPal Checkout................................................................................................................151
Envie informações de compra para o PayPal.....................................................................................................152
Detalhes do pedido de revisão.............................................................................................................................154
Concluir compra....................................................................................................................................................160
Segurar cancelar compra......................................................................................................................................164
Manipular erros de compra..................................................................................................................................164
EXECUTANDO O APLICATIVO.............................................................................................................................................165
REVENDO O BANCO DE DADOS......................................................................................................................................... 172
RESUMO...................................................................................................................................................................... 173
RECURSOS ADICIONAIS....................................................................................................................................................173
RESUMO...................................................................................................................................................................... 173
08 - ASSOCIAÇÃO E ADMINISTRAÇÃO................................................................................................................... 175
3
Padrões de URL........................................................................................................................................................201
Mapeamento e registro de rotas............................................................................................................................201
Recuperando e usando dados de rota.................................................................................................................204
Rotas de configuração.............................................................................................................................................204
Habilitar rotas para categorias e produtos..........................................................................................................................204
Adicione código para detalhes do produto..........................................................................................................................207
Executando o aplicativo........................................................................................................................................208
RESUMO.........................................................................................................................................................................208
10 - TRATAMENTO DE ERROS DO ASP.NET............................................................................................................ 209
O QUE VOCÊ VAI APRENDER:............................................................................................................................................209
VISÃO GERAL................................................................................................................................................................ 209
Classe de exceção..................................................................................................................................................209
Hierarquia de herança de exceção......................................................................................................................210
Hierarquia de manipulação de exceção..............................................................................................................210
Manipulação de erro de nível aplicação.............................................................................................................210
Manipulação de eventos de erro de nível de página.........................................................................................211
Código manipulação de erro de nível.................................................................................................................212
ADICIONANDO SUPORTE DE LOG DE ERRO...........................................................................................................................213
Adicionando uma página de erro........................................................................................................................215
Exibindo mensagens de erro do aplicativo.........................................................................................................219
Atualize a configuração....................................................................................................................................................219
Executando o aplicativo....................................................................................................................................................220
Incluindo uma exceção para fins de teste...........................................................................................................220
Executando o aplicativo....................................................................................................................................................221
Adicionando a manipulação de erro de aplicativo-nível..................................................................................222
Executando o aplicativo....................................................................................................................................................223
Adicionando a manipulação de erro de nível de página..................................................................................224
Executando o aplicativo....................................................................................................................................................225
Removendo a exceção usada para testes............................................................................................................226
Adicionando o log de erro de nível de código....................................................................................................226
Inspecionando as informações de log de erro....................................................................................................228
Mensagens de erro seguras..................................................................................................................................229
USANDO O ELMAH.......................................................................................................................................................229
Visualização do Log ELMAH.................................................................................................................................231
RESUMO...................................................................................................................................................................... 232
CONCLUSÃO................................................................................................................................................................. 232
RECURSOS ADICIONAIS....................................................................................................................................................232
AGRADECIMENTOS.........................................................................................................................................................232
CONTRIBUIÇÕES DA COMUNIDADE....................................................................................................................................233
INFORMAÇÕES DO AUTOR................................................................................................................................................233
4
01 - Introdução ao ASP.NET 4.5 Web
Forms e Visual Studio 2013
Introdução
Esta série de tutoriais orienta você através dos passos necessários para criar um aplicativo de
formulários da Web ASP.NET usando o Visual Studio Express 2013 para Web e 4.5 do ASP.NET.
O aplicativo que você vai criar chama-se Wingtip Toys. É um exemplo simplificado de um site de
frente de loja que vende itens on-line. Esta série de tutoriais destaques novos recursos disponíveis
no ASP.NET 4.5.
Comentários são bem-vindos, e nós vamos fazer todos os esforços para atualizar esta série de
tutoriais com base em suas sugestões.
Introdução ao ASP.NET 4.5 Web Forms e Visual Studio 2013 - Wingtip Toys (C#)
Audiência
O público-alvo desta série de tutoriais é formado por desenvolvedores experientes que são
novatos no uso do ASP.NET Web Forms. Um desenvolvedor interessado nesta série tutorial deve
ter as seguintes habilidades:
Se você está interessado em rever as áreas listadas acima, considere-se de revisar o conteúdo a
seguir:
5
Introdução ao Visual c#
Desenvolvimento web, HTML, CSS, JavaScript, SQL, PHP, JQuery
Características do aplicativo
Formulários da Web
Bootstrap
Validação de solicitação
Validação discreta
Roteamento
6
Carregando um arquivo para o aplicativo da web
Visão geral
Se você é novo no ASP.NET Web Forms mas tem familiaridade com conceitos de programação,
você tem o tutorial certo. Se você já está familiarizado com Web Forms do ASP.NET, você pode
beneficiar desta série de tutoriais por novos recursos disponíveis no ASP.NET 4.5. Se você não
estiver familiarizado com formulários da Web ASP.NET e conceitos de programação, consulte os
tutoriais adicionais fornecidos na seção Web Forms Começando no site da Web do ASP.NET.
Os recursos específicos mais recente ASP.NET 4.5 fornecidos nesta série tutorial Web Forms
incluem o seguinte:
Uma interface de usuário simples para criação de projetos que oferecem suporte para
múltiplas estruturas do ASP.NET (Web Forms, MVC e Web API).
Quadro Bootstrap, um layout e temas que fornece recursos de design e temas sensíveis.
Identidade do ASP.NET, um novo sistema de associação do ASP.NET que funciona da
mesma maneira em todos os quadros ASP.NET e trabalha com web hosting software diferente
do IIS.
6 estrutura de entidade, uma atualização para o Entity Framework que permite que você
recuperar e manipular dados como objetos com rigidez de tipos, acesso a dados assíncronos,
lidar com falhas de conexão transitória e instruções SQL de log.
Para uma lista completa dos recursos do ASP.NET 4.5, consulte ASP.NET e Web Tools para Visual
Studio 2013 notas de lançamento.
As capturas de tela a seguir fornecem uma visão rápida do aplicativo ASP.NET Web formulários
que você irá criar nesta série tutorial. Quando você executar o aplicativo do Visual Studio Express
2013 para Web, você verá a seguinte página da web em casa.
7
Você pode se registrar como um novo usuário, ou login como um usuário existente. Navegação é
fornecida no topo de cada categoria de produto, recuperando os produtos disponíveis no banco
de dados.
Selecionando o link de produtos, você poderá ver uma lista de todos os produtos disponíveis.
Você também pode ver detalhes do produto individual, selecionando qualquer um dos produtos
listados.
8
Como um usuário, você pode registrar e faça o login usando a funcionalidade padrão do modelo
de Web Forms. Este tutorial também explica como fazer o login usando uma conta existente do
Gmail. Além disso, você pode logar como o administrador adicionar e remover produtos do banco
de dados.
Uma vez que você tiver conectado como um usuário, você pode adicionar produtos ao carrinho de
compras e checkout com PayPal. Observe que esse aplicativo de exemplo é projetado para
funcionar com o sandbox de desenvolvedores do PayPal. Nenhuma transação de dinheiro real terá
lugar.
9
PayPal vai confirmar sua conta, ordem e informações de pagamento.
Microsoft Visual Studio 2013 ou Microsoft Visual Studio Express 2013 para Web . O .NET
Framework é instalado automaticamente.
Esta série de tutoriais usa o Microsoft Visual Studio Express 2013 para Web. Você pode usar o
Microsoft Visual Studio Express 2013 para Web ou Microsoft Visual Studio 2013 para completar
esta série de tutoriais.
Nota
Microsoft Visual Studio 2013 e Microsoft Visual Studio Express 2013 para Web serão muitas vezes
referido como o Visual Studio em toda esta série de tutoriais.
Se você já tem uma versão do Visual Studio instalada, o processo de instalação irá instalar Visual
Studio 2013 ou Microsoft Visual Studio Express 2013 para Web ao lado a versão existente. Sites
que você criou em versões anteriores podem ser abertos no Visual Studio 2013 e continuam a abrir
em versões anteriores.
Nota
Esta explicação passo a passo presume que você selecionou a coleção de configurações de
Desenvolvimento Web a primeira vez que você começou a Visual Studio. Para obter mais
informações, consulte como: selecionar configurações de ambiente de desenvolvimento Web .
O download é um arquivo . zip . Para ver o projeto concluído que cria esta série de tutoriais,
localize e selecione a pasta C# no arquivo . zip . Salve a pasta de C# para a pasta que você usar
para trabalhar com projetos de Visual Studio de 2013. Por padrão, a pasta de projetos do Visual
Studio de 2013 é o seguinte:
Nota
Se você já tiver uma pasta chamada WingtipToys na sua pasta de projetos, temporariamente
renomear essa pasta existente antes de renomear a pasta c# para WingtipToys.
Para executar o projeto concluído, abra a pasta WingtipToys e clique duas vezes no arquivo
WingtipToys.sln . Visual Studio 2013 irá abrir o projeto. Em seguida, clique no arquivo aspx na
janela Solution Explorer e clique em Exibir no navegador no menu de atalhos.
Comentários sobre esta série de tutoriais são bem-vindos, e quando esta série de tutoriais é
atualizado todo esforço será feito para levar em conta correções ou sugestões de melhorias que
são fornecidas nos comentários tutorial.
12
13
02 - Criar o projeto
Neste tutorial você vai criar, revisar e executar o projeto padrão no Visual Studio, que permitirá que
você se familiarize com os recursos do ASP.NET. Além disso, você revisará o ambiente do Visual
Studio.
Criando o projeto
1. Abra o Visual Studio.
14
Nota O nome do projeto nesta série tutorial é WingtipToys. É recomendável que você use esse
nome exato do projeto para que o código fornecido ao longo da série tutorial funções conforme o
esperado.
15
O projeto levará um breve período de tempo para ser criado. Quando estiver pronto, abra a página
Default. aspx .
Você pode alternar entre o modo de exibição Design e exibição da fonte , selecionando uma
opção na parte inferior da janela do centro. O modo design exibe páginas da Web ASP.NET,
páginas mestras, páginas de conteúdo, páginas HTML e controles de usuário usando um modo de
exibição próximo a WYSIWYG. Fonte exibe a marcação HTML para sua página Web, que você pode
editar.
ASP.NET MVC
ASP.NET MVC alvo são os desenvolvedores que estão interessados em padrões e princípios como
o desenvolvimento orientado a testes, separação de preocupações, inversão de controle (IoC) e
injeção de dependência (DI). Este quadro incentiva separando a camada de lógica de negócios de
uma aplicação web de sua camada de apresentação.
Além dos quatro quadros de desenvolvimento principal, o ASP.NET também oferece tecnologias
adicionais que são importantes para estar ciente e familiarizado com, mas não são abordadas nesta
série tutorial:
ASP.NET Web API – um framework para construção de serviços HTTP que alcançam uma
ampla gama de clientes, incluindo os navegadores e dispositivos móveis.
ASP.NET SignalR - uma biblioteca que facilita a funcionalidade em desenvolvimento de web
em tempo real.
Revisão do projeto
No Visual Studio, a janela Solution Explorer permite que você gerencie arquivos para o projeto.
Vamos dar uma olhada nas pastas que foram adicionados ao seu aplicativo em Gerenciador de
soluções. O modelo de aplicativo da web adiciona uma estrutura de pasta básica:
17
O Visual Studio cria alguns arquivos e pastas iniciais para seu projeto. Os primeiros arquivos com
os quais você trabalhará mais adiante neste tutorial são os seguintes:
Arquivo Finalidade
Site. Uma página que permite criar um layout consistente e usar um comportamento padrão
Master nas páginas do seu aplicativo.
Global. Um arquivo opcional que contém código para responder a eventos de nível de
asax aplicativo e sessão-nível gerados pelo ASP.NET ou por módulos HTTP.
18
config
O aplicativo da Web padrão fornece uma rica experiência baseada na funcionalidade incorporada e
suporte. Sem qualquer alteração de projeto de formulários da Web padrão, o aplicativo está
pronto para ser executado no navegador da Web local.
Existem três principais páginas neste aplicativo da Web padrão: Default. aspx (Home), about. aspxe
Contact.aspx. Cada uma dessas páginas pode ser alcançada a partir da barra de navegação
superior. Há também duas páginas adicionais contidas na pasta de conta, a página Register. aspx e
a página login. aspx. Estas duas páginas permitem que você use os recursos de associação do
ASP.NET para criar, armazenar e validar as credenciais do usuário.
Quando uma página de Web Forms do ASP.NET é executado, a página passa por um ciclo de vida
em que ele executa uma série de etapas de processamento. Estas etapas incluem inicialização,
instanciando controles, restaurar e manter o estado, executando o código manipulador de eventos
e renderização. Como você se familiarizar com o poder da Web Forms do ASP.NET, é importante
para você entender o ciclo de vida de página do ASP.NET que você pode escrever o código no
estágio do ciclo de vida apropriado para o efeito que pretende.
Quando um servidor Web recebe uma solicitação para uma página, ele localiza a página, processa-
a, envia-a ao navegador e, em seguida, descarta todas as informações da página. Se o usuário
solicitar a mesma página novamente, o servidor repetirá a sequência inteira, reprocessando a
página do zero. Dito de outra forma, um servidor não tem memória das páginas que ele tenha
processado — páginas são apátridas. A estrutura da página ASP.NET automaticamente manipula a
tarefa de manter o estado da sua página e seus controles, e que lhe fornece maneiras explícitas
para manter o estado de informações específicas do aplicativo.
Associação
ASP.NETIdentidade armazena as credenciais dos usuários em um banco de dados criado pelo
aplicativo. Quando os usuários efetuar login, o aplicativo valida suas credenciais através da leitura
do banco de dados. A pasta Account do seu projeto contém os arquivos que implementam as
várias partes da associação: registro, logon, alteração de uma senha e autorização de acesso. Além
disso, o ASP.NET Web Forms oferece suporte a OAuth e OpenID. Esses aprimoramentos de
autenticação permitem que os usuários façam logon no seu site usando credenciais existentes, de
contas como Facebook, Twitter, Windows Live e Google.
20
Por padrão, o modelo cria um banco de dados de associação usando um nome de banco de dados
padrão em uma instância do SQL Server Express LocalDB, o servidor de banco de dados de
desenvolvimento que vem com o Visual Studio Express 2013 para Web.
21
Express LocalDB permite que recursos como procedimentos armazenados, funções definidas pelo
usuário e agregados, integração do .NET Framework, tipos espaciais e outros que não estão
disponíveis no SQL Server Compact.
Páginas mestras
Uma página mestra ASP.NET define uma aparência consistente e comportamento para todas as
páginas em seu aplicativo. O layout da página mestra funde-se com o conteúdo de uma página de
conteúdo individual para produzir a última página que o usuário vê. No aplicativo Wingtip Toys,
você modifica a página mestra Site.Master para que todas as páginas no site do Wingtip Toys
compartilhem o mesmo logotipo distintivo e a barra de navegação.
HTML5
O modelo de aplicativo de formulários da Web ASP.NET suporta HTML5, que é a mais recente
versão da linguagem de marcação HTML. HTML5 oferece suporte a novos elementos e
funcionalidades que tornam mais fácil criar sites da Web.
Modernizr
Para navegadores que não oferecem suporte a HTML5, você pode usar o Modernizr. Modernizr é
uma biblioteca JavaScript open source que pode detectar se um navegador suporta recursos de
HTML5 e habilitá-los, se isso não acontecer. No modelo de aplicativo de formulários da Web do
ASP.NET, o Modernizr é instalado como um pacote NuGet.
Bootstrap
Os modelos de projeto Visual Studio 2013 usam Bootstrap, um layout e temas quadro criado pelo
Twitter. Bootstrap usa CSS3 para fornecer design responsivo, que significa layouts dinamicamente
podem adaptar-se aos tamanhos de janela de navegador diferente. Você também pode usar o
recurso de temas do Bootstrap para facilmente efetuar uma mudança na aparência do aplicativo.
Por padrão, o modelo de aplicativo da Web do ASP.NET no Visual Studio 2013 inclui Bootstrap
como um pacote NuGet.
Pacotes NuGet
O modelo de aplicativo de formulários da Web ASP.NET inclui um conjunto de pacotes NuGet .
Esses pacotes oferecem funcionalidade modular na forma de bibliotecas de código aberto e
ferramentas. Há uma grande variedade de pacotes para ajudá-lo a criar e testar seus aplicativos.
Visual Studio torna fácil adicionar, remover e atualizar pacotes NuGet. Os desenvolvedores podem
criar e adicionar pacotes NuGet também.
22
Quando você instala um pacote, o NuGet copia arquivos para sua solução e automaticamente faz
com que as mudanças são necessárias, tais como adicionar referências e mudando você tem a
configuração associada com seu aplicativo da Web. Se você decidir remover a biblioteca, o NuGet
remove arquivos e reverte as mudanças que fez em seu projeto para que a desordem não é
deixada. NuGet está disponível no menu ferramentas no Visual Studio.
jQuery
jQuery é uma biblioteca JavaScript rápida e concisa que simplifica o HTML documento
atravessando, manipulação de eventos, animação e interações Ajax para desenvolvimento web
rápido. A biblioteca JavaScript jQuery é incluída no modelo de aplicativo de formulários da Web do
ASP.NET como um pacote NuGet.
Validação discreta
Controles de validação interna foram configurados para usar JavaScript discreta para a lógica de
validação do lado do cliente. Isso significativamente reduz a quantidade de JavaScript processado
embutido na marcação da página e reduz o tamanho total da página. Discreta validação é
adicionada globalmente para o modelo de aplicativo de formulários da Web do ASP.NET com base
na configuração no elemento < appSettings > do arquivo Web. config na raiz do aplicativo.
23
que você se concentrar na lógica de negócios em seu aplicativo, em vez dos detalhes de como os
dados são acessados.
Para obter informações adicionais sobre as bibliotecas instaladas e os pacotes incluídos com o
modelo de Web Forms do ASP.NET, consulte a lista de pacotes NuGet instalados. Para fazer isso,
no Visual Studio cria um novo projeto de formulários da Web, selecione ferramentas ->
Gerenciador de pacotes da biblioteca -> Gerenciar pacotes de NuGet para soluçãoe selecione
pacotes instalados na caixa de diálogo Gerenciar pacotes de NuGet .
Para obter mais informações sobre Visual Studio, consulte Guia Visual de Visual Web Developer.
Resumo
Neste tutorial você criou, revisto e executar o aplicativo de formulários da Web padrão. Você tem
analisado as características diferentes do aplicativo de formulários da Web padrão e aprendeu
algumas noções básicas sobre como usar o ambiente Visual Studio. Nos seguintes tutoriais você
vai criar a camada de acesso de dados.
24
03 - Criar a camada de acesso a dados
Este tutorial descreve como criar, acessar e analisar dados de um banco de dados usando Web
Forms do ASP.NET e Entity Framework Code First. Este tutorial baseia-se no tutorial anterior "Criar
o projeto" e faz parte da série tutorial Wingtip Toy Store. Quando tiver completado este tutorial,
você vai ter construído um grupo de classes de acesso a dados que estão na pasta de modelos do
projeto.
LocalDB
Anotações de dados
Você começará criando as classes de entidade que definem os modelos de dados para o aplicativo
de formulários da Web. Em seguida, você criará uma classe de contexto que gerencia as classes de
entidade e fornece acesso a dados no banco de dados. Você também criará uma classe de
inicializador que você usará para preencher o banco de dados.
25
Referências e entity Framework
Por padrão, o Entity Framework está incluído quando você criar um novo aplicativo da Web
ASP.NET usando o modelo de Web Forms . Entity Framework pode ser instalado, desinstalado e
atualizado como um pacote NuGet.
Este pacote NuGet inclui os seguintes módulos de tempo de execução dentro de seu projeto:
Classes de entidade
As classes que você cria para definir o esquema dos dados são chamadas de classes de entidade.
Se você é novo para o projeto de banco de dados, pense as classes de entidade, como definições
de tabela de um banco de dados. Cada propriedade da classe especifica uma coluna na tabela do
banco de dados. Essas classes fornecem uma interface leve, objeto-relacional entre código
orientado a objeto e a estrutura de tabela relacional de banco de dados.
Neste tutorial, você vai começar adicionando classes de entidade simples que representam os
esquemas para produtos e categorias. A classe de produtos irá conter as definições para cada
produto. O nome de cada um dos membros da classe de produto será ProductID, ProductName,
Description, ImagePath, UnitPrice, CategoryIDe Category. A classe de categoria irá conter as
definições para cada categoria de um produto pode pertencer, como carro, barco ou avião. O
nome de cada um dos membros da classe de categoria será CategoryID, CategoryName,
Descriptione Products. Cada produto pertence a uma das categorias. Essas classes de entidade
serão adicionados à pasta de modelos do projeto existente.
26
Caixa de diálogo Add New Item é exibida.
27
3. Selecione classe do painel do meio e o nome desta nova classe Product.cs.
4. Clique em Adicionar.
O novo arquivo de classe é exibido no editor.
using System.ComponentModel.DataAnnotations;
namespace WingtipToys.Models
{
public class Product
{
[ScaffoldColumn(false)]
public int ProductID { get; set; }
[Display(Name = "Price")]
public double? UnitPrice { get; set; }
6. Criar outra classe, repetindo as etapas 1 a 4, no entanto, o nome da nova classe Category.cs
e substitua o código padrão com o seguinte código:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace WingtipToys.Models
{
public class Category
{
28
[ScaffoldColumn(false)]
public int CategoryID { get; set; }
Como mencionado anteriormente, a Category classe representa o tipo de produto que o aplicativo
é projetado para vender (tais como "Carros", "Barcos", "Foguetes" e assim por diante), e a classe de
Product representa os produtos individuais (brinquedos) no banco de dados. Cada instância de um
objeto Product corresponderá a uma linha dentro de uma tabela de banco de dados relacional, e
cada propriedade da classe de produto serão mapeados para uma coluna na tabela de banco de
dados relacional. No final deste tutorial, você vai analisar os dados do produto contidos no banco
de dados.
Anotações de dados
Você deve ter notado que alguns membros das classes têm atributos especificando detalhes sobre
o membro, como [ScaffoldColumn(false)]. Estas são anotações de dados. Os atributos de
anotação de dados podem descrever como validar entrada do usuário para esse membro, para
especificar a formatação para ele e para especificar como ele é modelado quando o banco de
dados é criado.
Classe de contexto
Para começar a usar as classes para acesso a dados, você deve definir uma classe de contexto.
Como mencionado anteriormente, a classe de contexto gerencia as classes de entidade (por
exemplo, a classe de Product e a classe de Category ) e fornece acesso a dados no banco de dados.
Esse procedimento adiciona uma nova classe de contexto c# para a pasta de modelos .
1. Clique com o botão direito do mouse na pasta Models e, em seguida, selecione Add ->
New Item.
Caixa de diálogo Add New Item é exibida.
using System.Data.Entity;
29
namespace WingtipToys.Models
{
public class ProductContext : DbContext
{
public ProductContext() : base("WingtipToys")
{
}
public DbSet<Category> Categories { get; set; }
public DbSet<Product> Products { get; set; }
}
Este código adiciona o namespace System.Data.Entity para que você tenha acesso a todas as
funcionalidades do núcleo do Entity Framework, que inclui a capacidade de consultar, inserir,
atualizar e excluir dados ao trabalhar com objetos com rigidez de tipos.
Classe de inicializador
Você precisará executar alguma lógica personalizada para inicializar o banco de dados na primeira
vez em que o contexto for usado. Isso permitirá que dados de semente a ser adicionado ao banco
de dados para que você possa exibir imediatamente produtos e categorias.
Esse procedimento adiciona uma nova classe de inicializador c# para a pasta de modelos .
using System.Collections.Generic;
using System.Data.Entity;
namespace WingtipToys.Models
{
public class ProductDatabaseInitializer :
DropCreateDatabaseIfModelChanges<ProductContext>
{
protected override void Seed(ProductContext context)
{
GetCategories().ForEach(c => context.Categories.Add(c));
GetProducts().ForEach(p => context.Products.Add(p));
}
30
private static List<Category> GetCategories()
{
var categories = new List<Category> {
new Category
{
CategoryID = 1,
CategoryName = "Cars"
},
new Category
{
CategoryID = 2,
CategoryName = "Planes"
},
new Category
{
CategoryID = 3,
CategoryName = "Trucks"
},
new Category
{
CategoryID = 4,
CategoryName = "Boats"
},
new Category
{
CategoryID = 5,
CategoryName = "Rockets"
},
};
return categories;
}
31
Description = "There's nothing old about this toy car, except it's
looks. Compatible with other old toy cars.",
ImagePath="carearly.png",
UnitPrice = 15.95,
CategoryID = 1
},
new Product
{
ProductID = 3,
ProductName = "Fast Car",
Description = "Yes this car is fast, but it also floats in
water.",
ImagePath="carfast.png",
UnitPrice = 32.99,
CategoryID = 1
},
new Product
{
ProductID = 4,
ProductName = "Super Fast Car",
Description = "Use this super fast car to entertain guests. Lights
and doors work!",
ImagePath="carfaster.png",
UnitPrice = 8.95,
CategoryID = 1
},
new Product
{
ProductID = 5,
ProductName = "Old Style Racer",
Description = "This old style racer can fly (with user
assistance). Gravity controls flight duration." +
"No batteries required.",
ImagePath="carracer.png",
UnitPrice = 34.95,
CategoryID = 1
},
new Product
{
ProductID = 6,
ProductName = "Ace Plane",
Description = "Authentic airplane toy. Features realistic color
and details.",
ImagePath="planeace.png",
UnitPrice = 95.00,
CategoryID = 2
},
new Product
{
ProductID = 7,
ProductName = "Glider",
Description = "This fun glider is made from real balsa wood. Some
assembly required.",
32
ImagePath="planeglider.png",
UnitPrice = 4.95,
CategoryID = 2
},
new Product
{
ProductID = 8,
ProductName = "Paper Plane",
Description = "This paper plane is like no other paper plane. Some
folding required.",
ImagePath="planepaper.png",
UnitPrice = 2.95,
CategoryID = 2
},
new Product
{
ProductID = 9,
ProductName = "Propeller Plane",
Description = "Rubber band powered plane features two wheels.",
ImagePath="planeprop.png",
UnitPrice = 32.95,
CategoryID = 2
},
new Product
{
ProductID = 10,
ProductName = "Early Truck",
Description = "This toy truck has a real gas powered engine.
Requires regular tune ups.",
ImagePath="truckearly.png",
UnitPrice = 15.00,
CategoryID = 3
},
new Product
{
ProductID = 11,
ProductName = "Fire Truck",
Description = "You will have endless fun with this one quarter
sized fire truck.",
ImagePath="truckfire.png",
UnitPrice = 26.00,
CategoryID = 3
},
new Product
{
ProductID = 12,
ProductName = "Big Truck",
Description = "This fun toy truck can be used to tow other trucks
that are not as big.",
ImagePath="truckbig.png",
UnitPrice = 29.00,
CategoryID = 3
33
},
new Product
{
ProductID = 13,
ProductName = "Big Ship",
Description = "Is it a boat or a ship. Let this floating vehicle
decide by using its " +
"artifically intelligent computer brain!",
ImagePath="boatbig.png",
UnitPrice = 95.00,
CategoryID = 4
},
new Product
{
ProductID = 14,
ProductName = "Paper Boat",
Description = "Floating fun for all! This toy boat can be
assembled in seconds. Floats for minutes!" +
"Some folding required.",
ImagePath="boatpaper.png",
UnitPrice = 4.95,
CategoryID = 4
},
new Product
{
ProductID = 15,
ProductName = "Sail Boat",
Description = "Put this fun toy sail boat in the water and let it
go!",
ImagePath="boatsail.png",
UnitPrice = 42.95,
CategoryID = 4
},
new Product
{
ProductID = 16,
ProductName = "Rocket",
Description = "This fun rocket will travel up to a height of 200
feet.",
ImagePath="rocket.png",
UnitPrice = 122.95,
CategoryID = 5
}
};
return products;
}
}
34
Como você pode ver o código acima, quando o banco de dados é criado e inicializado, a
propriedade de Seed é substituída e definida. Quando a Seed for definida, os valores das categorias
e produtos são usados para preencher o banco de dados. Se você tentar atualizar os dados de
semente, modificando o código acima depois que foi criado o banco de dados, você não verá
nenhuma atualização quando você executar o aplicativo da Web. A razão é que o código acima usa
uma implementação da classe DropCreateDatabaseIfModelChanges para reconhecer se o modelo
(esquema) foi alterado antes de redefinir os dados de sementes. Se nenhuma alteração será feita
para as classes de entidade Category e Product , o banco de dados não serão ser reinicializado
com os dados da semente.
Nota
Se você quisesse o banco de dados para ser recriada a cada vez que você executou o aplicativo,
você pode usar a classe DropCreateDatabaseAlways em vez da classe
DropCreateDatabaseIfModelChanges . No entanto, para esta série de tutoriais, use a classe
DropCreateDatabaseIfModelChanges .
Neste momento, neste tutorial, você terá uma pasta de modelos com quatro novas classes e um
classe de padrão:
35
Configurando o aplicativo para usar o modelo de dados
Agora que você criou as classes que representam os dados, você deve configurar o aplicativo para
usar as classes. No arquivo global.asax, adicione o código que inicializa o modelo. No arquivo
Web.config, você adiciona informações que dizem ao aplicativo qual banco de dados você usará
para armazenar os dados que são representados pelas novas classes de dados. O arquivo global
asax pode ser usado para manipular eventos de aplicativo ou métodos. O arquivo Web. config
permite que você controle a configuração do seu aplicativo da web ASP.NET.
36
Nota
No Solution Explorer, você pode selecionar o arquivo global asax ou o arquivo Global.asax.cs para
editar o arquivo Global.asax.cs .
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Optimization;
using System.Web.Routing;
using System.Web.Security;
using System.Web.SessionState;
using System.Data.Entity;
using WingtipToys.Models;
namespace WingtipToys
{
public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
Nota
Seu navegador deve suportar HTML5 para exibir o código destacado em amarelo, ao ver esta série
de tutoriais em um navegador.
Conforme mostrado no código acima, quando o aplicativo for iniciado, o aplicativo especifica o
inicializador que será executado durante a primeira vez que os dados é acessado. Os dois
namespaces adicionais são necessários para acessar o objeto de Database e o objeto de
ProductDatabaseInitializer .
37
Embora o Entity Framework Code First gere um banco de dados para você em um local padrão
quando o banco de dados é populado com dados de semente, adicionar suas próprias
informações de conexão para seu aplicativo proporciona controle do local do banco de dados.
Você especifica esta conexão de banco de dados usando uma cadeia de conexão no arquivo
Web.config do aplicativo na raiz do projeto. Adicionando uma nova seqüência de conexão, você
pode direcionar a localização do banco de dados (wingtiptoys.mdf) a ser criado no diretório de
dados do aplicativo (App_Data), ao invés de seu local padrão. Fazer essa alteração permitirá que
você encontrar e inspecionar o arquivo de banco de dados no final deste tutorial.
<connectionStrings>
<add name="DefaultConnection" connectionString="Data
Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-WingtipToys-
20131119102907.mdf;Initial Catalog=aspnet-WingtipToys-20131119102907;Integrated
Security=True"
providerName="System.Data.SqlClient" />
<add name="WingtipToys"
connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|
DataDirectory|\wingtiptoys.mdf;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
Quando o aplicativo é executado pela primeira vez, vai construir o banco de dados no local
especificado pela cadeia de conexão. Mas antes de executar o aplicativo, vamos construí-lo
primeiro.
Criando o aplicativo
Para ter certeza de que todas as classes e as alterações ao seu trabalho de aplicativo da Web, você
deve compilar o aplicativo.
38
Se você topar com um erro, verifique novamente os passos acima. As informações na janela de
saída irão indicar que o arquivo tem um problema e onde no arquivo uma mudança é necessária.
Esta informação permitirá que você determinar que parte das etapas acima precisam ser revisto e
corrigido em seu projeto.
Resumo
Neste tutorial da série você criou o modelo de dados, bem como adicionou o código que será
usado para inicializar e propagar o banco de dados. Você também configurou o aplicativo para
usar os modelos de dados quando o aplicativo é executado.
No próximo tutorial, você vai atualizar a interface do usuário, Adicionar navegação e recuperar
dados do banco de dados. Isso resultará no banco de dados a ser criado automaticamente com
base nas classes de entidade que você criou neste tutorial.
39
04 - Interface do usuário e navegação
Neste tutorial, você irá modificar a interface do usuário do aplicativo da Web padrão para suporte
a recursos do aplicativo front loja Wingtip Toys. Além disso, você irá adicionar simples e dados
ligados a navegação. Este tutorial baseia-se no tutorial anterior "Criar a camada de acesso dados" e
é parte da série tutorial Wingtip Toys.
Como criar um controle orientado a dados para navegar para dados específicos do
produto.
Como exibir dados de um banco de dados criado usando o Entity Framework Code First.
Web Forms do ASP.NET permitem que você criar conteúdo dinâmico para seu aplicativo da Web.
Cada página da Web do ASP.NET é criada de uma forma semelhante a uma página de Web de
HTML estática (uma página que não inclui processamento baseado em servidor), mas a página da
Web ASP.NET inclui elementos extras que ASP.NET reconhece e processa para gerar HTML quando
a página é executada.
Com uma página HTML estática (arquivo. htm ou . html ), o servidor atende a uma solicitação Web
por ler o arquivo e enviá-la como-é para o navegador. Em contraste, quando alguém solicita uma
página da Web do ASP.NET (arquivo.aspx ), a página é executado como um programa no servidor
Web. Enquanto a página é executada, ela pode realizar qualquer tarefa que seu site requeira,
incluindo cálculo de valores, leitura ou gravação de informações de banco de dados ou chamada a
outros programas. Como sua saída, a página dinamicamente produz marcação (como elementos
em HTML) e envia essa dinâmica de saída para o navegador.
40
3. Na parte superior da página na Directiva @Page , altere o atributo Title para "Welcome",
conforme destacado em amarelo abaixo.
4. Também na página Default. aspx , substitua todo o conteúdo de padrão contido na tag
<asp:Content> para que a marcação aparece como abaixo.
</asp:Content>
5. Salve a página Default. aspx , selecionando menu arquivo Salvar padrão. aspx .
</asp:Content>
No exemplo, você definiu o atributo Title da diretiva @Page. Quando o HTML é exibido em um
navegador, o código de servidor <%: Page.Title %> resolve para o conteúdo contido no atributo
de Title .
A página de exemplo inclui os elementos básicos que constituem uma página da Web do ASP.NET.
A página contém texto estático como você poderia ter em uma página HTML, além de elementos
que são específicos ao ASP.NET. O conteúdo contido na página Default. aspx será integrado com o
conteúdo de página mestra, que vai ser explicado mais adiante neste tutorial.
@Page Directiva
Web Forms do ASP.NET geralmente contêm diretivas que permitem que você especifique
informações de propriedades e configuração de página para a página. As diretivas são usadas pelo
41
ASP.NET como instruções para saber como processar a página, mas elas não são renderizadas
como parte da marcação que é enviada ao navegador.
A diretiva usada com mais frequência é a diretiva @Page, que permite que você especifique várias
opções de configuração para a página, incluindo o seguinte:
Se você não incluir uma diretiva @Page na página, ou se a diretiva não incluir uma configuração
específica, a configuração será herdada do arquivo de configuração Web. config ou do arquivo de
configuração Machine. config. O arquivo Machine config fornece configurações adicionais para
todas as aplicações rodando em uma máquina.
Nota
Na maioria das aplicações ASP.NET Web Forms, você irá adicionar controles que permitem que o
usuário interaja com a página, tais como botões, caixas de texto, listas e assim por diante. Esses
controles de servidor Web são semelhantes aos botões HTML e elementos de entrada. No entanto,
eles são processados no servidor, permitindo que você use o código do servidor para definir suas
propriedades. Esses controles também elevar eventos que você pode manipular no código do
servidor.
Controles de servidor usam uma sintaxe especial que ASP.NET reconhece quando a página é
executada. O nome de marca para controles de servidor ASP.NET começa com um prefixo asp:.
Isso permite ao ASP.NET reconhecer e processar esses controles do servidor. O prefixo pode ser
diferente se o controle não é parte do .NET Framework. Para além da asp: prefixo, controles de
servidor ASP.NET também incluem o runat="server" atributo e um ID que você pode usar para
referenciar o controle no código do servidor.
Código do servidor
42
A maioria dos aplicativos de formulários da Web ASP.NET incluir o código que é executado no
servidor quando a página é processada. Como mencionado acima, o código do servidor pode ser
usado para fazer uma variedade de coisas, como adicionar dados a um controle ListView. ASP.NET
oferece suporte a vários idiomas para executar no servidor, incluindo c#, Visual Basic, j# e outros.
ASP.NET suporta dois modelos para escrever código de servidor para uma página da Web. No
modelo de arquivo único, o código para a página está em um script elemento onde a tag de
abertura inclui o runat="server" atributo. Como alternativa, você pode criar o código para a
página em um arquivo de classe separado, que é conhecido como o modelo code-behind. Neste
caso, a página de Web Forms do ASP.NET geralmente não contém nenhum código de servidor. Em
vez disso, a directiva @Page inclui informações que vincula a página. aspx com seu arquivo code-
behind associado.
O atributo CodeBehind contido na Directiva @Page especifica o nome do arquivo de classe separado,
e o atributo Inherits especifica o nome da classe no arquivo code-behind que corresponde à
página.
No Web Forms do ASP.NET, páginas mestras permitem que você crie um layout consistente para as
páginas em seu aplicativo. Uma única página mestra define a aparência e comportamento padrão
que você deseja para todas as páginas (ou um grupo de páginas) em seu aplicativo. Você pode
criar páginas de conteúdo individuais que contêm o conteúdo que você deseja exibir, como
explicado acima. Quando os usuários solicitam as páginas de conteúdo, o ASP.NET mescla-as com
a página mestra para gerar uma saída que combine o layout da página mestra com o conteúdo da
página de conteúdo.
O novo site precisa de um logotipo único para exibir em cada página. Para adicionar este logotipo,
você pode modificar o HTML na página mestra.
2. Se a página estiver no modo de exibição Design , alterne para modo de exibição fonte .
<!DOCTYPE html>
<html lang="en">
<head runat="server">
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%: Page.Title %> - Wingtip Toys</title>
43
<asp:PlaceHolder runat="server">
<%: Scripts.Render("~/bundles/modernizr") %>
</asp:PlaceHolder>
<webopt:bundlereference runat="server" path="~/Content/css" />
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
</head>
<body>
<form runat="server">
<asp:ScriptManager runat="server">
<Scripts>
<%--To learn more about bundling scripts in ScriptManager see
http://go.microsoft.com/fwlink/?LinkID=301884 --%>
<%--Framework Scripts--%>
<asp:ScriptReference Name="MsAjaxBundle" />
<asp:ScriptReference Name="jquery" />
<asp:ScriptReference Name="bootstrap" />
<asp:ScriptReference Name="respond" />
<asp:ScriptReference Name="WebForms.js" Assembly="System.Web"
Path="~/Scripts/WebForms/WebForms.js" />
<asp:ScriptReference Name="WebUIValidation.js" Assembly="System.Web"
Path="~/Scripts/WebForms/WebUIValidation.js" />
<asp:ScriptReference Name="MenuStandards.js" Assembly="System.Web"
Path="~/Scripts/WebForms/MenuStandards.js" />
<asp:ScriptReference Name="GridView.js" Assembly="System.Web"
Path="~/Scripts/WebForms/GridView.js" />
<asp:ScriptReference Name="DetailsView.js" Assembly="System.Web"
Path="~/Scripts/WebForms/DetailsView.js" />
<asp:ScriptReference Name="TreeView.js" Assembly="System.Web"
Path="~/Scripts/WebForms/TreeView.js" />
<asp:ScriptReference Name="WebParts.js" Assembly="System.Web"
Path="~/Scripts/WebForms/WebParts.js" />
<asp:ScriptReference Name="Focus.js" Assembly="System.Web"
Path="~/Scripts/WebForms/Focus.js" />
<asp:ScriptReference Name="WebFormsBundle" />
<%--Site Scripts--%>
</Scripts>
</asp:ScriptManager>
44
<li><a runat="server" href="~/">Home</a></li>
<li><a runat="server" href="~/About">About</a></li>
<li><a runat="server" href="~/Contact">Contact</a></li>
</ul>
<asp:LoginView runat="server" ViewStateMode="Disabled">
<AnonymousTemplate>
<ul class="nav navbar-nav navbar-right">
<li><a runat="server"
href="~/Account/Register">Register</a></li>
<li><a runat="server" href="~/Account/Login">Log
in</a></li>
</ul>
</AnonymousTemplate>
<LoggedInTemplate>
<ul class="nav navbar-nav navbar-right">
<li><a runat="server" href="~/Account/Manage"
title="Manage your account">Hello, <%: Context.User.Identity.GetUserName() %> !
</a></li>
<li>
<asp:LoginStatus runat="server"
LogoutAction="Redirect" LogoutText="Log off" LogoutPageUrl="~/"
OnLoggingOut="Unnamed_LoggingOut" />
</li>
</ul>
</LoggedInTemplate>
</asp:LoginView>
</div>
</div>
</div>
<div id="TitleContent" style="text-align: center">
<a runat="server" href="~/">
<asp:Image ID="Image1" runat="server" ImageUrl="~/Images/logo.jpg"
BorderStyle="None" />
</a>
<br />
</div>
<div class="container body-content">
<asp:ContentPlaceHolder ID="MainContent" runat="server">
</asp:ContentPlaceHolder>
<hr />
<footer>
<p>© <%: DateTime.Now.Year %> - Wingtip Toys</p>
</footer>
</div>
</form>
</body>
</html>
Este HTML irá exibir a imagem chamada logo. jpg da pasta imagens do aplicativo da Web, o que
você vai adicionar mais tarde. Quando uma página que usa a página mestra é exibida em um
45
navegador, o logotipo será exibido. Se um usuário clica no logotipo, o usuário irá navegar de volta
para a página Default. aspx . A marca de âncora HTML <a> envolve o controle de servidor de
imagem e permite que a imagem seja incluída como parte do link. O atributo href para a marca de
âncora especifica a raiz " ~/" do site da Web como o local de ligação. Por padrão, a página Default.
aspx é exibida quando o usuário navega para a raiz do site. O controle de servidor <asp:Image>
imagem inclui propriedades de adição, como BorderStyle, que processam como HTML quando
exibido em um navegador.
Páginas mestras
Uma página mestra é um arquivo do ASP.NET com a extensão .master (por exemplo, site.Master)
com um layout predefinido que pode incluir texto estático, elementos HTML e controles de
servidor. A página mestra é identificada por uma diretiva especial @Master que substitui a diretiva
@Page que é usada para páginas . aspx comuns.
Além da diretiva @Master , a página mestra também contém todos os elementos HTML de nível
superior de uma página, como html, head e form. Por exemplo, na página mestra que você
adicionou acima, você usou um table HTML para o layout, um elemento img para o logotipo da
empresa, texto estático e controles de servidor para manipular a associação comum para seu site.
Você pode usar qualquer HTML e quaisquer elementos do ASP.NET como parte de sua página
mestra.
Além de texto estático e controles que serão exibidos em todas as páginas, a página mestra
também inclui um ou mais controles ContentPlaceHolder . Esses controles de espaço reservado
definem regiões onde aparecerá conteúdo substituível. Por sua vez, o conteúdo substituível é
definido em páginas de conteúdo, tais como Default. aspx, usando o controle de servidor de
conteúdo .
A imagem do logotipo referenciado acima, juntamente com todas as imagens de produto, deve ser
adicionada para o aplicativo da Web para que eles podem ser vistos quando o projeto é exibido
em um navegador.
O download inclui recursos na pasta WingtipToys-ativos que são usados para criar o aplicativo de
exemplo.
1. Se você não tiver feito isso, baixe os arquivos de amostra de comprimido usando o link
acima do site exemplos do MSDN.
2. Uma vez baixado, abra o arquivo. zip e copie o conteúdo para uma pasta local no seu
computador.
46
4. Arrastando e soltando, copie a pasta do Catálogo de sua pasta local para a raiz do projeto
de aplicativo da Web no Solution Explorer do Visual Studio.
5. Em seguida, crie uma nova pasta denominada imagens clicando com o projeto
WingtipToys no Solution Explorer e selecionando Add -> Nova pasta.
6. Copie o arquivo logo. jpg da pasta WingtipToys-ativos em File Explorer para a pasta de
imagens do projeto de aplicativo da Web no Solution Explorer do Visual Studio.
47
Adicionando páginas
Antes de adicionar a navegação para o aplicativo da Web, você primeiramente vai adicionar duas
novas páginas que você vai navegar para. No final desta série de tutoriais, você vai exibir produtos
e detalhes do produto nestas novas páginas.
48
3. Selecione site. Master para anexar a página mestra para a página. aspx de recém-criado.
Atualizando o Bootstrap
Os modelos de projeto Visual Studio 2013 usam Bootstrap, um layout e temas quadro criado pelo
Twitter. Bootstrap usa CSS3 para fornecer design responsivo, que significa layouts dinamicamente
podem adaptar-se aos tamanhos de janela de navegador diferente. Você também pode usar o
49
recurso de temas do Bootstrap para facilmente efetuar uma mudança na aparência do aplicativo.
Por padrão, o modelo de aplicativo da Web do ASP.NET no Visual Studio 2013 inclui Bootstrap
como um pacote NuGet.
Neste tutorial, você irá alterar a aparência do aplicativo Wingtip Toys, substituindo os arquivos CSS
de Bootstrap.
4. No Solution Explorer, botão direito do mouse a pasta de conteúdo e selecione Abrir pasta
no Explorer arquivo.
O File Explorer será exibido. Você vai salvar um carregar ficheiros CSS bootstrap para este local.
50
Você verá os dois novos arquivos CSS na pasta , mas observe que o ícone ao lado de cada nome
de arquivo é acinzentado. Isto significa que o arquivo não ainda foi adicionado para o projeto.
Nota
O modelo de aplicativo da Web ASP.NET usa o arquivo Bundle.config na raiz do projeto para
armazenar o caminho dos arquivos CSS de Bootstrap.
51
</ul>
Como você pode ver no HTML acima, você modificou a cada item de linha <li> contendo uma
âncora tag <a> com um atributo href do link. Cada href aponta para uma página no aplicativo da
Web. No navegador, quando um usuário clica em um desses links (tais como produtos), eles vão
navegar para a página contida na href (tais como ProductList). Você executará o aplicativo no
final deste tutorial.
Nota
O caractere til (~) é usado para especificar que o caminho href começa na raiz do projeto.
Você usará um ListView controle para exibir todas as categorias contidas no banco de dados. Para
adicionar um ListView controle para a página mestra:
1. Na página mestra , adicione o seguinte realçada <div> elemento após o elemento de <div>
que contém o id="TitleContent" que você adicionou anteriormente:
52
Este código irá exibir todas as categorias do banco de dados. O controle ListView exibe o nome de
cada categoria como o texto do link e inclui um link para a página ProductList.aspx com um valor
de cadeia de consulta contendo a ID da categoria. Definindo a propriedade ItemType no controle
ListView , a expressão de vinculação de dados Item está disponível dentro do nó de ItemTemplate
e o controle torna-se fortemente tipado. Você pode selecionar detalhes do objeto Item usando o
IntelliSense, como especificar o CategoryName. Este código está contido dentro do recipiente <%#:
%> que marca uma expressão de ligação de dados. Adicionando o (:) a fim do <%# prefixo, o
resultado da expressão de ligação de dados é codificado em HTML. Quando o resultado é
codificado em HTML, seu aplicativo está melhor protegido contra cross site script de injeção (XSS)
e ataques de injeção de HTML.
Dica
Quando você adiciona código digitando durante o desenvolvimento, você pode estar certo de que
um membro válido de um objeto é encontrado porque altamente digitado dados controles
mostram os membros disponíveis com base no IntelliSense. IntelliSense oferece opções de código
apropriado contexto conforme você digita o código, como propriedades, métodos e objetos.
2. Próximo ao início do arquivo Site.Master.cs , adicione dois namespaces adicionais para que
todos os namespaces incluídos aparecem da seguinte maneira:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Linq;
using WingtipToys.Models;
53
}
4. }
O código acima é executado quando qualquer página que usa a página mestra é carregada no
navegador. O controle ListView (chamado "categoryList") que você adicionou anteriormente neste
tutorial usa a vinculação do modelo para selecionar dados. Na marcação do controle ListView,
você define a propriedade SelectMethod do controle para o método GetCategories, mostrado
acima. O ListView controle chama o método GetCategories no momento apropriado do ciclo de
vida de página e vincula automaticamente os dados retornados. Você aprenderá mais sobre
vinculação de dados no próximo tutorial.
1. No Solution Explorer, botão direito do mouse a página Default. aspx e selecione Definir
como página inicial.
54
Quando você executar o aplicativo, o aplicativo será ser compilado e banco de dados chamado
wingtiptoys.mdf será criado na pasta App_Data . No navegador, você verá um menu de navegação
da categoria. Este menu foi gerado, recuperando as categorias do banco de dados. No próximo
tutorial, você irá implementar a navegação.
<connectionStrings>
<add name="DefaultConnection"
connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-
WingtipToys-20120302100502;Integrated Security=True"
providerName="System.Data.SqlClient" />
<add name="WingtipToys"
connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|
DataDirectory|\wingtiptoys.mdf;Integrated Security=True"
providerName="System.Data.SqlClient " />
</connectionStrings>
Nota
Se a pasta App_Data não estiver visível, ou se a pasta está vazia, selecione o ícone de Atualizar e,
em seguida, no ícone Mostrar todos os arquivos na parte superior da janela do Solution
55
Explorer . Expandir a largura da janela Solution Explorer pode ser necessária para mostrar todos
os ícones disponíveis.
Agora você pode inspecionar os dados contidos no arquivo de banco de dados wingtiptoys.mdf
usando a janela do Server Explorer .
1. Expanda a pasta App_Data . Se a pasta App_Data não estiver visível, consulte a nota acima.
56
6. Esta visão permite ver e modificar os dados da tabela produtos à mão.
57
9. Na aba de T-SQL , você verá a instrução SQL DDL que foi usada para criar a tabela. Você
também pode usar a interface do usuário na guia Design para modificar a esquema.
10. No Server Explorer, WingtipToys banco de dados com o botão direito e selecione a
Conexão fechada.
Com a desanexação do banco de dados do Visual Studio, o esquema de banco de dados poderá
ser modificado posteriormente nesta série de tutoriais.
11. Volte ao Solution Explorer selecionando a aba Solution Explorer na parte inferior da
janela do Gerenciador de servidores .
Resumo
Neste tutorial da série você adicionou um interface do usuário básica, gráficos, páginas e
navegação. Além disso, você executou o aplicativo da Web, que criou o banco de dados das
classes de dados que você adicionou no tutorial anterior. Você também visualizaram o conteúdo
da tabela produtos do banco de dados exibindo o banco de dados diretamente. No próximo
tutorial, você vai exibir itens de dados e detalhes do banco de dados.
58
59
05 - Exibir itens de dados e detalhes
Este tutorial descreve como exibir itens de dados e detalhes de item de dados usando Web Forms
do ASP.NET e Entity Framework Code First. Este tutorial baseia-se no tutorial anterior "UI e
navegação" e faz parte da série tutorial Wingtip Toy Store. Quando tiver completado este tutorial,
você será capaz de ver os produtos na página ProductsList.aspx e detalhes sobre um produto
individual na página ProductDetails.aspx .
Como adicionar um controle de dados para exibir detalhes do produto do banco de dados.
Como recuperar um valor de seqüência de consulta e usar esse valor para limitar os dados
que são recuperados do banco de dados.
Estes são os recursos introduzidos no tutorial:
Vinculação do modelo
Provedores de valor
Adicionar um controle de fonte de dados permite que você vincule o controle de fonte de dados
ao controle que exibe os dados. Esta abordagem permite conectar declarativamente controles do
lado do servidor diretamente para fontes de dados, em vez de usar uma abordagem programática.
Adicionar código à mão envolve ler o valor, à procura de um valor nulo, tentando convertê-lo para
o tipo apropriado, verificando se a conversão teve êxito e finalmente, usando o valor na consulta.
Você usaria esta abordagem quando você precisa manter o controle total sobre sua lógica de
acesso a dados.
60
Usando o modelo de ligação para ligar dados
Usar vinculação de modelo permite que você vincule os resultados usando muito menos código e
lhe dá a capacidade de reutilizar a funcionalidade em todo o aplicativo. Vinculação de modelo visa
simplificar o trabalho com a lógica de acesso a dados focados no código, mantendo ainda os
benefícios de um quadro rico, ligação de dados.
Exibindo produtos
Neste tutorial, você usará a vinculação do modelo para vincular a dados. Para configurar um
controle de dados para usar a vinculação do modelo para selecionar dados, você pode definir
SelectMethod Propriedade o controle para o nome de um método no código da página. O controle
de dados chama o método no momento apropriado do ciclo de vida de página e vincula
automaticamente os dados retornados. Não há nenhuma necessidade de chamar explicitamente o
DataBind método.
Usando as etapas abaixo, você vai modificar a marcação na página ProductList para que a página
possa exibir produtos.
61
<td id="itemPlaceholder" runat="server"></td>
</tr>
</GroupTemplate>
<ItemTemplate>
<td runat="server">
<table>
<tr>
<td>
<a href="ProductDetails.aspx?productID=<
%#:Item.ProductID%>">
<img src="/Catalog/Images/Thumbs/<
%#:Item.ImagePath%>"
width="100" height="75" style="border:
solid" /></a>
</td>
</tr>
<tr>
<td>
<a href="ProductDetails.aspx?productID=<
%#:Item.ProductID%>">
<span>
<%#:Item.ProductName%>
</span>
</a>
<br />
<span>
<b>Price: </b><%#:String.Format("{0:c}",
Item.UnitPrice)%>
</span>
<br />
</td>
</tr>
<tr>
<td> </td>
</tr>
</table>
</p>
</td>
</ItemTemplate>
<LayoutTemplate>
<table style="width:100%;">
<tbody>
<tr>
<td>
<table id="groupPlaceholderContainer"
runat="server" style="width:100%">
<tr id="groupPlaceholder"></tr>
</table>
</td>
</tr>
<tr>
<td></td>
</tr>
62
<tr></tr>
</tbody>
</table>
</LayoutTemplate>
</asp:ListView>
</div>
</section>
</asp:Content>
Esse código usa um controle ListView chamado "lista de produtos" para exibir os produtos.
O controle ListView exibe dados em um formato que você define usando modelos e estilos. É útil
para dados em qualquer estrutura de repetição. Este exemplo ListView simplesmente mostra
dados de banco de dados, no entanto, você pode habilitar os usuários para editar, inserir e excluir
dados e para classificar e dados da página, tudo sem código.
Além disso, você está usando a associação de modelo para especificar um valor SelectMethod. Este
valor (GetProducts) corresponderá ao método que você adicionará ao code-behind para exibir
produtos na próxima etapa.
63
1. No Solution Explorer, clique com botão direito ProductList e clique em Exibir código.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using WingtipToys.Models;
using System.Web.ModelBinding;
namespace WingtipToys
{
public partial class ProductList : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Este código mostra o método GetProducts que é referenciado pela propriedade ItemType do
controle ListView na página ProductList.aspx. Para limitar os resultados de uma categoria específica
no banco de dados, o código define o valor de categoryId do valor de seqüência de caracteres de
consulta passado para a página de ProductList quando ProductList página é navegada. A classe
QueryStringAttribute no namespace System.Web.ModelBinding é usada para recuperar o valor da
id de variável de seqüência de caracteres de consulta. Isso instrui a vinculação do modelo para
tentar associar um valor da cadeia de caracteres de consulta para o parâmetro categoryId em
tempo de execução.
Quando uma categoria válida é passada como uma seqüência de caracteres de consulta para a
página, os resultados da consulta são limitados a esses produtos no banco de dados que
64
correspondem ao valor de categoryId . Por exemplo, se a URL para a página de ProductsList.aspx é
o seguinte:
http://localhost/ProductList.aspx?id=1
As fontes de valores para esses métodos são chamadas de provedores de valor (como QueryString),
e os atributos de parâmetro que indicam qual provedor de valor para usar são referidos como
atributos de provedor de valor (por exemplo, "id"). O ASP.NET inclui provedores de valor e
atributos correspondentes para todas as fontes típicas de entrada do usuário em um aplicativo de
formulários da Web, como a seqüência de caracteres de consulta, cookies, valores de formulário,
controles, estado de exibição, estado de sessão e propriedades de perfil. Você também pode
escrever os provedores de valor personalizado.
Executando o aplicativo
Execute o aplicativo agora para ver como você pode ver todos os produtos ou apenas um conjunto
de produtos limitada pela categoria.
1. No Solution Explorer, botão direito do mouse a página Default. aspx e selecione Exibir no
navegador.
O navegador irá abrir e mostrar a página Default. aspx .
65
3. Selecione produtos do menu de navegação no topo.
Novamente, a página ProductList é exibida, no entanto desta vez mostra toda a lista de produtos.
66
4. Feche o navegador e retorne ao Visual Studio.
Adicionando um controle de dados para exibir detalhes do produto
Em seguida, você vai modificar a marcação na página de ProductDetails.aspx que você adicionou
no tutorial anterior para que a página possa exibir informações sobre um determinado produto.
67
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<asp:FormView ID="productDetail" runat="server"
ItemType="WingtipToys.Models.Product" SelectMethod ="GetProduct"
RenderOuterTable="false">
<ItemTemplate>
<div>
<h1><%#:Item.ProductName %></h1>
</div>
<br />
<table>
<tr>
<td>
<img src="/Catalog/Images/<%#:Item.ImagePath %>"
style="border:solid; height:300px" alt="<%#:Item.ProductName %>"/>
</td>
<td> </td>
<td style="vertical-align: top; text-align:left;">
<b>Description:</b><br /><%#:Item.Description %>
<br />
<span><b>Price:</b> <%#: String.Format("{0:c}",
Item.UnitPrice) %></span>
<br />
<span><b>Product Number:</b> <%#:Item.ProductID %></span>
<br />
</td>
</tr>
</table>
</ItemTemplate>
</asp:FormView>
</asp:Content>
Esse código usa um controle FormView para exibir detalhes sobre um determinado produto. Essa
marcação usa métodos como aqueles que são usados para exibir os dados na página ProductList .
O controle FormView é usado para exibir um único registro em um tempo de uma fonte de dados.
Quando você usar o controle FormView , você cria modelos para exibir e editar os valores ligados
a dados. Os modelos contêm controles, expressões de vinculação e formatação que definem a
aparência e funcionalidade do formulário.
Para conectar-se a marcação acima no banco de dados, você deve adicionar código adicional para
o código ProductDetails.aspx .
using System;
68
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using WingtipToys.Models;
using System.Web.ModelBinding;
namespace WingtipToys
{
public partial class ProductDetails : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Este código verifica para um valor de seqüência de consulta " productID". Se um valor de cadeia de
caracteres de consulta válida for encontrado, o produto correspondente é exibido. Se nenhuma
seqüência de consulta for encontrada, ou o valor de seqüência de consulta não é válido, nenhum
produto é exibido sobre o ProductDetails.aspx página.
Executando o aplicativo
Agora você pode executar o aplicativo para ver um produto individual exibido com base no id do
produto.
4. Feche o navegador.
Resumo
Neste tutorial da série você tem adicionar marcação e código para exibir uma lista de produtos e
para exibir detalhes do produto. Durante esse processo, você aprendeu sobre os controles de
dados com rigidez de tipos, vinculação do modelo e os provedores de valor. No próximo tutorial,
você vai adicionar um carrinho de compras para o aplicativo de exemplo do Wingtip Toys.
70
06 - Carrinho de compras
Este tutorial descreve a lógica de negócios necessária para adicionar um carrinho de compras ao
aplicativo de exemplo Wingtip Toys do ASP.NET Web Forms. Este tutorial baseia-se no tutorial
anterior "Exibir dados itens e detalhes" e faz parte da série tutorial Wingtip Toy Store. Quando tiver
completado este tutorial, os usuários do seu aplicativo de amostra será capazes de adicionar,
remover e modificar os produtos em seu carrinho de compras.
Nota
1. A pasta de modelos com o botão direito e selecione Add -> New Item.
2. Caixa de diálogo Add New Item é exibida. Selecione Código e depois Classe.
72
3. Nomeie esta nova classe CartItem.cs.
4. Clique em Adicionar.
O novo arquivo de classe é exibido no editor.
using System.ComponentModel.DataAnnotations;
namespace WingtipToys.Models
{
public class CartItem
{
[Key]
public string ItemId { get; set; }
73
}
A classe CartItem contém o esquema que define cada produto que um usuário adiciona ao
carrinho de compras. Essa classe é semelhante para as outras classes de esquema que você criou
anteriormente nesta série de tutoriais. Por convenção, Entity Framework Code First espera que a
chave primária para a tabela CartItem será CartItemId ou ID. No entanto, o código substitui o
comportamento padrão usando o atributo [Key] anotação de dados. O atributo de Key da
propriedade ItemId especifica que a propriedade ItemID é a chave primária.
A propriedade CartId especifica a ID do usuário que está associado com o item para comprar.
Você adicionará código para criar esta ID de usuário quando o usuário acessa o carrinho de
compras. Este ID também será armazenado como uma variável de sessão do ASP.NET.
using System.Data.Entity;
namespace WingtipToys.Models
{
public class ProductContext : DbContext
{
public ProductContext()
: base("WingtipToys")
{
}
74
e excluir dados ao trabalhar com objetos com rigidez de tipos. A classe ProductContext adiciona o
acesso para a classe de modelo CartItem recém-adicionado.
A lógica de carrinho de compras que você irá adicionar conterá a funcionalidade para gerenciar as
seguintes ações:
O diagrama a seguir mostra o processo básico que ocorre quando o usuário adiciona um produto
ao carrinho de compras.
75
Quando o usuário clicar no link Adicionar ao carrinho na página ProductList.aspx ou
ProductDetails.aspx, o aplicativo navegará para a página AddToCart.aspx e depois automaticamente
para a página ShoppingCart.aspx. A página AddToCart.aspx adicionará o produto selecionado ao
carrinho de compras chamando um método na classe ShoppingCart. A página de
ShoppingCart.aspx irá exibir os produtos que foram adicionados ao carrinho de compras.
2. Botão direito do mouse a pasta lógica e em seguida selecione Add -> New Item.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WingtipToys.Models;
namespace WingtipToys.Logic
{
public class ShoppingCartActions : IDisposable
{
public string ShoppingCartId { get; set; }
76
ProductId = id,
CartId = ShoppingCartId,
Product = _db.Products.SingleOrDefault(
p => p.ProductID == id),
Quantity = 1,
DateCreated = DateTime.Now
};
_db.ShoppingCartItems.Add(cartItem);
}
else
{
// If the item does exist in the cart,
// then add one to the quantity.
cartItem.Quantity++;
}
_db.SaveChanges();
}
77
return _db.ShoppingCartItems.Where(
c => c.CartId == ShoppingCartId).ToList();
}
}
O método GetCartId retorna o carrinho ID para o usuário. O carrinho ID é usado para controlar os
itens que um usuário tem em seu carrinho de compras. Se o usuário não tem um carrinho existente
ID, um carrinho novo ID é criado para eles. Se o usuário é logado como um usuário registrado, o
carrinho ID é definido como seu nome de usuário. No entanto, se o usuário não está assinado, o
carrinho ID é definido como um valor exclusivo (um GUID). Um GUID garante que apenas um
carrinho é criado para cada usuário, com base na sessão.
O método GetCartItems retorna uma lista de compras de itens do carrinho para o usuário. Mais
tarde neste tutorial, você verá que a vinculação do modelo é usada para exibir os itens do carrinho
no carrinho de compras, usando o método GetCartItems .
Nota
Você vai estar modificando o código-behind (AddToCart.aspx.cs) para esta página, não o interface
do usuário (AddToCart.aspx).
2. Adicionar uma nova página padrão (Web Form) para o aplicativo chamado AddToCart.aspx.
78
3. No Solution Explorer, botão direito do mouse a página AddToCart.aspx e clique em Exibir
código. O arquivo de code-behind AddToCart.aspx.cs é aberto no editor.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Diagnostics;
using WingtipToys.Logic;
namespace WingtipToys
{
public partial class AddToCart : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string rawId = Request.QueryString["ProductID"];
int productId;
if (!String.IsNullOrEmpty(rawId) && int.TryParse(rawId, out productId))
{
using (ShoppingCartActions usersShoppingCart = new ShoppingCartActions())
{
usersShoppingCart.AddToCart(Convert.ToInt16(rawId));
}
79
else
{
Debug.Fail("ERROR : We should never get to AddToCart.aspx without a
ProductId.");
throw new Exception("ERROR : It is illegal to load AddToCart.aspx without
setting a ProductId.");
}
Response.Redirect("ShoppingCart.aspx");
}
}
Como mencionado anteriormente, um usuário ID é usado para identificar os produtos que estão
associados um usuário específico. Este ID é adicionado a uma linha na tabela CartItem cada vez
que o usuário adiciona um produto ao carrinho de compras.
2. Adicione uma nova página (formulário Web) que inclui uma página-mestre, selecionando o
formulário da Web usando a página mestra. Nomeie a nova página ShoppingCart.aspx.
3. Selecione site. Master para anexar a página mestra para a página. aspx de recém-criado.
80
<div id="ShoppingCartTitle" runat="server" class="ContentHead"><h1>Shopping
Cart</h1></div>
<asp:GridView ID="CartList" runat="server" AutoGenerateColumns="False"
ShowFooter="True" GridLines="Vertical" CellPadding="4"
ItemType="WingtipToys.Models.CartItem" SelectMethod="GetShoppingCartItems"
CssClass="table table-striped table-bordered" >
<Columns>
<asp:BoundField DataField="ProductID" HeaderText="ID"
SortExpression="ProductID" />
<asp:BoundField DataField="Product.ProductName" HeaderText="Name" />
<asp:BoundField DataField="Product.UnitPrice" HeaderText="Price (each)"
DataFormatString="{0:c}"/>
<asp:TemplateField HeaderText="Quantity">
<ItemTemplate>
<asp:TextBox ID="PurchaseQuantity" Width="40" runat="server"
Text="<%#: Item.Quantity %>"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Item Total">
<ItemTemplate>
<%#: String.Format("{0:c}", ((Convert.ToDouble(Item.Quantity)) *
Convert.ToDouble(Item.Product.UnitPrice)))%>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Remove Item">
<ItemTemplate>
<asp:CheckBox id="Remove" runat="server"></asp:CheckBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<div>
<p></p>
<strong>
<asp:Label ID="LabelTotalText" runat="server" Text="Order Total:
"></asp:Label>
<asp:Label ID="lblTotal" runat="server"
EnableViewState="false"></asp:Label>
</strong>
</div>
<br />
</asp:Content>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using WingtipToys.Models;
using WingtipToys.Logic;
namespace WingtipToys
{
public partial class ShoppingCart : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
82
objeto ShoppingCartActions . Em seguida, o código usa essa instância para retornar os itens no
carrinho, chamando o método GetCartItems .
Agora, você adicionará um link Adicionar ao carrinho para a página de ProductList e a página
ProductDetails.aspx . Este link irá incluir o produto ID que é recuperado do banco de dados.
2. Adicione a marcação destacada em amarelo para a página de ProductList para que a página
inteira aparece da seguinte maneira:
83
<tr>
<td>
<a href="ProductDetails.aspx?productID=<
%#:Item.ProductID%>">
<img src="/Catalog/Images/Thumbs/<
%#:Item.ImagePath%>"
width="100" height="75" style="border:
solid" /></a>
</td>
</tr>
<tr>
<td>
<a href="ProductDetails.aspx?productID=<
%#:Item.ProductID%>">
<span>
<%#:Item.ProductName%>
</span>
</a>
<br />
<span>
<b>Price: </b><%#:String.Format("{0:c}",
Item.UnitPrice)%>
</span>
<br />
<a href="/AddToCart.aspx?productID=<
%#:Item.ProductID %>">
<span class="ProductListItem">
<b>Add To Cart<b>
</span>
</a>
</td>
</tr>
<tr>
<td> </td>
</tr>
</table>
</p>
</td>
</ItemTemplate>
<LayoutTemplate>
<table runat="server" style="width:100%;">
<tbody>
<tr runat="server">
<td runat="server">
<table id="groupPlaceholderContainer"
runat="server" style="width:100%">
<tr id="groupPlaceholder" runat="server"></tr>
</table>
</td>
</tr>
<tr runat="server">
<td runat="server"></td>
</tr>
84
<tr></tr>
</tbody>
</table>
</LayoutTemplate>
</asp:ListView>
</div>
</section>
</asp:Content>
Execute o aplicativo para ver como você adicionar produtos ao carrinho de compras.
85
3. Clique no link Adicionar ao carrinho , ao lado do primeiro produto listado (o carro
conversível).
A página de ShoppingCart.aspx é exibida, mostrando a seleção em seu carrinho de compras.
6. Feche o navegador.
Calcular e exibir o Total do pedido
Além de adicionar produtos ao carrinho de compras, você adicionará um método GetTotal à classe
ShoppingCart e exibir a quantidade total da encomenda na página de carrinho de compras.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WingtipToys.Models;
86
namespace WingtipToys.Logic
{
public class ShoppingCartActions : IDisposable
{
public string ShoppingCartId { get; set; }
_db.ShoppingCartItems.Add(cartItem);
}
else
{
// If the item does exist in the cart,
// then add one to the quantity.
cartItem.Quantity++;
}
_db.SaveChanges();
}
87
}
}
return _db.ShoppingCartItems.Where(
c => c.CartId == ShoppingCartId).ToList();
}
88
Primeiro, o método de GetTotal Obtém o ID do carrinho de compras para o usuário. Em seguida, o
método obtém o carrinho total multiplicando a quantidade de produto para cada produto listado
no carrinho o preço do produto.
Nota
O código acima usa o tipo anulável " int?". Tipos anuláveis podem representar todos os valores de
um tipo subjacente e também como um valor nulo. Para mais informações, consulte Usando tipos
anulável.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using WingtipToys.Models;
using WingtipToys.Logic;
namespace WingtipToys
{
public partial class ShoppingCart : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
using (ShoppingCartActions usersShoppingCart = new ShoppingCartActions())
{
decimal cartTotal = 0;
cartTotal = usersShoppingCart.GetTotal();
if (cartTotal > 0)
{
// Display Total.
lblTotal.Text = String.Format("{0:c}", cartTotal);
}
else
{
LabelTotalText.Text = "";
lblTotal.Text = "";
ShoppingCartTitle.InnerText = "Shopping Cart is Empty";
}
89
}
}
Quando carrega a página ShoppingCart.aspx , ele carrega o objeto carrinho compras e em seguida,
recupera o total carrinho compras chamando o método GetTotal da classe ShoppingCart . Se o
carrinho de compras está vazio, uma mensagem será exibida para o efeito.
Execute o aplicativo agora para ver como você não pode apenas adicionar um produto ao carrinho
de compras, mas você pode ver o total de carrinho compras.
90
4. Adicione alguns outros produtos (por exemplo, um avião) para o carrinho.
91
6. Pare a execução app fechando a janela do navegador.
Adicionando botões de Checkout e atualização para o carrinho de compras
Para permitir que os usuários modifiquem o carrinho de compras, você adicionará um botão de
atualização e um botão Checkout para a página do carrinho de compras. Não é usado para o
botão Checkout até mais tarde na série este tutorial.
92
<asp:Label ID="LabelTotalText" runat="server" Text="Order Total:
"></asp:Label>
<asp:Label ID="lblTotal" runat="server"
EnableViewState="false"></asp:Label>
</strong>
</div>
<br />
<table>
<tr>
<td>
<asp:Button ID="UpdateBtn" runat="server" Text="Update"
OnClick="UpdateBtn_Click" />
</td>
<td>
<!--Checkout Placeholder -->
</td>
</tr>
</table>
</asp:Content>
Em seguida, você pode atualizar o código contido no arquivo ShoppingCart.aspx.cs para percorrer
os itens do carrinho e chamar os métodos RemoveItem e UpdateItem .
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using WingtipToys.Models;
using WingtipToys.Logic;
using System.Collections.Specialized;
using System.Collections;
using System.Web.ModelBinding;
namespace WingtipToys
{
public partial class ShoppingCart : System.Web.UI.Page
93
{
protected void Page_Load(object sender, EventArgs e)
{
using (ShoppingCartActions usersShoppingCart = new ShoppingCartActions())
{
decimal cartTotal = 0;
cartTotal = usersShoppingCart.GetTotal();
if (cartTotal > 0)
{
// Display Total.
lblTotal.Text = String.Format("{0:c}", cartTotal);
}
else
{
LabelTotalText.Text = "";
lblTotal.Text = "";
ShoppingCartTitle.InnerText = "Shopping Cart is Empty";
UpdateBtn.Visible = false;
}
}
}
94
}
usersShoppingCart.UpdateShoppingCartDatabase(cartId, cartUpdates);
CartList.DataBind();
lblTotal.Text = String.Format("{0:c}", usersShoppingCart.GetTotal());
return usersShoppingCart.GetCartItems();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WingtipToys.Models;
namespace WingtipToys.Logic
{
public class ShoppingCartActions : IDisposable
{
public string ShoppingCartId { get; set; }
_db.ShoppingCartItems.Add(cartItem);
}
else
{
// If the item does exist in the cart,
// then add one to the quantity.
cartItem.Quantity++;
96
}
_db.SaveChanges();
}
return _db.ShoppingCartItems.Where(
c => c.CartId == ShoppingCartId).ToList();
}
97
cartItems.Product.UnitPrice).Sum();
return total ?? decimal.Zero;
}
98
public void RemoveItem(string removeCartID, int removeProductID)
{
using (var _db = new WingtipToys.Models.ProductContext())
{
try
{
var myItem = (from c in _db.ShoppingCartItems where c.CartId == removeCartID
&& c.Product.ProductID == removeProductID select c).FirstOrDefault();
if (myItem != null)
{
// Remove Item.
_db.ShoppingCartItems.Remove(myItem);
_db.SaveChanges();
}
}
catch (Exception exp)
{
throw new Exception("ERROR: Unable to Remove Cart Item - " +
exp.Message.ToString(), exp);
}
}
}
// Get the count of each item in the cart and sum them up
int? count = (from cartItems in _db.ShoppingCartItems
where cartItems.CartId == ShoppingCartId
select (int?)cartItems.Quantity).Sum();
// Return 0 if all entries are null
return count ?? 0;
}
O próximo tutorial, você usará o método EmptyCart para limpar o carrinho de compras após a
compra de produtos. Mas por agora, você usará o método de GetCount que você acabou de
adicionar para o arquivo ShoppingCartActions.cs para determinar quantos itens estão no carrinho
de compras.
100
Para permitir que o usuário a exibir o número total de itens no carrinho de compras, você irá
adicionar um contador para a página mestra . Este contador também atuará como um link para o
carrinho de compras.
</ul>
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Security.Principal;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Linq;
using WingtipToys.Models;
using WingtipToys.Logic;
namespace WingtipToys
{
public partial class SiteMaster : MasterPage
{
private const string AntiXsrfTokenKey = "__AntiXsrfToken";
private const string AntiXsrfUserNameKey = "__AntiXsrfUserName";
private string _antiXsrfTokenValue;
Page.PreLoad += master_Page_PreLoad;
}
102
protected void Page_PreRender(object sender, EventArgs e)
{
using (ShoppingCartActions usersShoppingCart = new ShoppingCartActions())
{
string cartStr = string.Format("Cart ({0})",
usersShoppingCart.GetCount());
cartCount.InnerText = cartStr;
}
}
103
4. Selecione o menu de navegação da categoria aviões .
7. Clique no botão Atualizar para atualizar a página do carrinho de compras e exibir o novo
total do pedido.
Resumo
Neste tutorial, você criou um carrinho de compras para o aplicativo de exemplo do Wingtip Toys
Web Forms. Durante este tutorial você usou Entity Framework Code First, anotações de dados,
controles de dados fortemente tipados e vinculação do modelo.
O carrinho de compras oferece suporte a adição, exclusão e atualizando itens que o usuário tiver
selecionado para compra. Além de implementar a funcionalidade de carrinho de compras, você
aprendeu como exibir compras carrinho itens em um controle GridView e calcular o total do
pedido.
104
07 - Check-out e pagamento com PayPal
Este tutorial descreve como modificar o aplicativo de exemplo do Wingtip Toys para incluir a
autorização do usuário, registro e pagamento através do PayPal. Somente os usuários que fizeram
logon terão autorização para comprar produtos. A funcionalidade de registro de usuário interno do
modelo de projeto do ASP.NET 4.5 Web Forms já inclui muito do que você precisa. Você irá
adicionar essa funcionalidade do PayPal Express Checkout. Neste tutorial, você estará usando o
ambiente de teste para desenvolvedores do PayPal, portanto não serão transferidos fundos reais.
Ao final do tutorial, você testará o aplicativo selecionando produtos para adicionar ao carrinho de
compras, clicando no botão de check-out e transferindo dados para o site de testes do PayPal. No
site de testes do PayPal, você confirmará suas informações de remessa e pagamento e, em
seguida, retornará ao aplicativo de exemplo Wingtip Toys local para confirmar e concluir a compra.
Nota
O aplicativo de exemplo do Wingtip Toys foi projetado para mostrados conceitos específicos do
ASP.NET e recursos disponíveis para os desenvolvedores da web ASP.NET. Este aplicativo de
exemplo não foi otimizado para todas as circunstâncias possíveis em relação à escalabilidade e
segurança.
Como usar o PayPal para comprar produtos usando o ambiente de teste do PayPal.
105
Adicionar as classes de modelo Order e OrderDetail
No início desta série de tutoriais, você definiu o esquema para categorias, produtos e itens de
carrinho de compras, criando as Category, Producte CartItem classes na pasta modelos . Agora
você irá adicionar duas novas classes para definir o esquema para a ordem do produto e os
detalhes da ordem.
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using System.ComponentModel;
namespace WingtipToys.Models
{
public class Order
{
public int OrderId { get; set; }
106
[Required(ErrorMessage = "Postal Code is required")]
[DisplayName("Postal Code")]
[StringLength(10)]
public string PostalCode { get; set; }
[StringLength(24)]
public string Phone { get; set; }
[ScaffoldColumn(false)]
public decimal Total { get; set; }
[ScaffoldColumn(false)]
public string PaymentTransactionId { get; set; }
[ScaffoldColumn(false)]
public bool HasBeenShipped { get; set; }
using System.ComponentModel.DataAnnotations;
namespace WingtipToys.Models
{
public class OrderDetail
{
public int OrderDetailId { get; set; }
107
public string Username { get; set; }
Além disso, você precisará atualizar a classe de contexto de banco de dados que gerencia as
classes de entidade e que fornece acesso a dados no banco de dados. Para fazer isso, você irá
adicionar as classes de modelo de ordem e OrderDetail recém-criado para ProductContext classe.
using System.Data.Entity;
namespace WingtipToys.Models
{
public class ProductContext : DbContext
{
public ProductContext()
: base("WingtipToys")
{
}
public DbSet<Category> Categories { get; set; }
public DbSet<Product> Products { get; set; }
public DbSet<CartItem> ShoppingCartItems { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<OrderDetail> OrderDetails { get; set; }
}
3. Botão direito do mouse a pasta de saída e selecione Adicionar --> Novo Item .
109
4. Caixa de diálogo Add New Item é exibida.
110
7. Adicione as seguintes páginas adicionais para a pasta de saída usando as mesmas etapas
acima:
CheckoutReview.aspx
CheckoutComplete.aspx
CheckoutCancel.aspx
CheckoutError.aspx
Adicionar um arquivo Web. config
Adicionando um novo arquivo Web. config para a pasta de saída , você será capaz de restringir o
acesso a todas as páginas contidas na pasta.
1. Clique com o botão direito do mouse na pasta Checkout e selecione Add -> New Item.
Caixa de diálogo Add New Item é exibida.
<?xml version="1.0"?>
<configuration>
<system.web>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
</configuration>
O arquivo Web. config especifica que todos os usuários desconhecidos do aplicativo da Web
devem ser negados o acesso às páginas contidas na pasta check-out . No entanto, se o usuário
tiver registrado uma conta e fizer logon, será um usuário conhecido e terá acesso às páginas na
pasta check-out .
É importante observar que a configuração do ASP.NET segue uma hierarquia, onde cada arquivo
Web.config aplica parâmetros de configuração à pasta em que está e a todos os diretórios filho
abaixo dela.
Quando você adicionar um provedor de OAuth (Facebook, Twitter ou Windows Live) para seu
aplicativo ASP.NET Web Forms, você deve definir o valor de ID (chave) de aplicativo e um valor
secreto do aplicativo. Você pode adicionar esses valores para o arquivo Startup.Auth.cs em seu
aplicativo de formulários da Web. Além disso, você deve criar um aplicativo no site externo
(Facebook, Twitter ou Windows Live). Quando você cria o aplicativo no site externo, você pode
obter as chaves de aplicativo que você vai precisar para invocar o recurso de login para aqueles
locais.
Nota
Aplicativos Windows Live só aceitam uma URL ao vivo para um site de trabalho, então você não
pode usar uma URL de site local para inícios de uma sessão de teste.
Para sites que usam um provedor de OpenID (Google), você não precisa criar um aplicativo no site
externo.
3. Descomente a única linha de código destacado em amarelo para permitir que as contas do
Google OpenID como segue:
using Microsoft.AspNet.Identity;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Owin;
namespace WingtipToys
{
public partial class Startup {
112
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login")
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
//app.UseTwitterAuthentication(
// consumerKey: "",
// consumerSecret: "");
//app.UseFacebookAuthentication(
// appId: "",
// appSecret: "");
app.UseGoogleAuthentication();
}
}
Quando você executar o aplicativo de amostra do Wingtip Toys, você terá a opção de acessar sua
conta do Google e associar sua conta do Wingtip Toys com a conta do Google.
113
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using System;
using System.Linq;
using System.Web;
using System.Web.UI;
using WingtipToys.Models;
namespace WingtipToys.Account
{
public partial class Login : Page
{
protected void Page_Load(object sender, EventArgs e)
{
RegisterHyperLink.NavigateUrl = "Register";
OpenAuthLogin.ReturnUrl = Request.QueryString["ReturnUrl"];
var returnUrl = HttpUtility.UrlEncode(Request.QueryString["ReturnUrl"]);
if (!String.IsNullOrEmpty(returnUrl))
{
RegisterHyperLink.NavigateUrl += "?ReturnUrl=" + returnUrl;
}
}
IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response);
}
else
{
FailureText.Text = "Invalid username or password.";
ErrorMessage.Visible = true;
}
}
114
}
}
Por enquanto, você pode ignorar o aviso de que não há definição para o método de MigrateCart .
Você estará adicionando um pouco mais tarde neste tutorial.
Quando é chamado o método de Login sobre o Login.aspx.cs , uma nova instância do carrinho de
compras chamado usersShoppingCart é criada. A identificação do carrinho de compras (um GUID)
é obtida e defina a variável de cartId . Em seguida, o método MigrateCart é chamado, passando
tanto a cartId e o nome do usuário conectado a este método. Quando o carrinho de compras é
migrado, o GUID usado para identificar o carrinho de compras anônimo é substituído com o nome
de usuário.
2. Modificar o arquivo code-behind, incluindo o código em amarelo, para que ele apareça da
seguinte forma:
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using System;
using System.Linq;
using System.Web;
using System.Web.UI;
using WingtipToys.Models;
namespace WingtipToys.Account
{
public partial class Register : Page
{
protected void CreateUser_Click(object sender, EventArgs e)
{
var manager = new UserManager();
var user = new ApplicationUser() { UserName = UserName.Text };
115
IdentityResult result = manager.Create(user, Password.Text);
if (result.Succeeded)
{
IdentityHelper.SignIn(manager, user, isPersistent: false);
IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"],
Response);
}
else
{
ErrorMessage.Text = result.Errors.FirstOrDefault();
}
}
}
}
3. Salve o arquivo Register.aspx.cs . Mais uma vez, ignore o aviso sobre o método de
MigrateCart .
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WingtipToys.Models;
namespace WingtipToys.Logic
116
{
public class ShoppingCartActions : IDisposable
{
public string ShoppingCartId { get; set; }
_db.ShoppingCartItems.Add(cartItem);
}
else
{
// If the item does exist in the cart,
// then add one to the quantity.
cartItem.Quantity++;
}
_db.SaveChanges();
}
117
}
return _db.ShoppingCartItems.Where(
c => c.CartId == ShoppingCartId).ToList();
}
118
}
119
_db.SaveChanges();
}
}
catch (Exception exp)
{
throw new Exception("ERROR: Unable to Remove Cart Item - " +
exp.Message.ToString(), exp);
}
}
}
// Get the count of each item in the cart and sum them up
120
int? count = (from cartItems in _db.ShoppingCartItems
where cartItems.CartId == ShoppingCartId
select (int?)cartItems.Quantity).Sum();
// Return 0 if all entries are null
return count ?? 0;
}
O método MigrateCart usa o cartId existente para encontrar o carrinho de compras do usuário. Em
seguida, o código percorrerá todos os itens do carrinho de compras e substitui a propriedade
CartId (conforme especificado pelo esquema CartItem ) com o nome do usuário conectado.
2. Atualize seqüência de conexão padrão para que ele apareça da seguinte forma:
Integração PayPal
121
PayPal é uma plataforma de faturamento baseado em web que aceita pagamentos por
comerciantes on-line. Neste tutorial, em seguida, explica como integrar funcionalidade de Express
Checkout do PayPal no seu aplicativo. O Express Checkout permite que seus clientes utilizem o
PayPal para pagar pelos artigos que adicionaram ao carrinho de compras.
Para usar o PayPal em ambiente de teste, você deve criar e verificar uma conta de teste do
desenvolvedor. Você usará a conta de teste do desenvolvedor para criar um comprador conta de
teste e uma conta de teste do vendedor. As credenciais de conta de teste do desenvolvedor
também permitirá que o aplicativo de exemplo do Wingtip Toys acessar o ambiente de teste do
PayPal.
2. Se você não tiver uma conta de desenvolvedor do PayPal, criar uma nova conta clicando em
Cadastre-se e seguindo o etapas de inscrição. Se você tiver uma conta de desenvolvedor existente
do PayPal, Cadastre-se clicando em Log In. Você vai precisar de sua conta de desenvolvedor de
PayPal para testar o aplicativo de exemplo do Wingtip Toys no final deste tutorial.
3. Se você se inscreveu para sua conta de desenvolvedor do PayPal, você pode precisar
verificar a sua conta de desenvolvedor PayPal com PayPal. Você pode verificar sua conta,
seguindo os passos que o PayPal enviada para sua conta de e-mail. Uma vez que você
verificou que sua conta de desenvolvedor do PayPal, log de volta para o desenvolvedor
PayPal testando o site.
4. Depois que você está logado no site do desenvolvedor PayPal com sua conta de
desenvolvedor do PayPal que você precisa criar uma conta de teste do comprador PayPal se você
ainda não tem um. Para criar uma conta de teste do comprador, no site do PayPal clique na guia
aplicativos e em seguida, clique em contas de Sandbox.
A página de Sandbox contas de teste é mostrada.
Nota
122
5. Na caixa de areia teste página contas, clique em Criar conta.
6. Na página criar conta de teste escolha um comprador teste conta de e-mail e senha de
sua escolha.
Nota
Você vai precisar os endereços de e-mail do comprador e a senha para testar o aplicativo de
exemplo do Wingtip Toys no final deste tutorial.
123
124
7. Crie conta de teste o comprador clicando no botão Criar conta .
A página de teste Sandbox contas é exibida.
9. Selecione a opção de perfil e, em seguida, clique em credenciais de API para exibir suas
credenciais de API para a conta de teste mercantes.
Você precisará de suas credenciais clássico teste API exibidas (nome de usuário, senha e assinatura)
para fazer chamadas de API do aplicativo de exemplo Wingtip Toys para o PayPal, ambiente de
teste. Você adicionará as credenciais na próxima etapa.
Você colocará a maioria do código PayPal em uma única classe. Esta classe contém os métodos
usados para se comunicar com o PayPal. Além disso, você irá adicionar suas credenciais de PayPal
para essa classe.
1. No aplicativo de amostra Wingtip Toys dentro do Visual Studio, clique com botão direito na
pasta lógica e selecione Add -> New Item.
Caixa de diálogo Add New Item é exibida.
4. Clique em Adicionar.
O novo arquivo de classe é exibido no editor.
using System;
using System.Collections;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Text;
using System.Data;
using System.Configuration;
using System.Web;
using WingtipToys;
using WingtipToys.Models;
using System.Collections.Generic;
using System.Linq;
// Live strings.
private string pEndPointURL = "https://api-3t.paypal.com/nvp";
private string host = "www.paypal.com";
// Sandbox strings.
private string pEndPointURL_SB = "https://api-3t.sandbox.paypal.com/nvp";
private string host_SB = "www.sandbox.paypal.com";
126
//HttpWebRequest Timeout specified in milliseconds
private const int Timeout = 15000;
private static readonly string[] SECURED_NVPS = new string[] { ACCT, CVV2,
SIGNATURE, PWD };
public bool ShortcutExpressCheckout(string amt, ref string token, ref string retMsg)
{
if (bSandbox)
{
pEndPointURL = pEndPointURL_SB;
host = host_SB;
}
127
string pStresponsenvp = HttpCall(pStrrequestforNvp);
128
retMsg = "ErrorCode=" + decoder["L_ERRORCODE0"] + "&" +
"Desc=" + decoder["L_SHORTMESSAGE0"] + "&" +
"Desc2=" + decoder["L_LONGMESSAGE0"];
return false;
}
}
return false;
}
}
129
string strPost = NvpRequest + "&" + buildCredentialsNVPString();
strPost = strPost + "&BUTTONSOURCE=" + HttpUtility.UrlEncode(BNCode);
try
{
using (StreamWriter myWriter = new StreamWriter(objRequest.GetRequestStream()))
{
myWriter.Write(strPost);
}
}
catch (Exception)
{
// No logging for this tutorial.
}
//Retrieve the Response returned from the NVP API call to PayPal.
HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
string result;
using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
{
result = sr.ReadToEnd();
}
return result;
}
if (!IsEmpty(APIUsername))
codec["USER"] = APIUsername;
if (!IsEmpty(APIPassword))
codec[PWD] = APIPassword;
if (!IsEmpty(APISignature))
codec[SIGNATURE] = APISignature;
if (!IsEmpty(Subject))
codec["SUBJECT"] = Subject;
codec["VERSION"] = "88.0";
130
return codec.Encode();
}
131
public void Add(string name, string value, int index)
{
this.Add(GetArrayName(index, name), value);
}
6. Adicione as credenciais de comerciante API (nome de usuário, senha e assinatura) que você
exibido anteriormente neste tutorial para que você possa fazer chamadas de função para
o ambiente de teste do PayPal.
Nota
132
Neste aplicativo de exemplo você está simplesmente adicionando credenciais em um arquivo c# (.
cs). No entanto, em uma solução implementada, você deve considerar criptografar suas credenciais
em um arquivo de configuração.
Função SetExpressCheckout
Função GetExpressCheckoutDetails
Função DoExpressCheckoutPayment
Nota
PayPal permite que você inclua detalhes de compra opcional, com base na especificação da API do
PayPal. Estendendo o código no aplicativo de amostra Wingtip Toys, você pode incluir detalhes de
localização, descrições de produto, imposto, um número de serviço ao cliente, bem como muitos
outros campos opcionais.
Quando o Visual Web Developer executa um projeto web, uma porta aleatória é usada para o
servidor web. Como mostrado acima, o número da porta é 1234. Quando você executar o
aplicativo, você provavelmente verá um número de porta diferente. Seu número de porta precisa
ser definido no código acima para que você possa executar com êxito o aplicativo de exemplo
Wingtip Toys ao final deste tutorial. A próxima seção deste tutorial explica como recuperar o
número da porta do host local e atualizar a classe PayPal.
O aplicativo de exemplo do Wingtip Toys compra produtos navegando no site de teste de PayPal e
retornando a sua instância local do aplicativo de exemplo Wingtip Toys. Para ter PayPal retornar
133
para a URL correta, você precisa especificar o número da porta da executando localmente amostra
de aplicativo no código PayPal acima mencionado.
Agora o código que você adicionou corresponderá a porta esperada para seu aplicativo da Web
local. PayPal será capaz de retornar para a URL correta na sua máquina local.
Agora que as principais funções do PayPal foram adicionadas para o aplicativo de exemplo, você
pode começar adicionando a marcação e o código necessário para chamar essas funções. Primeiro,
você deve adicionar o botão checkout que o usuário verá na página de carrinho de compras.
3. Substitua o comentário com um ImageButton controle para que a marca se é ter a seguinte
redacção:
ImageUrl="https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif"
Width="145" AlternateText="Check out with PayPal"
OnClick="CheckoutBtn_Click"
134
using (ShoppingCartActions usersShoppingCart = new ShoppingCartActions())
{
Session["payment_amt"] = usersShoppingCart.GetTotal();
}
Response.Redirect("Checkout/CheckoutStart.aspx");
135
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WingtipToys.Checkout
{
public partial class CheckoutStart : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
NVPAPICaller payPalCaller = new NVPAPICaller();
string retMsg = "";
string token = "";
if (Session["payment_amt"] != null)
{
string amt = Session["payment_amt"].ToString();
136
método ShortcutExpressCheckout é completo, ele irá redirecionar o usuário para a página
CheckoutReview.aspx especificada no método ShortcutExpressCheckout . Isto permite ao usuário
examinar os detalhes da ordem de dentro do aplicativo de amostra do Wingtip Toys.
137
<asp:Label ID="PostalCode" runat="server" Text='<%#:
Eval("PostalCode") %>'></asp:Label>
<p></p>
<h3>Order Total:</h3>
<br />
<asp:Label ID="Total" runat="server" Text='<%#: Eval("Total", "{0:C}")
%>'></asp:Label>
</ItemTemplate>
<ItemStyle HorizontalAlign="Left" />
</asp:TemplateField>
</Fields>
</asp:DetailsView>
<p></p>
<hr />
<asp:Button ID="CheckoutConfirm" runat="server" Text="Complete Order"
OnClick="CheckoutConfirm_Click" />
</asp:Content>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using WingtipToys.Models;
namespace WingtipToys.Checkout
{
public partial class CheckoutReview : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
NVPAPICaller payPalCaller = new NVPAPICaller();
138
if (ret)
{
Session["payerId"] = PayerID;
// Get DB context.
ProductContext _db = new ProductContext();
139
for (int i = 0; i < myOrderList.Count; i++)
{
// Create a new OrderDetail object.
var myOrderDetail = new OrderDetail();
myOrderDetail.OrderId = myOrder.OrderId;
myOrderDetail.Username = User.Identity.Name;
myOrderDetail.ProductId = myOrderList[i].ProductId;
myOrderDetail.Quantity = myOrderList[i].Quantity;
myOrderDetail.UnitPrice = myOrderList[i].Product.UnitPrice;
// Set OrderId.
Session["currentOrderId"] = myOrder.OrderId;
// Display OrderDetails.
OrderItemList.DataSource = myOrderList;
OrderItemList.DataBind();
}
}
else
{
Response.Redirect("CheckoutError.aspx?" + retMsg);
}
}
}
O DetailsView controle é usado para exibir os detalhes do pedido que retornaram do PayPal.
Também, o código acima salva os detalhes do pedido no banco de dados do Wingtip Toys como
140
um objeto OrderDetail . Quando o usuário clica no botão Ordem completa , eles são
redirecionados para a página CheckoutComplete.aspx .
Dica
Na marcação da página CheckoutReview.aspx , observe que a tag <ItemStyle> é usada para alterar
o estilo dos itens dentro do controle DetailsView na parte inferior da página. Exibindo a página no
Modo de exibição Design (selecionando Design no canto inferior esquerdo do Visual Studio),
então selecionando o controle DetailsView , e selecionando a Marca inteligente (o ícone de seta
no canto superior direito do controle), você será capaz de ver o DetailsView Tasks.
Selecionando Editar campos, irá aparecer a caixa de diálogo campos . Nesta caixa de diálogo,
você pode facilmente controlar as propriedades visuais, como ItemStyle, do controle
DetailsView .
141
Concluir compra
Página de CheckoutComplete.aspx faz a compra do PayPal. Como mencionado acima, o usuário
deve clicar no botão Ordem completa antes que o aplicativo será navegar para a página
CheckoutComplete.aspx .
142
</asp:Content>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using WingtipToys.Models;
namespace WingtipToys.Checkout
{
public partial class CheckoutComplete : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Verify user has completed the checkout process.
if ((string)Session["userCheckoutCompleted"] != "true")
{
Session["userCheckoutCompleted"] = string.Empty;
Response.Redirect("CheckoutError.aspx?" + "Desc=Unvalidated%20Checkout.");
}
token = Session["token"].ToString();
PayerID = Session["payerId"].ToString();
finalPaymentAmount = Session["payment_amt"].ToString();
143
TransactionId.Text = PaymentConfirmation;
</asp:Content>
</asp:Content>
A página da CheckoutError.aspx é exibida com os detalhes do erro quando ocorre um erro durante
o processo de checkout.
Executando o aplicativo
Execute o aplicativo para ver como a aquisição de produtos. Note que você estará executando no
PayPal ambiente de teste. Nenhum dinheiro real está sendo trocado.
3. Faça o login com sua conta de desenvolvedor do PayPal que você criou anteriormente
neste tutorial.
Para sandbox de desenvolvedores do PayPal, você precisa estar logado no
https://developer.paypal.com para testar o check-out expresso. Isso só se aplica à proteção do
PayPal, testes, não para viver ambiente do PayPal.
146
7. Check-out vai exigir que você tem uma conta de usuário para o aplicativo de exemplo do
Wingtip Toys.
8. Clique no link do Google à direita da página para fazer login com uma conta de e-mail
existente do gmail.com.
Se você não tiver uma conta do gmail.com, você pode criar um para testes em www.gmail.com.
Você também pode usar uma conta local padrão clicando em "Register".
147
9. Inscreva-se com sua conta do gmail e senha.
148
10. Clique no botão Log in para registrar sua conta do gmail com seu nome de usuário do
aplicativo de amostra Wingtip Toys.
149
11. No site de teste do PayPal, adicionar o seu endereço de e-mail do comprador e a senha
que você criou anteriormente neste tutorial e, em seguida, clique no botão Log In .
150
13. Revisar as informações de ordem sobre o PayPal página de revisão do ambiente de teste e
clique em continuar.
151
14. Na página CheckoutReview.aspx , verifique se o valor do pedido e ver o endereço de
entrega gerado. Em seguida, clique no botão Ordem completa .
152
Revendo o banco de dados
Revendo os dados atualizados do banco de dados do aplicativo de amostra Wingtip Toys depois
de executar o aplicativo, você pode ver que o aplicativo gravado com êxito a compra dos produtos.
Você pode inspecionar os dados contidos no arquivo de banco de dados Wingtiptoys.mdf usando a
janela de Banco de dados Explorer (janelaServer Explorer no Visual Studio), como você fez no
início desta série de tutoriais.
153
8. Feche a janela da tabela de pedidos .
10. Rever os valores OrderId e Username na tabela detalhes do pedido . Observe que esses
valores correspondem aos valores de OrderId e Username incluídos na tabela Orders .
12. Botão direito do mouse o arquivo de banco de dados do Wingtip Toys (Wingtiptoys.mdf) e
selecione a Conexão fechada.
13. Se você não vir a janela Solution Explorer , clique em Gerenciador de soluções na parte
inferior da janela do Server Explorer para mostrar o Solution Explorer novamente.
Resumo
Neste tutorial você adicionou a ordem e ordem detalhe esquemas para controlar a compra de
produtos. Você também integrado a funcionalidade do PayPal no aplicativo de amostra do Wingtip
Toys.
Recursos adicionais
Visão geral de configuração do ASP.NET
Criar um aplicativo ASP.NET MVC 5 com Facebook e Google OAuth2 e OpenID Sign-on (c#)
Resumo
Este tutorial contém código de exemplo. Tal código de exemplo é fornecido "como está" sem
garantia de qualquer tipo. Nesse sentido, a Microsoft não garante a exatidão, integridade ou
qualidade de código de exemplo. Você concorda em usar o código de exemplo em seu próprio
risco. Sob nenhuma circunstância a Microsoft será responsável de qualquer forma por qualquer
código de amostra, conteúdo, incluindo mas não limitado a, quaisquer erros ou omissões em
qualquer código de amostra, conteúdo, ou qualquer perda ou dano de qualquer tipo incorrido
154
como resultado do uso de qualquer código de amostra. Você é notificado por este meio e
concorda em indenizar, salvar e Microsoft de e contra todas e quaisquer perdas, sinistros de perda,
lesão ou danos de qualquer tipo, incluindo, sem limitação, aqueles resultantes ou decorrentes de
material que você postar, transmite, utilizar ou contar com incluindo, mas não limitado a, as
opiniões expressas nele.
155
08 - Associação e administração
Este tutorial mostra como atualizar o aplicativo de exemplo do Wingtip Toys para adicionar uma
função de administrador e usar a identidade do ASP.NET. Ele também mostra como implementar
uma página de administração do qual o administrador pode adicionar e remover produtos do site.
Este tutorial baseia-se no tutorial anterior, intitulado "Checkout e pagamento com PayPal" na série
tutorial Wingtip Toys.
Como usar o código para adicionar uma função de administrador e um usuário para o
aplicativo.
Como restringir o acesso para a pasta de administração e a página.
Configuração e autorização
Vinculação do modelo
156
Validação discreta
Web Forms do ASP.NET fornece recursos de associação. Usando o modelo padrão, você tem a
funcionalidade de associação interna que você pode usar imediatamente quando o aplicativo é
executado. Este tutorial mostra como usar a identidade do ASP.NET para adicionar uma função de
administrador e atribuir um usuário a esse papel. Você vai aprender como restringir o acesso para
a pasta de administração. Você adicionará uma página para a pasta de administração que permite
que um administrador para adicionar e remover produtos e para visualizar um produto depois que
ele foi adicionado.
Adicionar um administrador
Usando a identidade do ASP.NET, você pode adicionar uma função de administrador e atribuir um
usuário a esse papel usando código.
1. No Solution Explorer, clique com botão direito na pasta lógica e criar uma nova classe.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace WingtipToys.Logic
{
internal class RoleActions
{
}
using System;
using System.Collections.Generic;
157
using System.Linq;
using System.Web;
using System.Web.Optimization;
using System.Web.Routing;
using System.Web.Security;
using System.Web.SessionState;
using System.Data.Entity;
using WingtipToys.Models;
using WingtipToys.Logic;
namespace WingtipToys
{
public class Global : HttpApplication
{
{
// Code that runs on application startup
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
Database.SetInitializer(new ProductDatabaseInitializer());
roleActions.createAdmin();
}
}
158
7. Em seguida, passe o mouse sobre a letra "c" para exibir a interface do usuário que permite
que você gere um esboço do método para o método createAdmin .
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WingtipToys.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
namespace WingtipToys.Logic
{
internal class RoleActions
{
internal void createAdmin()
{
// Access the application context and create result variables.
IdentityResult IdRoleResult;
IdentityResult IdUserResult;
159
var roleStore = new RoleStore<IdentityRole>(context);
if (!roleMgr.RoleExists("Administrator"))
{
// Handle the error condition if there's a problem creating the
RoleManager object.
}
}
{
UserName = "Admin",
};
IdUserResult = userMgr.Create(appUser, "Pa$$word");
{
IdUserResult = userMgr.AddToRole(appUser.Id, "Administrator");
if (!IdUserResult.Succeeded)
{
// Handle the error condition if there's a problem adding the user to the
role.
}
}
else
{
// Handle the error condition if there's a problem creating the new user.
}
}
}
O código acima, primeiro, estabelece um contexto de banco de dados para o banco de dados de
associação. O banco de dados de associação também é armazenado como um arquivo. MDF na
pasta App_Data . Você será capaz de ver os este banco de dados, uma vez que o primeiro usuário
assinou para esse aplicativo web.
Nota
Se você deseja armazenar os dados de associação juntamente com os dados do produto, você
pode considerar usando a mesma DbContext usado para armazenar os dados de produto no
código acima.
Um objeto RoleStore , que fornece gerenciamento de função, é criado com base no contexto do
banco de dados.
Nota
161
Observe que, quando o RoleStore objeto é criado ele usa um tipo genérico IdentityRole . Isto
significa que o RoleStore só é permitido para conter objetos IdentityRole . Também usando
Generics, recursos na memória são tratados melhor.
Em seguida, o objeto de RoleManager , é criado com base no objeto RoleStore que você acabou de
criar. o RoleManager objeto expõe papel relacionado API que pode ser usado para salvar
automaticamente as alterações para o RoleStore. O RoleManager só é permitido para conter
objetos de IdentityRole , porque o código usa o tipo genérico <IdentityRole> .
Você chamar o método RoleExists para determinar se a função de "Administrador" está presente
no banco de dados de associação. Se não for, você cria o papel.
Criar o objeto UserManager parece ser mais complicado do que o RoleManager controle, no
entanto, é quase o mesmo. Só está codificado em uma linha, em vez de vários. Aqui, o parâmetro
que você está passando é instanciar como um novo objeto contido no parêntese.
Em seguida, você criar o usuário "Admin", criando um novo objeto ApplicationUser . Então, se
você criar o usuário, com êxito, você adicionar o usuário à nova função.
Nota
Da próxima vez que o aplicativo for iniciado, o usuário chamado "Admin" será adicionado como a
função denominada "Administrador" do aplicativo. No final deste tutorial, você irá login como o
usuário "Admin" para exibir recursos adicionais que você será adicionado durante este tutorial.
Para API detalhes sobre a identidade do ASP.NET, consulte o Namespace Microsoft.AspNet.Identity.
Para obter detalhes adicionais sobre a inicialização do sistema de identidade do ASP.NET, consulte
o AspnetIdentitySample.
3. Botão direito do mouse a pasta Admin e em seguida selecione Add -> New Item.
Caixa de diálogo Add New Item é exibida.
4. Selecione o Visual c# -> grupo de modelos Web à esquerda. Médio na lista, selecione O
formulário da Web com a página mestra, nome AdminPage.aspx, e selecione Adicionar .
162
5. Selecione o arquivo site Master como a página mestra e em seguida, escolha OK.
1. Botão direito do mouse a pasta Admin e selecione Add -> New Item.
Caixa de diálogo Add New Item é exibida.
2. Na lista de modelos de web do Visual translation from VPE for Csharp, selecione o Arquivo
de configuração Web lista média, aceite o nome padrão do Web. config,, e selecione Adicionar.
<?xml version="1.0"?>
<configuration>
<system.web>
<authorization>
<allow roles="Administrator"/>
<deny users="*"/>
</authorization>
</system.web>
</configuration>
Salve o arquivo Web. config . O arquivo Web. config especifica que somente os administradores do
aplicativo podem acessar a página contida na pasta Admin .
2. Para criar um link para os administradores, adicione a marcação destacada em amarelo para
o seguinte elemento <ul> lista não ordenada para que a lista aparece da seguinte maneira:
163
<li><a runat="server" href="~/About">About</a></li>
<li><a runat="server" href="~/Contact">Contact</a></li>
<li><a runat="server" href="~/ProductList">Products</a></li>
<li><a runat="server" href="~/ShoppingCart"
ID="cartCount"> </a></li>
</ul>
3. Abra o arquivo Site.Master.cs . Fazer o link Admin visível apenas para o usuário "Admin",
adicionando o código destacado em amarelo para o manipulador Page_Load . O manipulador
Page_Load aparecerá como segue:
Quando a página for carregada, o código verifica se o usuário conectado tem o papel de
"Administrador". Se o usuário for um administrador, o span elemento, que contém o link para a
página de AdminPage.aspx (e, consequentemente, o link dentro do intervalo) é tornado visível.
164
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master"
AutoEventWireup="true" CodeBehind="AdminPage.aspx.cs"
Inherits="WingtipToys.Admin.AdminPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<h1>Administration</h1>
<hr />
<h3>Add Product:</h3>
<table>
<tr>
<td><asp:Label ID="LabelAddCategory"
runat="server">Category:</asp:Label></td>
<td>
<asp:DropDownList ID="DropDownAddCategory" runat="server"
ItemType="WingtipToys.Models.Category"
SelectMethod="GetCategories" DataTextField="CategoryName"
DataValueField="CategoryID" >
</asp:DropDownList>
</td>
</tr>
<tr>
<td><asp:Label ID="LabelAddName" runat="server">Name:</asp:Label></td>
<td>
<asp:TextBox ID="AddProductName" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1"
runat="server" Text="* Product name required." ControlToValidate="AddProductName"
SetFocusOnError="true" Display="Dynamic"></asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td><asp:Label ID="LabelAddDescription"
runat="server">Description:</asp:Label></td>
<td>
<asp:TextBox ID="AddProductDescription"
runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator2"
runat="server" Text="* Description required."
ControlToValidate="AddProductDescription" SetFocusOnError="true"
Display="Dynamic"></asp:RequiredFieldValidator>
</td>
165
</tr>
<tr>
<td><asp:Label ID="LabelAddPrice" runat="server">Price:</asp:Label></td>
<td>
<asp:TextBox ID="AddProductPrice" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator3"
runat="server" Text="* Price required." ControlToValidate="AddProductPrice"
SetFocusOnError="true" Display="Dynamic"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="RegularExpressionValidator1"
runat="server" Text="* Must be a valid price without $."
ControlToValidate="AddProductPrice" SetFocusOnError="True" Display="Dynamic"
ValidationExpression="^[0-9]*(\.)?[0-9]?[0-9]?$"></asp:RegularExpressionValidator>
</td>
</tr>
<tr>
<td><asp:Label ID="LabelAddImageFile" runat="server">Image
File:</asp:Label></td>
<td>
<asp:FileUpload ID="ProductImage" runat="server" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator4"
runat="server" Text="* Image path required." ControlToValidate="ProductImage"
SetFocusOnError="true" Display="Dynamic"></asp:RequiredFieldValidator>
</td>
</tr>
</table>
<p></p>
<p></p>
<asp:Button ID="AddProductButton" runat="server" Text="Add Product"
OnClick="AddProductButton_Click" CausesValidation="true"/>
<asp:Label ID="LabelAddStatus" runat="server" Text=""></asp:Label>
<p></p>
<h3>Remove Product:</h3>
<table>
<tr>
<td><asp:Label ID="LabelRemoveProduct"
runat="server">Product:</asp:Label></td>
<td><asp:DropDownList ID="DropDownRemoveProduct" runat="server"
ItemType="WingtipToys.Models.Product"
SelectMethod="GetProducts" AppendDataBoundItems="true"
166
DataTextField="ProductName" DataValueField="ProductID" >
</asp:DropDownList>
</td>
</tr>
</table>
<p></p>
<asp:Button ID="RemoveProductButton" runat="server" Text="Remove Product"
OnClick="RemoveProductButton_Click" CausesValidation="false"/>
<asp:Label ID="LabelRemoveStatus" runat="server" Text=""></asp:Label>
</asp:Content>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using WingtipToys.Models;
using WingtipToys.Logic;
namespace WingtipToys.Admin
{
public partial class AdminPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
{
LabelAddStatus.Text = "Product added!";
167
}
if (productAction == "remove")
{
LabelRemoveStatus.Text = "Product removed!";
}
}
if (ProductImage.HasFile)
{
String fileExtension =
System.IO.Path.GetExtension(ProductImage.FileName).ToLower();
String[] allowedExtensions = { ".gif", ".png", ".jpeg", ".jpg" };
if (fileExtension == allowedExtensions[i])
fileOK = true;
}
}
}
if (fileOK)
try
{
168
// Save to Images folder.
ProductImage.PostedFile.SaveAs(path + ProductImage.FileName);
// Save to Images/Thumbs folder.
ProductImage.PostedFile.SaveAs(path + "Thumbs/" + ProductImage.FileName);
}
{
LabelAddStatus.Text = ex.Message;
}
AddProductPrice.Text, DropDownAddCategory.SelectedValue,
ProductImage.FileName);
if (addSuccess)
{
// Reload the page.
Response.Redirect(pageUrl + "?ProductAction=add");
}
else
{
LabelAddStatus.Text = "Unable to add new product to database.";
}
}
else
{
LabelAddStatus.Text = "Unable to accept file type.";
}
169
}
return query;
return query;
{
_db.Products.Remove(myItem);
_db.SaveChanges();
170
Response.Redirect(pageUrl + "?ProductAction=remove");
}
else
{
LabelRemoveStatus.Text = "Unable to locate product.";
}
}
}
}
No código que você digitou para o arquivo de code-behind AdminPage.aspx.cs , uma classe
chamada AddProducts faz o trabalho real de adicionar produtos no banco de dados. Essa classe
ainda não existe, então você irá criá-lo agora.
1. No Solution Explorer, clique com botão direito na pasta lógica e em seguida selecione
Add -> New Item.
Caixa de diálogo Add New Item é exibida.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WingtipToys.Models;
namespace WingtipToys.Logic
{
public class AddProducts
{
public bool AddProduct(string ProductName, string ProductDesc, string ProductPrice,
string ProductCategory, string ProductImagePath)
{
171
var myProduct = new Product();
myProduct.ProductName = ProductName;
myProduct.Description = ProductDesc;
myProduct.UnitPrice = Convert.ToDouble(ProductPrice);
myProduct.ImagePath = ProductImagePath;
myProduct.CategoryID = Convert.ToInt32(ProductCategory);
{
// Add product to DB.
_db.Products.Add(myProduct);
_db.SaveChanges();
}
// Success.
return true;
}
}
Validação discreta
Os detalhes do produto que o usuário fornece na página AdminPage.aspx são validados usando
controles de validação (RequiredFieldValidator e RegularExpressionValidator). Esses controles
automaticamente usam a validação de discreta. Discreta validação permite que os controles de
validação usar JavaScript para lógica de validação do lado do cliente, o que significa que a página
não requer uma viagem para o servidor para ser validado. Por padrão, validação discreta está
incluída no arquivo Web. config baseado a definição de configuração a seguir:
Expressões regulares
172
O preço do produto na página AdminPage.aspx é validado usando um controle
RegularExpressionValidator . Este controle valida se o valor do Controlarar de entrada associado
(a caixa de texto "AddProductPrice") coincide com o padrão de expressão regular. Uma expressão
regular é uma notação de correspondência de padrões que permite que você rapidamente
encontrar e combinar padrões de caracteres específicos. O controle RegularExpressionValidator
inclui uma propriedade chamada ValidationExpression que contém a expressão regular usada
para validar a entrada do preço, como mostrado abaixo:
<asp:RegularExpressionValidator
ID="RegularExpressionValidator1" runat="server"
Text="* Must be a valid price without $." ControlToValidate="AddProductPrice"
SetFocusOnError="True" Display="Dynamic"
ValidationExpression="^[0-9]*(\.)?[0-9]?[0-9]?$">
</asp:RegularExpressionValidator>
Controle fileUpload
Além dos controles de entrada e validação, você adicionou o FileUpload controle para a página
AdminPage.aspx . Esse controle fornece a capacidade de fazer upload de arquivos. Neste caso, você
só permite que arquivos de imagem a ser carregada. No arquivo code-behind (AdminPage.aspx.cs),
quando o AddProductButton for clicado, o código verifica a propriedade HasFile do controle
FileUpload . Se o controle tem um arquivo e o tipo de arquivo (com base na extensão de arquivo)
é permitido, a imagem é salva a pasta de imagens e a pasta de Imagens/Thumbs do aplicativo.
Vinculação do modelo
No início desta série de tutoriais você usou a vinculação do modelo para preencher um controle
ListView , um FormsView controle, um controle GridView e um controle DetailView . Neste
tutorial, você pode usar vinculação do modelo para preencher um controle DropDownList com
uma lista de categorias de produtos.
ItemType="WingtipToys.Models.Category"
SelectMethod="GetCategories" DataTextField="CategoryName"
DataValueField="CategoryID" >
1. </asp:DropDownList>
173
Você pode usar vinculação do modelo para preencher o DropDownList por configuração o
atributo ItemType e o atributo SelectMethod . O atributo ItemType especifica que você use o tipo
de WingtipToys.Models.Category ao preencher o controle. Você definiu este tipo no início desta
série tutorial Criando a classe de Category (mostrado abaixo). A classe de Category está na pasta
de modelos dentro do arquivo Category.cs .
[ScaffoldColumn(false)]
public int CategoryID { get; set; }
Este método especifica que um IQueryable interface é usado para avaliar uma consulta contra um
tipo de Category . O valor retornado é usado para preencher o DropDownList na marcação da
página (AdminPage.aspx).
174
O texto exibido para cada item na lista é especificado, definindo o atributo DataTextField . O
atributo DataTextField usa o CategoryName da classe Category (mostrado acima) para exibir cada
categoria no controle DropDownList . O real valor que é passado quando um item é selecionado
no controle DropDownList é baseado no atributo DataValueField . O DataValueField atributo
está definido como o CategoryID como definir a classe de Category (mostrado acima).
AddProductPrice.Text, DropDownAddCategory.SelectedValue,
ProductImage.FileName);
Se com êxito, o código adiciona o novo produto no banco de dados, a página será recarregada
com o valor de seqüência de caracteres de consulta ProductAction=add.
Response.Redirect(pageUrl + "?ProductAction=add");
175
string productAction = Request.QueryString["ProductAction"];
if (productAction == "add")
{
}
if (productAction == "remove")
{
Executando o aplicativo
Você pode executar o aplicativo agora para ver como você pode adicionar, excluir e atualizar itens
no carrinho de compras. O total de carrinho compras irá refletir o custo total de todos os itens no
carrinho de compras.
176
A página login. aspx é exibida.
5. Na parte superior da próxima página, selecione o link Admin para navegar para a página
AdminPage.aspx .
177
6. Para testar a validação de entrada, clique no botão Adicionar produto sem adição de
quaisquer detalhes do produto.
178
8. Selecione produtos do menu de navegação superior para ver o novo produto que você
adicionou.
179
10. Na seção Remover produto da página, selecione o novo produto que você adicionou no
DropDownListBox.
11. Clique no botão Remover produto para remover o novo produto da aplicação.
12. Selecione os produtos no menu de navegação superior para confirmar que o produto foi
removido.
Resumo
Neste tutorial, você acrescentou uma função de administrador e um usuário administrativo, acesso
restrito para a pasta de administração e a página e fornecido a navegação para o papel de
administrador. Você usou a vinculação do modelo para preencher um controle DropDownList
com os dados. Você implementou o controle FileUpload e controles de validação. Além disso,
você aprendeu como adicionar e remover produtos de um banco de dados. No próximo tutorial,
você aprenderá como implementar roteamento do ASP.NET.
180
09 - Roteamento de URL
Neste tutorial, você modificará o aplicativo de exemplo do Wingtip Toys para oferecer suporte a
roteamento de URL. Roteamento permite que seu aplicativo da web usar URLs que são melhor
suportados pelos motores de busca, amigável e mais fácil de lembrar. Este tutorial baseia-se no
tutorial anterior "Associação e administração" e faz parte da série tutorial Wingtip Toys.
Por padrão, o modelo de formulários da Web inclui URLs amigáveis do ASP.NET. Grande parte do
trabalho básico de roteamento irão ser implementado usando URLs amigáveis. No entanto, neste
tutorial, você irá adicionar capacidades de roteamento personalizadas.
http://localhost:1234/ProductDetails.aspx?ProductID=2
Personalizando o roteamento de URL, o aplicativo de exemplo do Wingtip Toys vai ligar para o
mesmo produto utilizando uma maneira mais fácil de ler a URL:
http://localhost:1234/Product/Convertible%20Car
Rotas
Uma rota é um padrão de URL que é mapeado para um manipulador. O manipulador pode ser um
arquivo físico, como um arquivo. aspx em um aplicativo de formulários da Web. Um manipulador
também pode ser uma classe que processa a solicitação. Para definir uma rota, você deve criar uma
181
instância da classe Route especificando o padrão de URL, o manipulador e, opcionalmente, um
nome para a rota.
Você pode adicionar a rota para o aplicativo, adicionando o objeto de Route para a propriedade de
Routes estática da classe RouteTable . A propriedade de rotas é RouteCollection .
Padrões de URL
Um padrão de URL pode conter valores literais e variáveis espaços reservados (referidos como
parâmetros de URL). Os literais e espaços reservados estão localizados em segmentos da URL que
são delimitados por um caractere de barra (/).
Quando é feita uma solicitação para seu aplicativo da web, o URL é analisada em segmentos e
espaços reservados, e os valores de variáveis são fornecidos para o manipulador de solicitações.
Este processo é semelhante à maneira como os dados em uma seqüência de caracteres de consulta
são analisados e passados para o manipulador de solicitações. Em ambos os casos, informações de
variável são incluídas na URL e passadas para o manipulador na forma de pares chave-valor. Para
seqüências de caracteres de consulta, tanto as chaves e os valores estão na URL. Para rotas, as
chaves são os nomes de placeholder definidos no padrão de URL, e apenas os valores são na URL.
Em um padrão de URL, você definir espaços reservados, colocando-os entre chaves ( { e } ). Você
pode definir mais de um espaço reservado em um segmento, mas os espaços reservados devem
ser separados por um valor literal. Por exemplo, {language}-{country}/{action} é um padrão de
rota válida. No entanto, {language}{country}/{action} não é um padrão válido, porque não há
nenhum valor literal ou delimitador entre os espaços reservados. Portanto, roteamento não pode
determinar onde separar o valor para o espaço reservado de linguagem de valor para o espaço
reservado do país.
Antes que você pode incluir rotas para páginas do aplicativo de exemplo Wingtip Toys, você deve
registrar as rotas quando o aplicativo for iniciado. Para registrar as rotas, você modificará o
manipulador de evento Application_Start .
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Optimization;
182
using System.Web.Routing;
using System.Web.Security;
using System.Web.SessionState;
using System.Data.Entity;
using WingtipToys.Models;
using WingtipToys.Logic;
namespace WingtipToys
{
public class Global : HttpApplication
{
{
// Code that runs on application startup
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
Database.SetInitializer(new ProductDatabaseInitializer());
roleActions.createAdmin();
// Add Routes.
RegisterCustomRoutes(RouteTable.Routes);
}
{
routes.MapPageRoute(
"ProductsByCategoryRoute",
"Category/{categoryName}",
"~/ProductList.aspx"
183
);
routes.MapPageRoute(
"ProductByNameRoute",
"Product/{productName}",
"~/ProductDetails.aspx"
);
}
}
Quando começa a aplicação da amostra a Wingtip Toys, ele chama o manipulador de evento
Application_Start . No final deste manipulador de evento, o método RegisterCustomRoutes é
chamado. O método RegisterCustomRoutes adiciona cada rota, chamando o método MapPageRoute
do objeto RouteCollection . Rotas são definidas usando um nome de rota, uma URL de rota e um
URL de física.
routes.MapPageRoute(
"ProductsByCategoryRoute",
"Category/{categoryName}",
"~/ProductList.aspx"
);
O segundo parâmetro da rota inclui um valor dinâmico especificado por chaves ( { }). Neste caso, o
categoryName é uma variável que será usada para determinar o caminho de roteamento adequado.
Opcional
Você pode encontrá-lo mais fácil de gerenciar o seu código, movendo o método
RegisterCustomRoutes para uma classe separada. Na pasta lógica , crie uma classe separada de
RouteActions . Mudar o método de RegisterCustomRoutes acima do arquivo Global.asax.cs para a
nova classe RoutesActions . Use a classe RoleActions e o método de createAdmin como um
exemplo de como chamar o método RegisterCustomRoutes do arquivo Global.asax.cs .
184
Você também deve ter notado o método RegisterRoutes chamar usando o objeto de RouteConfig
no início do manipulador de evento Application_Start . Essa chamada é feita para implementar
roteamento padrão. Foi incluído como código padrão quando você criou o aplicativo usando o
modelo de formulários da Web do Visual Studio.
Como mencionado acima, rotas podem ser definidas. O código que você adicionou ao
manipulador de evento Application_Start no arquivo Global.asax.cs carrega as rotas definíveis.
Rotas de configuração
Rotas exigem que você adicionar código adicional. Neste tutorial, você usará a vinculação do
modelo para recuperar um objeto RouteValueDictionary que é usado ao gerar as rotas usando
dados de um controle de dados. RouteValueDictionary irá conter uma lista de nomes de produtos
que pertencem a uma categoria específica de produtos. É criado um link para cada produto com
base nos dados e rota.
Em seguida, você vai atualizar o aplicativo para usar o ProductsByCategoryRoute para determinar a
rota correta para incluir para cada link de categoria de produto. Você também vai atualizar a
página ProductList para incluir um link encaminhado para cada produto. Os links serão exibidos
como eram antes da alteração, porém os links agora irá usar o roteamento de URL.
<asp:ListView ID="categoryList"
ItemType="WingtipToys.Models.Category"
runat="server"
SelectMethod="GetCategories" >
<ItemTemplate>
185
</ItemTemplate>
<ItemSeparatorTemplate> | </ItemSeparatorTemplate>
</asp:ListView>
<ItemTemplate>
<td runat="server">
<table>
<tr>
<td>
<a href="<%#: GetRouteUrl("ProductByNameRoute", new {productName =
Item.ProductName}) %>">
<image src='/Catalog/Images/Thumbs/<%#:Item.ImagePath%>'
width="100" height="75" border="1" />
</a>
</td>
</tr>
<tr>
<td>
<a href="<%#: GetRouteUrl("ProductByNameRoute", new {productName =
Item.ProductName}) %>">
<%#:Item.ProductName%>
</a>
<br />
<span>
<b>Price: </b><%#:String.Format("{0:c}", Item.UnitPrice)%>
</span>
<br />
<a href="/AddToCart.aspx?productID=<%#:Item.ProductID %>">
<span class="ProductListItem">
<b>Add To Cart<b>
</span>
</a>
186
</td>
</tr>
<tr>
<td> </td>
</tr>
</table>
</p>
</td>
</ItemTemplate>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using WingtipToys.Models;
using System.Web.ModelBinding;
using System.Web.Routing;
{
var _db = new WingtipToys.Models.ProductContext();
IQueryable<Product> query = _db.Products;
187
query = query.Where(p => p.CategoryID == categoryId);
}
if (!String.IsNullOrEmpty(categoryName))
{
query = query.Where(p =>
String.Compare(p.Category.CategoryName,
categoryName) == 0);
}
return query;
{
var _db = new WingtipToys.Models.ProductContext();
IQueryable<Product> query = _db.Products;
if (productId.HasValue && productId > 0)
{
query = query.Where(p => p.ProductID == productId);
}
else if (!String.IsNullOrEmpty(productName))
{
query = query.Where(p =>
String.Compare(p.ProductName, productName) == 0);
188
}
else
{
query = null;
}
return query;
Executando o aplicativo
4. Clique no link que contém o nome do primeiro carro listado na página ("Carro
conversível") para exibir os detalhes do produto.
A URL a seguir (usando seu número de porta) é exibida para o navegador:
http://localhost:1234/Product/Convertible%20Car
5. Em seguida, insira a seguinte URL não roteado (usando seu número da porta) no
navegador:
http://localhost:1234/ProductDetails.aspx?ProductID=2
O código ainda reconhece uma URL que inclui uma seqüência de caracteres de consulta, para o
caso em que um usuário tem um link marcado.
Resumo
Neste tutorial, você adicionou rotas para categorias e produtos. Você aprendeu como rotas podem
ser integradas com os controles de dados que usam vinculação do modelo. No próximo tutorial,
você irá implementar manipulação de erro global.
189
190
10 - Tratamento de erros do ASP.NET
Neste tutorial, você modificará o aplicativo de exemplo do Wingtip Toys para incluir a manipulação
de erro e log de erro. Tratamento de erros permite que o aplicativo graciosamente manipular erros
e exibir mensagens de erro em conformidade. Log de erro permitirá que você a localizar e corrigir
erros que ocorreram. Este tutorial baseia-se no tutorial anterior "Roteamento de URL" e faz parte
da série tutorial Wingtip Toys.
Visão geral
Aplicativos ASP.NET devem ser capazes de manipular erros que ocorrem durante a execução de
uma maneira consistente. O ASP.NET usa o common language runtime (CLR), que fornece uma
maneira de notificar aplicativos de erros de maneira uniforme. Quando ocorre um erro, uma
exceção é Descartado. Uma exceção é qualquer erro, condição ou comportamento inesperado que
encontra um aplicativo.
No .NET Framework, uma exceção é um objeto que herda da classe System.Exception . Uma
exceção é lançada a partir de uma área de código onde ocorreu um problema. A exceção é
passada para cima na pilha de chamadas para um lugar onde o aplicativo fornece o código para
manipular a exceção. Se o aplicativo não manipula a exceção, o navegador é forçado para exibir os
detalhes do erro.
Classe de exceção
A classe de exceção é a classe base da qual exceções herdam. A maioria dos objetos de exceção
são instâncias de uma classe derivada da classe de exceção, como a classe
ArgumentNullException , IndexOutOfRangeException classe ou classe SystemException . A classe
191
de exceção tem propriedades, como a propriedade StackTrace , a InnerException Propriedade e a
propriedade de Message , que fornecem informações específicas sobre o erro que ocorreu.
Em um aplicativo de formulários da Web ASP.NET, exceções podem ser tratadas com base em uma
hierarquia de tratamento específico. Uma exceção pode ser tratada nos seguintes níveis:
Nível de aplicativo
Nível de página
Código nível
Quando um aplicativo manipula exceções, informações adicionais sobre a exceção que é herdada
da classe Exception muitas vezes podem ser recuperadas e exibidas para o usuário. Além de
aplicação, página e nível de código, você também pode tratar exceções no nível de módulo HTTP e
usando um manipulador personalizado de IIS.
Você pode manipular erros padrão e erros HTTP, adicionando uma seção customErrors no arquivo
Web. config . A seção customErrors permite que você especifique uma página padrão que os
usuários serão redirecionados para quando ocorre um erro. Ele também permite que você
especifique as páginas individuais para erros de código de status específico.
<configuration>
<system.web>
<customErrors mode="On" defaultRedirect="ErrorPage.aspx?handler=customErrors
%20section%20-%20Web.config">
<error statusCode="404" redirect="ErrorPage.aspx?msg=404&handler=customErrors
%20section%20-%20Web.config"/>
</customErrors>
</system.web>
</configuration>
Infelizmente, quando você usar a configuração para redirecionar o usuário para uma página
diferente, você não tem os detalhes do erro que ocorreu.
192
No entanto, você pode interceptar erros que ocorrem em qualquer lugar em seu aplicativo
adicionando código para o manipulador Application_Error no arquivo global. asax .
if (exc is HttpUnhandledException)
{
// Pass the error on to the error page.
Server.Transfer("ErrorPage.aspx?handler=Application_Error%20-%20Global.asax",
true);
}
Um manipulador de nível de página retorna o usuário para a página onde o erro ocorreu, mas
porque instâncias de controles não são mantidas, já não haverá nada na página. Para fornecer os
detalhes de erro para o usuário do aplicativo, você deve escrever especificamente os detalhes do
erro para a página.
Você normalmente usaria um manipulador de erro de nível de página para registrar erros não
tratados ou para levar o usuário para uma página que pode exibir informações úteis.
Este exemplo de código mostra um manipulador para o evento de erro em uma página da Web do
ASP.NET. Esse manipulador captura todas as exceções que não são manipuladas já dentro
try/catch blocos página.
Depois que você lidar com um erro, você deve apagá-lo chamando o método ClearError do
objeto Server (classeHttpServerUtility ), caso contrário, você verá um erro que ocorreu
anteriormente.
193
Código manipulação de erro de nível
A instrução try-catch consiste de um bloco try, seguido por um ou mais catch cláusulas que
especificam os manipuladores para diferentes exceções. Quando uma exceção é Descartado, o
common language runtime (CLR) procura a instrução catch que manipula a exceção. Se o método
atualmente em execução não contiver um bloco catch, o CLR Olha para o método que chamou o
método atual e assim por diante, até a pilha de chamada. Não se for encontrado nenhum bloco
catch, o CLR exibe uma mensagem de exceção sem tratamento para o usuário e interrompe a
execução do programa.
O exemplo de código a seguir mostra uma maneira comum de usar try/catch/finally para
manipular erros.
try
{
file.ReadBlock(buffer, index, buffer.Length);
}
catch (FileNotFoundException e)
{
Server.Transfer("NoFileErrorPage.aspx", true);
}
catch (System.IO.IOException e)
{
Server.Transfer("IOErrorPage.aspx", true);
}
finally
{
if (file != null)
{
file.Close();
}
}
No código acima, o bloco try contém o código que precisa ser protegido contra uma possível
exceção. O bloco é executado até que uma exceção é Descartado ou o bloco é concluído com
êxito. Se uma exceção IOException ou uma FileNotFoundException exceção ocorre, a execução é
transferida para uma página diferente. Em seguida, o código contido no finally bloco é executado,
se ocorreu um erro ou não.
194
1. Botão direito do mouse a pasta lógica e em seguida selecione Add -> New Item.
Caixa de diálogo Add New Item é exibida.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
namespace WingtipToys.Logic
{
// Create our own utility for exceptions
public sealed class ExceptionUtility
{
// All methods are static, so this can be private
private ExceptionUtility()
{ }
// Log an Exception
public static void LogException(Exception exc, string source)
{
// Include logic for logging exceptions
// Get the absolute path to the log file
string logFile = "App_Data/ErrorLog.txt";
logFile = HttpContext.Current.Server.MapPath(logFile);
// Open the log file for append and write the log
StreamWriter sw = new StreamWriter(logFile, true);
sw.WriteLine("********** {0} **********", DateTime.Now);
if (exc.InnerException != null)
{
sw.Write("Inner Exception Type: ");
sw.WriteLine(exc.InnerException.GetType().ToString());
sw.Write("Inner Exception: ");
sw.WriteLine(exc.InnerException.Message);
sw.Write("Inner Source: ");
sw.WriteLine(exc.InnerException.Source);
if (exc.InnerException.StackTrace != null)
{
sw.WriteLine("Inner Stack Trace: ");
sw.WriteLine(exc.InnerException.StackTrace);
}
}
195
sw.Write("Exception Type: ");
sw.WriteLine(exc.GetType().ToString());
sw.WriteLine("Exception: " + exc.Message);
sw.WriteLine("Source: " + source);
sw.WriteLine("Stack Trace: ");
if (exc.StackTrace != null)
{
sw.WriteLine(exc.StackTrace);
sw.WriteLine();
}
sw.Close();
}
}
Quando ocorre uma exceção, a exceção pode ser escrita em um arquivo de log de exceção,
chamando o método LogException . Este método usa dois parâmetros, o objeto de exceção e uma
seqüência de caracteres que contém detalhes sobre a origem da exceção. O log da exceção é
gravado para o arquivo ErrorLog. txt na pasta App_Data .
No aplicativo de amostra Wingtip Toys, uma página será usada para exibir erros. A página de erro
é projetada para mostrar uma mensagem de erro de seguro para os usuários do site. No entanto,
se o usuário é um desenvolvedor fazendo uma solicitação HTTP que está sendo servida localmente
na máquina onde vive o código, detalhes de erro adicionais serão exibidos na página de erro.
2. Selecione o Visual c# -> grupo de modelos Web à esquerda. Médio na lista, selecione O
formulário da Web com a página mestra, e denomine ErrorPage. aspx.
3. Clique em Adicionar.
4. Selecione o arquivo site Master como a página mestra e em seguida, escolha OK.
196
<asp:Panel ID="DetailedErrorPanel" runat="server" Visible="false">
<p> </p>
<h4>Detailed Error:</h4>
<p>
<asp:Label ID="ErrorDetailedMsg" runat="server" Font-Size="Small" /><br />
</p>
<h4>Error Handler:</h4>
<p>
<asp:Label ID="ErrorHandler" runat="server" Font-Size="Small" /><br />
</p>
</asp:Content>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using WingtipToys.Logic;
namespace WingtipToys
{
public partial class ErrorPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// Create safe error messages.
string generalErrorMsg = "A problem has occurred on this web site. Please try
again. " +
"If this error continues, please contact support.";
string httpErrorMsg = "An HTTP error occurred. Page Not found. Please try
again.";
197
string unhandledErrorMsg = "The error was unhandled by application code.";
if (ex.InnerException != null)
{
InnerMessage.Text = ex.GetType().ToString() + "<br/>" +
ex.InnerException.Message;
InnerTrace.Text = ex.InnerException.StackTrace;
}
else
198
{
InnerMessage.Text = ex.GetType().ToString();
if (ex.StackTrace != null)
{
InnerTrace.Text = ex.StackTrace.ToString().TrimStart();
}
}
}
Atualize a configuração
Atualize a configuração, adicionando uma seção customErrors no arquivo Web. config .
<configuration>
<system.web>
<customErrors mode="On" defaultRedirect="ErrorPage.aspx?handler=customErrors
%20section%20-%20Web.config">
199
<error statusCode="404" redirect="ErrorPage.aspx?
msg=404&handler=customErrors%20section%20-%20Web.config"/>
</customErrors>
</system.web>
</configuration>
A seção customErrors especifica o modo, que é definido como "On". Ela também especifica o
defaultRedirect, que informa o aplicativo qual página para navegar para quando um erro ocorre.
Além disso, você adicionou um elemento de erro específico que especifica como lidar com um erro
404 quando uma página não é encontrada. Mais tarde neste tutorial, você irá adicionar erro
adicional manipulação que irá capturar os detalhes de um erro no nível do aplicativo.
Executando o aplicativo
200
Quando você solicitar a página de NoPage.aspx , que não existe, a página de erro irá mostrar a
mensagem de erro simples e as informações de erro detalhadas se detalhes adicionais estão
disponíveis. No entanto, se o usuário solicitou uma página inexistente de um local remoto, a
página de erro só mostraria a mensagem de erro em vermelho.
Para verificar como seu aplicativo funcionará quando um erro ocorre, você pode criar
deliberadamente as condições de erro no ASP.NET. No aplicativo de amostra Wingtip Toys, você
lançará uma exceção de teste quando a página padrão é carregada para ver o que acontece.
201
É possível criar vários tipos diferentes de exceções. No código acima, você está criando um
InvalidOperationException quando a página Default. aspx é carregada.
Executando o aplicativo
Você pode executar o aplicativo para ver como o aplicativo manipula a exceção.
Nota
Você deve pressionar CTRL + F5 para exibir a página, sem quebrar o código para exibir a fonte do
erro no Visual Studio.
Como você pode ver os detalhes do erro, a exceção foi preso pela customError seção no arquivo
Web. config .
202
2. Adicione um manipulador Application_Error para que ele apareça da seguinte forma:
if (exc is HttpUnhandledException)
{
if (exc.InnerException != null)
{
exc = new Exception(exc.InnerException.Message);
Server.Transfer("ErrorPage.aspx?handler=Application_Error%20-%20Global.asax",
true);
}
}
Executando o aplicativo
Você pode executar o aplicativo para ver os detalhes de erro adicionais fornecidos pela
manipulação de exceção no nível do aplicativo.
203
Adicionando a manipulação de erro de nível de página
Você pode adicionar o tratamento a uma página usando adicionando um atributo ErrorPage da
Directiva @Page da página, ou adicionando um manipulador de evento Page_Error para o code-
behind da página de erro de nível de página. Nesta seção, você irá adicionar um manipulador de
evento Page_Error que irá transferir a execução para a página ErrorPage. aspx .
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WingtipToys
{
public partial class _Default : Page
204
{
protected void Page_Load(object sender, EventArgs e)
{
throw new InvalidOperationException("An InvalidOperationException " +
"occurred in the Page_Load handler on the Default.aspx page.");
}
Executando o aplicativo
205
3. Feche a janela do seu navegador.
Removendo a exceção usada para testes
Para permitir que o aplicativo de exemplo do Wingtip Toys funcionar sem lançar a exceção que
você adicionou anteriormente neste tutorial, remova a exceção.
2. No Page_Load manipulador, remova o código que lança a exceção para que o manipulador
aparece da seguinte maneira:
206
Como mencionado anteriormente neste tutorial, você pode adicionar instruções try/catch para
tentar executar uma seção de código e lidar com o primeiro erro que ocorre. Neste exemplo, você
só irá gravar os detalhes do erro para o arquivo de log de erro para que o erro pode ser revisto
posteriormente.
try
{
using (StreamWriter myWriter = new StreamWriter(objRequest.GetRequestStream()))
{
myWriter.Write(strPost);
}
}
catch (Exception e)
{
// Log the exception.
WingtipToys.Logic.ExceptionUtility.LogException(e, "HttpCall in
PayPalFunction.cs");
}
//Retrieve the Response returned from the NVP API call to PayPal.
HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
string result;
using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
{
result = sr.ReadToEnd();
}
return result;
207
O código acima chama o método de LogException que está contido na classe ExceptionUtility .
Você adicionou o arquivo de classe ExceptionUtility.cs para a pasta lógica no início deste tutorial. O
método LogException usa dois parâmetros. O primeiro parâmetro é o objeto de exceção. O
segundo parâmetro é uma seqüência de caracteres usada para reconhecer a origem do erro.
Como mencionado anteriormente, você pode usar o log de erros para determinar quais erros em
seu aplicativo devem ser fixados primeiro. Claro, somente os erros que foram presos e gravados no
log de erro serão registrados.
Usando o ELMAH
ELMAH (manipuladores e módulos de log de erro) é um recurso de log de erro que você conecte
seu aplicativo ASP.NET como um pacote NuGet. ELMAH fornece os seguintes recursos:
Uma página da web para exibir o log inteiro de recodificado exceções não tratadas.
Uma notificação por email de cada erro no momento em que ele ocorre.
Antes que você possa trabalhar com o ELMAH, você deve instalá-lo. Isto é fácil de usar o instalador
de pacotes NuGet . Como mencionado no início desta série de tutoriais, NuGet é uma extensão do
Visual Studio que torna mais fácil para instalar e atualizar bibliotecas de código aberto e
ferramentas no Visual Studio.
209
4. Você precisará ter uma conexão de internet para baixar o pacote.
7. Se Visual Studio solicita que você recarregar todos os arquivos abertos, selecione "Sim para
todos".
8. O pacote do ELMAH adiciona entradas por si no arquivo Web. config na raiz do seu projeto.
Se Visual Studio te perguntar se você deseja recarregar o arquivo Web. config modificado, clique
em Sim.
210
ELMAH está agora pronto para armazenar qualquer sem tratamento de erros que ocorrem.
Exibindo o log ELMAH é fácil, mas primeiro, você criará uma exceção não tratada que será gravada
no log do ELMAH.
2. Para gravar uma exceção não tratada no log ELMAH, navegue no seu navegador para o
seguinte URL (usando seu número da porta):
http://localhost:1234/NoPage.aspx
A página de erro será exibida.
3. Para exibir o log do ELMAH, navegue no seu navegador para o seguinte URL (usando seu
número da porta):
http://localhost:1234/ELMAH.axd
Resumo
Neste tutorial, você aprendeu sobre tratamento de erros no nível do aplicativo, o nível de página e
o nível de código. Você também aprendeu como log de erros manipulados e não tratados para
revisão posterior. Você adicionou o utilitário ELMAH para fornecer registro de exceção e
notificação para seu aplicativo usando o NuGet. Além disso, você aprendeu sobre a importância
das mensagens de erro seguras.
211
Conclusão
Isso completa a 4.5 ASP.NET Web Forms e Visual Studio 2013 - série de tutoriais Wingtip Toys. Para
obter mais informações sobre os novos recursos de formulários da Web disponíveis em 4.5 de
ASP.NET e Visual Studio 2013, consulte ASP.NET e Web Tools para Visual Studio 2013 notas de
lançamento.
Recursos adicionais
Detalhes de erro de log com monitoramento da integridade ASP.NET
ELMAH
Agradecimentos
Eu gostaria de agradecer as seguintes pessoas que fizeram importantes contribuições para o
conteúdo desta série de tutoriais:
Contribuições da Comunidade
Graham Mendick (@grahammendick)
Visual Studio 2012 relacionados a amostra de código do MSDN: Navegação Wingtip Toys
212
James Chaney (jchaney@agvance.net)
Visual Studio 2012 relacionados a amostra de código do MSDN: 4.5 ASP.NET Web Forms
Tutorial Series no Visual Basic
Andrielle Azevedo - Microsoft técnico público contribuinte (twitter: @driazevedo)
Visual Studio 2012 Tradução: Iniciando com ASP.NET Web Forms 4.5 – Parte 1 – Introdução e
Visão Geral
Informações do autor
Erik Reitan – Erik Reitan é um escritor sênior de programação da Microsoft. Durante seu tempo
livre ele gosta de desenvolvimento de aplicativos do Windows Phone e Windows 8. Siga ele no
Twitter em @ReitanErik.
213