WebMatrix - Criando uma Loja Virtual - Definindo o banco de dados, as categorias e os produtos - 2


Na primeira parte deste artigo lançamos os fundamentos da nossa loja virtual. Vamos agora incluir um banco de dados em nosso projeto.

Incluindo um banco de dados

Vamos incluir um banco de dados SQL Server Compact usando o IDE do WebMatrix. Este banco de dados irá armazenar todos os dados necessários para a nossa aplicação o que inclui dados de produtos, clientes, pedidos.

Se você for usar a versão 2 do WebMatrix para criar o projeto terá que fazer o seguinte ajuste:

Atenção!! - Para evitar erros na abertura do banco de dados em todas as páginas que houve a abertura do banco de dados (Database.Open) deverá ser incluida a declaração @using WebMatrix.Data; no início da página.

- Abra o projeto TecnoSite no WebMatrix e clique no Seletor DataBases para ativar o menu apropriado;

- A seguir clique no item New DataBase;

- Será criado um banco de dados com o nome do nosso projeto e extensão .sdf: TecnoSite.sdf (para alterar esse nome clique com o botão direito do mouse sobre ele e selecione a opção Rename)

Agora vamos criar agora as tabelas necessárias para o catálogo de produtos que desejamos exibir na loja.

Vamos precisar de duas tabelas:

  1. A primeira tabela irá conter os produtos e será chamada Produtos
  2. A segunda tabela irá conter as categorias a que cada produto pertence e será chamada Categorias

Selecione o banco de dados TecnoSite.sdf e no menu clique em New Table;

Usando o editor integrado ao ambiente WebMatrix e inclua os campos conforme mostra a figura abaixo na tabela Produtos: (para criar uma nova coluna clique em New Column)

Após terminar a definição salve a tabela com o nome Produtos.

Vamos criar a tabela Categorias usando o mesmo procedimento definindo os campos abaixo nesta tabela:

Ao final salve a tabela com o nome Categorias.

Podemos incluir alguns dados em nossas tabelas clicando com o botão direito do mouse sobre o nome da tabela e selecionando a opção Data e a seguir digitar os valores diretamente no editor WebMatrix;

Vamos fazer isso para a tabela Categorias e incluir algumas categorias conforme abaixo:

Vamos fazer a mesma coisa para a tabela Produtos incluindo alguns produtos conforme abaixo:

Agora que temos as duas tabelas relacionadas preenchidas com alguns dados vamos criar o catálogo de produtos da nossa loja virtual.

Criando o Catálogo de Produtos

O catálogo de produtos pode ser dividido em dois componentes principais:

Como queremos exibir a lista de categorias em cada página, o melhor lugar para fazer isso é no layout da página.

Abra o arquivo _Layout.cshtml que criamos anteriormente na pasta Shared ,e vamos inserir uma referência a uma página parcial contendo a lógica e apresentação para a lista de categorias.

A lista de categorias será exibida em uma coluna no lado esquerdo da página, por isso vamos alterar a marcação dentro _Layout.cshtml conforme o código a seguir:

O conteúdo <div> agora tem duas tags filhas chave:

O chamada do método RenderPage() feita no interior da div "categorias" requisita uma página parcial chamada _Categories.cshtml na pasta /Shared/Partials/.

Nós iremos criar esta página a seguir mas primeiro precisamos adicionar um estilo ao nosso arquivo CSS, a fim formatar a <div> categorias relacionada em uma coluna de 150 pixels de largura para a esquerda da <div> main.

Para fazer isso adicione o seguinte código no arquivo /CSS/Style.css:

Criando a lista de categorias

Vamos criar o arquivo _Categorias.cshtml na pasta /Shared/Partials/ que será solicitado pelo método RenderPage() na página de layout.

Com a pasta Partials selecionada clique no seletor Files e a seguir no menu New File;

Selecione o template CSHTML e informe o nome _Categorias.cshtml e clique em OK;

A seguir vamos incluir o código abaixo neste arquivo:

