.NET

16 nov, 2010

Criando aplicativos web com WebMatrix e ASP.NET Razor – Parte 03

Publicidade

Leia os dois primeiros artigos da série:

Após conhecer o WebMatrix um pouco mais de perto e ter uma introdução ao universo do ASP.NET Razor, a partir do artigo de hoje, dessa série, vamos conhecer conhecer algumas características específicas do Razor. No artigo de hoje especificamente, veremos como é possível criar aplicações visualmente ricas e consistentes utilizando ASP.NET Razor e WebMatrix.

Se você já trabalha com WebForms ou ASP.NET MVC, já deve estar acostumado com os famosos Web User Controls. Os WUCs são estruturas que suportam textos, código de marcação (HTML/XHTML) e codificação em geral, de forma que esta estrutura pode ser inserida no contexto de outra página (uma ASPX, por exemplo) no momento que for conveniente, e quando a página mãe for chamada pelo browser, esta exibe o conteúdo do WUC no local específico onde ele foi inserido.

O ASP.NET Razor trouxe um mecanismo parecido com os WUCs (muito provavelmente baseado neles), os “blocos de conteúdos”. Assim como os WUCs, estes blocos podem hospedar textos, imagens, vídeos, código, etc. e, podem ser chamados em quantas páginas forem necessárias. Assim, temos a possibilidade de criar sites com aparências consistentes e reaproveitáveis, isso sem falar na facilidade de manutenção de nossas views, já que é mais fácil resolver problemas isolados do que um grande problema. Para que possamos entender melhor este conceito, vejamos a Figura 1.

Figura 1: Esquema funcional para inserção de blocos (Fonte: http://www.asp.net/webmatrix)

Realmente, “uma imagem vale mais que mil palavras”. Olhando a Figura 1 fica fácil notar a utilização de blocos de conteúdos sendo inseridos ao longo da página index.cshtml. Esta inserção é realizada utilizando a diretiva @RenderPage(). Assim, podemos criar nossas “páginas” com conteúdo específico e “renderizá-las” na página principal.

O exemplo da Figura 1 apresenta a inserção de um “Head” e de um “Footer“. Neste artigo, vamos construir um aplicativo de menu contextualizado onde, na tela de login, dependendo do nível do usuário que faz o acesso ao sistema, o menu administrativo apresenta opções diferentes.

Uma observação importante em relação a Figura 1 é que as páginas que são especificadas com o caracter “_” na frente do nome não são interpretadas pelo browser, entretanto, podem ser invocadas por RenderPage(), assim, o conselho é: páginas com conteúdo isolado devem ser nomeadas com underline na frente do nome (no exemplo da Figura 1: _footer e _header).

Criando nossa aplicação de exemplo

Com os parâmetros e a situação problema definidos, vamos à implementação de nosso exemplo. Abra o WebMatrix Beta 2 (você pode baixá-lo através do Microsoft Web Platform clicando aqui) e crie um projeto do tipo “Site from Template” > “Empty Site“. A Figura 2 apresenta este processo.

Figura 2: Criando o projeto

Muito bem, como criaremos uma aplicação de Login, o primeiro passo é criar um banco de dados com uma tabela de usuários para que a verificação dos dados do usuário seja realizada. Para isso, vamos até a guia “Database” > “New Database” e criar nossa tabela. O processo é apresentado em detalhes na Figura 3.

Figura 3: Criando o banco de dados da aplicação

Ao clicar no botão “New Database” o bloco apresentado em vermelho à esquerda apresenta a base de dados criada (que possui o mesmo nome da aplicação criada). Note que o botão com a opção “New Table” é habilitado assim que selecionamos a base de dados “AppGrafica.sdf“. Em seguida, o que temos a fazer é criar nossa tabela de usuários clicando neste botão. A tabela terá 5 campos (e será chamada de tbUsuarios). São eles: IDUsuario, Nome, Username, Password e Nivel, conforme apresenta a Figura 4.

Figura 4: Criando a tabela “tbUsuarios”

Os campos da tabela podem ser inseridos clicando-se na opção “New Columns“. A configuração de cada campo pode ser visualizada na parte inferior vermelha. Ao clicar-mos na opção “Save“, a janela para definição do nome da tabela se abre, como pode ser visto no canto superior direito da Figura 4.

Neste ponto já temos nossa base de dados criada e devidamente configurada. O que precisamos agora é populá-la com os dados de usuários. Vamos inserir dois usuários, um com o nível 1 (administrador) e outro com o nível 2 (colaborador). Evidentemente que o administrador tem acesso a todas as rotinas do sistema e o colaborador a algumas rotinas apenas. Assim, utilizaremos o recurso RenderPage() pra trazer o menu de opções adequado ao usuário logado.

A Figura 5 apresenta a tabela populada com dois usuários, um administrador e outro colaborador para que possamos fazer todos os testes.

Figura 5: Tabela populada com dados de usuários fictícios

Criando as páginas de menu

Vamos, antes de mais nada, criar nossas páginas de menus. Estas serão chamadas “_menuAdmin.cshtml” e “_menuColab.cshtml“. Para configurar nosso menu visualmente utilizaremos um arquivo do tipo CSS chamado “Estilos.css“. A Listagem 1 apresenta o código da página “_menuAdmin.cshtml“.

<link rel="stylesheet" type="text/css" href="CSS/Estilos.css" />

<div id="BoxMenu">
<ul id="menuAdmin">
<li>
<a href="#">
Posts
</a>
</li>
<li>
<a href="#">
Páginas
</a>
</li>
<li>
<a href="#">
Comentários
</a>
</li>
<li>
<a href="#">
Plugins
</a>
</li>
<li>
<a href="#">
Ferramentas
</a>
</li>
<li>
<a href="#">
Configurações gerais
</a>
</li>
</ul>
</div>

Listagem 1: Estrutura do menu do administrador

Agora que temos a estrutura do menu de administração, podemos construir a estrutura do menu dos usuários com status de colaborador. A Listagem 2 apresenta a estrutura (mais simples) deste menu.

<link rel="stylesheet" type="text/css" href="CSS/Estilos.css" />

<div id="BoxMenu">
<ul id="menuAdmin">
<li>
<a href="#">
Posts
</a>
</li>
<li>
<a href="#">
Páginas
</a>
</li>
</ul>
</div>

Listagem 2: Estrutura do menu de colaborador

Aqui já temos nossos menus criados. Para incrementar um pouco mais nossa aplicação e deixá-la ainda mais dinânica e “plugável”, vamos criar mais três arquivos: dois de header (se o usuário está logado carrega o _headerLogin. Caso contrário, carrega o _headerLogout) e um de rodapé (_footer). A Listagem 3 apresenta a estrutura das três páginas na sequência.

<!------ _headerLogin.cshtml -->
<div>
Painel Administrativo - Você entrou em @{ Datetime.Now }
</div>

<!------ _headerLogout.cshtml -->
<div>
Painel Administrativo
</div>

<!----- _footer.cshtml -->
<div>
2010 - Todos os direitos reservados
</div>

Listagem 3: Códigos das páginas _headerLogin.cshtml, _headerLogout.cshtml e _footer.cshtml

Finalmente, falta-nos a página de configuração gráfica, ou seja, o CSS. A Listagem 4 apresenta a folha de estilos.

h1
{
font-family:"Lucida Sans Unicode", Verdana;
font-size:35px;
letter-spacing:-1px;
font-weigth:bold;
}

#menuAdmin
{
width:200px;
font-size:12px;
color:#999;
font-family:"Lucida Sans Unicode", Verdana;
}

#menuAdmin li {
list-style: none;
margin: 1.0em 0 1.0em 1.0em;
}