Neste código, selecionamos todas as categorias do banco de dados (SELECT * FROM Categorias), e então percorremos o resultado da consulta, adicionando cada título da categoria em uma lista não-ordenada HTML na forma de um item da lista.

O conteúdo do item da lista <li> é processado como um hiperlink (<a href) apontando para a página de produtos, que iremos criar mais tarde.

Este hiperlink também passa o valor do campo categoriaTitulo na URL. Ao passar o valor categoriaTitulo em vez de categoriaid, no atributo href do link, somos capaz de fornecer uma url amigável.

Por exemplo, para ver todos os produtos dentro da categoria de Cursos, em vez de exigir o código da categoria(categoriaid) URL: Ex: http://dominio/Produtos/2

O usuário pode navegar diretamente para: http://domain-name/Produtos/Cursos

Esta é uma solução mais limpa, tanto em termos de busca otimizada (Search Engine Optimization - SEO ) como de usabilidade.

No entanto ela requer um pouco de trabalho extra que termos mais tarde, tanto para exibir os produtos dentro da categoria como para garantir que nenhum nome de categoria duplicado seja criado.

Finalmente, vamos adicionar três novos estilos CSS ao nosso arquivo Style.css na pasta /CSS/Style.css conforme abaixo:

Selecione o arquivo Default.chstml e no menu Run selecione um navegador para abrir este arquivo no navegador. O resultado pode ser visto na figura abaixo:

O conteúdo desta página está sendo combinado a partir de três fontes (não incluindo a folha de estilo) pelo WebMatrix antes de ser enviado para o navegador do usuário.

  1. O cabeçalho e rodapé vêm do layout de página (_Layouts.cshtml);
  2. A listagem da categoria é gerada por uma página parcial (_Categorias.cshtml);
  3. O conteúdo na parte principal da página é gerada pelo arquivo Default.cshtml;

Esta técnica de layout de página é muito útil, pois agora podemos exibir o cabeçalho, rodapé e as categorias em cada página, simplesmente definindo o layout da página em /Shared/Layouts/_Layout.cshtml.

Se quero fazer uma alteração no projeto no futuro, podemos alterar somente arquivo uma em vez de ter que mudar cada página do site.

Criando a página de produtos

A página exibindo os produtos deverá exibir um resumo de todos os produtos dentro da categoria selecionada.

cada resumo do produto irá conter um link para uma página de detalhes do produto onde o usuário poderá efetuar um pedido.

Vamos criar um novo arquivo na raiz do site chamado Produtos.cshtml.

Clique no seletor Files e a seguir no menu File-> New File;

A seguir selecione o template CSHTML, informe o nome Produtos.cshtml e clique em OK;

A seguir digite o seguinte bloco de código no topo da página deste arquivo:

@{
Layout = "~/Shared/Layouts/_Layout.cshtml";
var categoriaTitulo = UrlData[0];

if (categoriaTitulo.IsEmpty())
{
   Response.Redirect("/Default");
}

Page.Title = categoriaTitulo;
var db = Database.Open("TecnoSite");

var sqlSelect = "SELECT produtoid, titulo, preco FROM Produtos " +
                       "LEFT OUTER JOIN Categorias ON Produtos.categoria = Categorias.categoriaid " +
                      "WHERE Categorias.categoriaTitulo = @0";

var produtos = db.Query(sqlSelect, categoriaTitulo);
}
<div id="contentTitle">
<h1>@categoriaTitulo</h1>
</div>
@if (produtos.Count() == 0)
{
<p>
   Nenhum encontrado nesta categoria.
   Tente navegar em uma das categorias do menu.
</p>
}
else
{
<ul id="listaprodutos">
@foreach (var item in produtos) {
<li>
  <h3>
     <a href="/ProdutoDetalhes/@item.produtoid">@item.titulo</a>
  </h3>
  <p class="preco">
      R$@item.preco
  </p>
  <p>
    <a href="/ProdutoDetalhes/@item.produtoid" class="detalhesButton">
    mais detalhes
    </a>
  </p>
</li>
}
</ul>
}

Neste bloco de código, vamos definir o layout de página, obter o título da categoria a partir da coleção UrlData, que contém todos os dados passados como parte da URL, e atribuí-lo a uma variável, categoriaTitulo.

Em seguida, vamos verificar se o valor da variável categoriaTitulo não está vazio, redirecionando o usuário de volta para a página padrão se isto for verdade.

var categoriaTitulo = UrlData[0];

if (categoriaTitulo.IsEmpty())
{
Response.Redirect("/Default");
}

Definimos então a propriedade Title da página para categoriaTitulo e abrimos a conexão com o banco de dados TecnoSite.sdf:

Page.Title = categoriaTitulo;
var db = Database.Open("TecnoSite");

Após isso, criamos o SQL necessário para recuperar o produtoid,titulo e preco de todos os produtos dentro da categoria selecionada.

A fim de fornecer usuário uma URL amigável, passamos apenas o título da categoria para a página a partir do link na lista de categorias.

Porque nós armazenamos apenas o ID da categoria para cada produto na tabela Produtos , precisamos executar uma SQL LEFT OUTER JOIN entre produtos e categorias na instrução SELECT , a fim de usar o Categorias.categoriaTitulo como critério na cláusula WHERE.

Ao final chamamos o método Query() contra o banco de dados passando a instrução SQL e o categoriaTitulo (que é inserido na consulta em lugar do 0@) como parâmetro:

var sqlSelect = "SELECT produtoid, titulo, preco FROM Produtos " +
"LEFT OUTER JOIN Categorias ON Produtos.categoria = Categorias.categoriaid " +
"WHERE Categorias.categoriaTitulo = @0";

var produtos = db.Query(sqlSelect, categoriaTitulo);

Agora vamos adicionar algum código de marcação e Razor ao corpo da página para exibir um resumo dos produtos contidos dentro da categoria selecionada.

Cada resumo do produto será exibido dentro de uma lista HTML não ordenada e irá indicar o título e o preço do produto.

O título do produto irá fornecer um link para uma página de detalhes do produto, que iremos criar mais a frente.

A partir da página Detalhes do produto, o cliente será capaz de adicionar o item ao carrinho de compras.

Nós também irá fornecer um link 'Mais Detalhes' para a mesma página por uma questão de clareza, no caso de o usuário não perceber que o título do produto é um hiperlink.

Neste código adicionamos uma tag de cabeçalho <h1> para a página, exibindo o título da categoria. Após isso, nós verificamos o resultado de uma chamada para o método count() de IEnumerable<dynamic> retornada pelo método Query() do objeto de banco de dados para ver se as linhas foram devolvidas (ou seja, se a categoria selecionada contém pelo menos um produto).

Se não houver linhas vamos mostrar uma mensagem útil para o usuário:

@if (produtos.Count() == 0)
{
<p>
Nenhum encontrado nesta categoria.
Tente navegar em uma das categorias do menu.
</p>
}

Se pelo menos um produto for encontrado para a categoria selecionada então percorremos o resultado da consulta usando um laço for each exibindo cada produto em uma lista não ordenada:

<ul id="listaprodutos">
@foreach (var item in produtos) {
<li>
<h3>
<a href="/ProdutoDetalhes/@item.produtoid">@item.titulo</a>
</h3>
<p class="preco">
R$@item.preco
</p>
<p>
<a href="/ProdutoDetalhes/@item.produtoid" class="detalhesButton">
mais detalhes
</a>
</p>
</li>
}
</ul>

O resultado pode ser visto a seguir onde temos:

1- A página de apresentação do site exibindo as categorias e um texto fixo:

A relação de produtos para uma categoria que foi selecionada:

Criando a página de detalhes do produto

A página final do nosso catálogo de produtos irá exibir os detalhes do produto completo e fornecer ao usuário uma maneira para adicionar o produto ao carrinho de compras. Iremos implementar o carrinho de compras e check-out em outro artigo, neste artigo vamos simplesmente fornecer a interface do usuário na página de produtos para facilitar este processo.

O código da página é bastante simples, vamos criar uma página chamada ProdutoDetalhes na raiz do site, e substituir o conteúdo gerado automaticamente com o seguinte bloco de código:

@{
Layout = "~/Shared/Layouts/_Layout.cshtml";
var produtoID = !UrlData[0].IsEmpty() ? UrlData[0] : "0";
var db = Database.Open("TecnoSite");
var sqlSelect = "SELECT * FROM Produtos WHERE produtoid = @0";
var produto = db.QuerySingle(sqlSelect, produtoID);
}
@if (produto == null)
{
<p>
  Não foi possível localizar detalhes do produto
  tente selecionar uma das categorias na lista.
</p>
}
else
{
Page.Title = produto.titulo;
<text>
<h1>@produto.titulo</h1>
    <div id="produtoDetalhes">
        <p class="preco">
           R$@produto.preco
        </p>
        <p>@produto.descricao</p>
    </div>
    <div id="pedido">
    <form action="/Carrinho" method="post">
    <fieldset>
    <legend>Pedido</legend>
    <p>
       @Html.Hidden("produtoid", produtoID)
       @Html.Hidden("preco", produto.preco)
       <input type="submit" value="Incluir no Carrinho" />
    </p>
   </fieldset>
</form>
</div>
</text>
}

Vamos entender o código:

Neste código, vamos definir o layout da página e obter o produtoid a partir de UrlData.

Usamos o operador Ternário C# (?:) para atribuir o valor do parâmetro urlData[0] para o a variável produtoID se UrlData[0] não contiver uma cadeia vazia.

Se UrlData [0] contém uma string vazia, ou seja, nenhuma identificação do produto foi passada na URL, vamos definir a variável produtoID para "0".

Como a coluna Produtos.produtoid foi definida como um campo identity, podemos ter certeza de que nunca haverá uma linha de produtos na tabela com um produtoID igual a zero.

var = productID! UrlData [0]. IsEmpty ()? UrlData [0]: "0";

Em seguida, abrimos uma conexão com o banco para TecnoSite, e obtemos uma linha contendo o produtoID, utilizando o método QuerySingle() no objeto de banco de dados, passando a variável que contém a instrução SQL SELECT e o produtoid.

Se nenhum produto for retornado pela consulta avisamos o usuário:

@if (produto == null)
{
<p>
Não foi possível localizar detalhes do produto
tente selecionar uma das categorias na lista.
</p>
}

Para levar em conta um produto retornado, vamos definir o título da página para o valor do título do produto e renderizar os detalhes do produto para a página.

Exibimos os detalhes do produto e também exibimos um formulário de pedido.

O formulário atual possui apenas dois campos ocultos que armazenam a identificação do produto e preço, e, por último, um botão Enviar com o qual o cliente pode adicionar o produto ao carrinho de compras. Note-se que o estamos postando os dados para a página Carrinho.cshtml que iremos criar mais adiante.

Para concluir temos que incluir no arquivo /CSS/Style.css os seguintes estilos para a folha de estilo padrão:

Selecionando o arquivo Default.cshtml e clicando no menu Run e no navegador de sua escolha. Após clicar no link para detalhes de um produto iremos obter o seguinte resultado:

Dessa forma já implementamos a exibição das categorias, dos produtos e seus detalhes, no próximo artigo iremos incluir os recursos das redes sociais, a busca no catálogo de produtos e o tratamento de erros.

Aguarde a segunda parte do artigo: WebMatrix - Criando uma Loja Virtual - 3

Salmos 15:1 Quem, Senhor, habitará na tua tenda? quem morará no teu santo monte?

Salmos 15:2 Aquele que anda irrepreensivelmente e pratica a justiça, e do coração fala a verdade;

Salmos 15:3 que não difama com a sua língua, nem faz o mal ao seu próximo, nem contra ele aceita nenhuma afronta;

Salmos 15:4 aquele a cujos olhos o réprobo é desprezado, mas que honra os que temem ao Senhor; aquele que, embora jure com dano seu, não muda;

Salmos 15:5 que não empresta o seu dinheiro a juros, nem recebe peitas contra o inocente. Aquele que assim procede nunca será abalado.

Referências:


José Carlos Macoratti