#menuAdmin li a
{
border-top:1px solid #ccc;
color:#999;
margin:0px;
padding:0px;
text-decoration:none;
}

#menuAdmin li a:hover
{
border-top:1px solid #333;
color:#333;
margin:0px;
padding:0px;
}

#menuAdmin li a:active
{
border-top:1px solid #333;
color:#333;
margin:0px;
padding:0px;
}

#menuAdmin li a:visited
{
border-top:1px solid #ccc;
color:#999;
margin:0px;
padding:0px;
}

#Geral
{
width:1000px;
margin-left:auto;
margin-right:auto;
text-align:left;
}

#BoxMenu
{
float:left;
width:250px;
}

#BoxConteudo
{
float:right;
width:750px;
}

Listagem 4: Folha de estilos de nossa aplicação

Muito bem, a estrutura de nossa aplicação está pronta. Resta-nos agora “encaixar” o quebra cabeças, ou seja, renderizar as páginas de acordo com o status do usuário logado. Vamos então começar encaixando o rodapé (_footer.cshtml), pois este independe de o usuário estar ou não logado. Para isso, basta indicarmos este arquivo no local apropriado via RenderPage(). A Listagem 5 apresenta a linha da chamada no arquivo “Default.cshtml“.

<center>
@RenderPage("_footer.cshtml")
</center>

Listagem 5: Chamada para renderização do rodapé

Após executarmos nossa página principal (Default.cshtml) com a chamada apresentada na Listagem 5, o resultado apresentado pode ser visualizado na Figura 5.

Figura 5: Resultado da renderização do rodapé

O passo seguinte consiste em efetuarmos a autenticação e, de acordo com o login, exibir o header e o menu adequandos. A Listagem 6 apresenta o processo de autenticação.

@{
var _username = "";
var _password = "";
string mensagemH1 = "";
string mensagemMenu = "";
string nivel = "";

var bd = Database.Open("AppGrafica");

if(IsPost)
{
_username = Request["txtUsername"];
_password = Request["txtPassword"];

var result = bd.Query("SELECT * FROM tbUsuarios WHERE Username = @0 AND Password = @1", _username, _password);
var cont = result.Count();

foreach(var row in result)
{
nivel = row.Nivel.ToString();
}

if(cont == 1) {
mensagemH1 = "_headerLogin.cshtml";

if(nivel == "1"){
mensagemMenu = "_menuAdmin.cshtml";
}
else{
mensagemMenu = "_menuColab.cshtml";
}

}
else {
mensagemH1 = "_headerLogout.cshtml";
}
}
}

Listagem 6: Criando o processo de autenticação e definindo valores

O objetivo deste trabalho não é apresentar os conceitos de acesso a dados, já que falaremos exatamente disso no próximo artigo. Entretanto, em linhas gerais, o que o código da Listagem 6 faz é, em sendo realizado um post, capturar os valores dos campos de texto do fomulário de login, efetuar a consulta na base de dados e verificar se foi retornada uma linha (indicando que o usuário foi localizado) e setar os devidos valores de páginas a serem carregadas. A Listagem 7 apresenta o código final da página “Default.cshtml“, onde efetuaremos o processo de login e carregaremos nossas páginas isoladas.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Painel Administrativo</title>
</head>
<body>
<center>
@{
if(mensagemH1 == "")
{
<text><h1>@RenderPage("_headerLogout.cshtml")</h1></text>
}
else
{
<text><h1>@RenderPage(mensagemH1)</h1></text>
}
}
</center>

<p>
<hr size="1" style="border-bottom:0px; border-left:0px; border-right:0px;" />
</p>

<div id="Geral">

<div id="BoxMenu">

@{
if(mensagemMenu == "")
{
<text>

</text>
}
else
{
<text>
@RenderPage(mensagemMenu)
</text>
}
}

</div>

<div id="BoxConteudo">

@{
if(mensagemH1 == "")
{
<text>
<div id="BoxLogin">
<form method="post" action="">
<table>
<tr>
<td>
Usuário:
</td>
</tr>
<tr>
<td>
<input type="text" name="txtUsername" id="txtUsername" />
</td>
</tr>
<tr>
<td>
Senha:
</td>
</tr><tr>
<td>
<input type="password" name="txtPassword" id="txtPassword" />
</td>
</tr>
<tr>
<td>
<input type="submit" id="btnEntrar" value="Entrar" />
</td>
</tr>
<tr>
<td>

</td>
</tr>
</table>
</form>
</div>
</text>
}
else
{
<text>
<center><img src="Imagens/process.png" /></center>
<p>
<center>Painel Administrativo</center>
</p>
</text>
}
}

</div>

</div>

<br clear="all" />

<p>
<hr size="1" style="border-bottom:0px; border-left:0px; border-right:0px;" />
</p>

<center>
@RenderPage("_footer.cshtml")
</center>

</body>
</html>

Listagem 7: Efetuando o login e carregando as páginas isoladas

Existem alguns aspectos fundamentais que devem analisados no código apresentado pela Listagem 7. Vamos a eles:

  • Linhas 9-18: como nosso cabeçalho é dinâmico, isto é, se estiver “logado” apresenta um cabeçalho e se não estiver logado apresenta outro, o que fazemos é verificar se a variável “mensagemH1” está vindo vazia. Se estiver, significa que o usuário não está logado e deve ser carregada a página “_headerLogout.cshtml“.
  • Linhas 29-43: o que verificamos aqui é o valor que está vindo com a variável “mensagemMenu” e exibe o menu adequado de acordo com o nível do login, como pode ser visto na Listagem 6.
  • Linhas 48-98: verificamos o conteúdo da variável “mensagemH1” e exibe o conteúdo da div “BoxConteudo” conforme a conveniência.
  • Linha 111: finalmente, na linha 111 o que fazemos é carregar o “_footer.cshtml“.

Vamos então aos testes. As Figuras 7, 8, 9 e 10 apresentam os testes realizados.

Figura 7: Efetuando login com dados de administrador, conforme Figura 6

Figura 8: Carregando o painel de administração do administrador

Figura 9: Efetuando login com os dados de colaborador

Figura 10: Exibindo painel de administração do colaborador

Bom pessoal é isso. Espero que este artigo possa continuar ajudando a entender o Razor. Considere usar o WebMatrix na construção de suas aplicações web!