ASP - Enviando Cartões Postais


Neste artigo você vai aprender a criar um serviço de envio de cartões postais usando o ASP. Para tanto deixe-me delinear o escopo do projeto afim de que você não se sinta perdido e que também não fique frustrado esperando por coisas milaborantes.

O objetivo é criar páginas com script ASP com acesso a banco de dados que permitam enviar cartões postais. O projeto é simples mas pode ser aperfeiçoado de forma a se tornar um serviço profissional.

Para testar o projeto você vai precisar de um editor de textos para os scripts ASP (bloco de notas, TextPad, HtmlKit(muito bom)) ; ter o IIS ou o personal web server instalado na sua máquina local e poder criar um banco de dados Access (poderia ter sido usado MySql) ter instalado o CDONTS ou um componente para envio de emails (JMail, ASPMail , etc...)

Nosso projeto irá ser constituído de 5 páginas ASP e irá acessar um banco de dados Access que possuirá duas tabelas: imagens e cartoes :

A estrutura das tabelas imagens e cartoes do banco de dados CartaoPostal.mdb são :

tabela - Cartoes tabela - Imagens

A estrutura básica da aplicação pode ser vista segundo o esquema abaixo:

A estrutura de diretórios da aplicação na minha máquina local é a seguinte :

-Para publicação na web a estrutura poderá ser diferente dependendo da configuração adotada pelo se servidor web.

-Estou  usando o diretório de trabalho padrão : \inetpub\wwwroot

-Perceba que as páginas ASP estão em um mesmo diretório

- O conteúdo das demais pastas é :

  • dados -  o banco de dados CartaoPostal.mdb
  • imagens - as imagens usadas nos cartões
  • musicas - as músicas (formato mid) usadas nos cartões

Dada as explicações iniciais vamos ao que interessa...

A página principal da aplicação : index.asp

Abaixo você esta vendo a página principal da aplicação representada pelo arquivo index.asp.

Este arquivo possui basicamente código html e poderia ser chamado de index.htm . Nele eu apenas exibo as imagens que representam categorias de cartões postais. Eu só ativei a categoria festas pois não vou criar aqui um serviço completo , mas o que foi feito para a categoria festas vale para as demais.

Exibir  código do arquivo:

index.asp

Cada imagem possui um link que aponta para a página cartao.asp e passa como parâmetro a variável postal com um valor para cada categoria. Assim a categoria saudade tem o parâmetro postal com valor igual a 1 ; para a categoria festas o valor de postal é 5 , assim por diante.

Estes parâmetros são usados para passar informação de uma página para outra e a sintaxe para a passagem destes parâmetros é anexá-los ao fim do endereço URL da página. Assim se fizermos uma chamada ao arquivo ASP como http://www.teste.com/exemplo.asp e quisermos passar a este arquivo um parâmetro identificado como par com o valor de 7 , iremos anexar ?par=7 ao final da URL original e ficaríamos com http://www.teste.com/exemplo.asp?par=7.

Para passar múltiplos parâmetros basta separá-los usando o ampersand (&) assim , passando o parâmetro codigo com o valor Azul , teremos: http://www.teste.com/exemplo.asp?par=7&codigo=Azul

No nosso exemplo eu estou usando a seguinte codificação :

- para primeira imagem temos a categoria 'saudade' com o seguinte link:

<a href="cartao.asp?postal=1" onMouseOver="self.status='Saudade'; return true" onMouseOut="self.status=''; return true">

Quando o usuário clica em uma categoria (lembre-se que somente a categoria 'festas' esta ativa para o nosso exemplo) a página cartao.asp será processada com parâmetro informado no link. 0

Exibindo imagens para os cartões

A página cartao.asp ao ser processada exibe as imagens da categoria selecionada. Abaixo temos a página para a categoria 'festas':

As imagens estão armazenadas na tabela imagens.

A coluna 'categoria' da tabela imagens indica a que categoria a imagem pertence ; assim para a categoria 'festas' o parâmetro postal tem valor igual a 5 e na tabela imagens temos armazenadas 8 imagens para esta categoria conforme mostrada abaixo:

Exibir código do arquivo:

cartao.asp

 

Vejamos o código do arquivo cartao.asp que faz o acesso ao banco de dados e seleciona as imagens para serem exibidas na página:

<%
'define o local do banco de dados
acessoDB="dados/CartaoPostal.mdb"
'monta a string de conexão 
conn="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath(acessoDB)
'obtem o parametro informado na página index.asp
cat = request.QueryString("postal")
'cria o objeto recordset e define o cursor
Set rs = Server.CreateObject("ADODB.Recordset")
rs.CursorLocation = 3
strSQL = "SELECT * FROM imagens where categoria='" & cat & "'"
rs.Open strSQL, conn
' se não houver dados retorna para a página principal
if rs.EOF and rs.BOF then
    rs.close
    set rs = nothing
    response.redirect "index.asp"
end if
%>
Eu estou cometendo um pecado mortal neste código.

- Não estou usando Option explicit

- Não estou declarando as variáveis usadas

NUNCA FAÇA ISTO em uma aplicação de produção.

Você poderia também colocar em um arquivo include o caminho do banco de dados e a string de conexão.

Leia o artigo abaixo para saber mais:

ASP - Usando Server-Side Includes.

A linha de código onde estamos verificando qual categoria foi selecionada é : cat = request.QueryString("postal")

O objeto Request permite que você acesse o cabeçalho HTTP enviado ao servidor da WEB pelo navegador do cliente utilizando os parâmetros discutidos a seguir.

Sintaxe : Request[.Collection](variável)

Cada requisição pode ter diversos parâmetros em diferentes categorias, e para tratar esta quantidade de informação o objeto Request utiliza as Coleções (Collections) , que podem ser vistas como vetores contendo um conjunto de informações.

As coleções que podem ser acessadas via objeto Request são:

  1. QueryString
  2. Form
  3. ServerVariables
  4. ClientCertificates
  5. Cookies

A coleção QueryString é usada para capturar os valores dos parâmetros que são passados para um arquivo ASP usando o método GET.

Sintaxe: Request.QueryString(variavel)[(index)][.count]

Estamos obtendo o valor do parãmetro e armazenando-o na variável cat. A seguir é só montar a instrução SQL para selecionar as imagens da categoria:

strSQL = "SELECT * FROM imagens where categoria='" & cat & "'"

Após criar um recordset com as imagens da categoria percorremos o recordset em um loop e obtemos o nome  e o código da imagem assim :

 Do while not rs.EOF
   nom = rs("nome")
   cod = rs("codigo")

.....

Loop

O nome da imagem é armazenado na variável nom e o código na variável cod.

Estas variáveis serão usadas para exibir a imagem e montar o parâmetro na chamada da página pesonalizar.asp?cod=<%=cod%>

Cada imagem possui um link que aponta para o arquivo personalizar.asp e passa como parâmetro o codigo da imagem. Lembre-se que na tabela imagens cada imagem possui um código que a identifica ;é com este código que vamos recuperar a imagem escolhida na tabela. O código do link para cada imagem é dado abaixo:

<a href="personalizar.asp?cod=<%=cod%>"><img src="imagens/<%=nom%>" border=0></a>

aqui <%=cod%> representa o código da imagem recuperada da tabela imagens. Para a primeira imagem teremos:personalizar.asp?cod=1

Exibindo o formulário para criar o cartão postal

Quando o usuário clica em uma imagem a página personalizar.asp é processada com o parâmetro que informa o código da imagem selecionada. Como cada imagem possui um código ao clicar na imagem este código será processado na instrução SQL:

strSQL = "SELECT * From imagens WHERE codigo =" & Cint(request.QueryString("cod"))

O arquivo personalizar.asp é então processado exibindo a imagem e o formulário onde o usuário poderá informar os dados do destinatário , remetente , configurar a cor de fundo do cartão e selecionar uma música de fundo. Abaixo temos a página exibida para a imagem escolhida:

Nota: No arquivo personalizar.asp temos também o código javascript para validar os dados informados no formulário. Ele poderia ter sido incluído também em um arquivo a parte.

 

Exibir código do arquivo:

personalizar.asp

 

O código que acesso o banco de dados e a tabela de imagens

<%
acessoDB="dados/CartaoPostal.mdb"
conn="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath(acessoDB)
if request.QueryString("cod") = "" then
    reponse.redirect "index.asp"
End If
session("ip") = Request.ServerVariables("REMOTE_ADDR")
Set rs = Server.CreateObject("ADODB.Recordset")
strSQL = "SELECT * From imagens WHERE codigo =" & Cint(request.QueryString("cod"))
rs.Open strSQL, conn
if rs.EOF and rs.BOF then
    rs.close
    conn.close
    set rs = nothing
    set conn = nothing
    response.redirect "index.asp"
end if
session("img") = rs("nome")
%>

Vale destacar que após selecionar a imagem da tabela estou armazenando o seu nome em uma variável de sessão em : session("img") = rs("nome")

Aqui estou usando o objeto Session , o objeto Session é semelhante ao objeto Application no sentido de que ele também contém eventos dentro do arquivo global.asa. Entretanto, ao contrário do objeto Application , o objeto Session armazena informacões de uma sessão de usuário em particular.

Esse objeto persiste para a sessão inteira e proporciona assim uma solução elegante para o problema comum da persistência do estado - quando você precisa controlar um usuário de uma página da Web para a seguinte.

O servidor identifica cada usuário com um único SessionID a qual é atribuida a cada usuário no inicio de sua sessão. Esta variável é armazenada na memória do servidor e é gravada no cliente atribuindo o valor da SessionID a um cookie, assim este cookie é enviado ao servidor cada vez que o usuário faz uma solicitação e é comparado com o valor que fica na memória do servidor.
 
O servidor Web cria automaticamente um objeto Session quando uma página é requisitada pelo usuário que ainda não tenha uma sessão. A sessão é destruída quando for abandonada ou quando expirar.  Uma sessão inicia quanto o usuário requisita qualquer página dentro de uma aplicação ASP e termina quando o script Abandona a sessão ou quando o tempo da sessão expira.

Após preencher os dados do formulário ao clicar - Visualizar - o arquivo visualizar.asp será executado e irá gerar a página com a visualização do cartão montado.

Isto é feito usando a atributo  action do formulário durante a submissão do mesmo ao servidor:

<form action="visualizar.asp" method="post" onsubmit="return verificadados(this)">

A seguir temos a página visualizar.asp exibindo um cartão postal com dados selecionados pelo usuário:

 

Exibir código do arquivo:

visualizar.asp

O código do arquivo visualizar que obtêm os valores da requisição do formulário é mostrado abaixo:

<%
session("destinatario") = request("destinatario_nome")
session("destinatario_email") = request("destinatario_email")
session("remetente") = request("remetente_nome")
session("remetente_email") = request("remetente_email")
session("texto") = request("mensagem")
session("texto") =CStr(Replace(session("texto"),str,"<br>"))
session("texto") =CStr(Replace(session("texto"),vbcr,"<br>"))
session("corfundo") = request("cor")
session("musica") = request("musica")
%>

Aqui estamos usando o objeto Session para persistir os valores das informações enquanto durar a sessão do usuário.

Ao clicar no botão Enviar o arquivo enviar.asp será processado. Ele irá efetuar as seguintes tarefas:

<%
Set Conexao = Server.CreateObject("ADODB.Connection")
acessoDB="dados/CartaoPostal.mdb"
conn="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath(acessoDB)
Conexao.Open conn
Randomize()
Codigo = Int((999999 - 1) * RND +1)
final = now()
final = DateAdd("d",5,final)
sql = "INSERT INTO Cartoes(Codigo,Destinatario, EmailDestinatario, Remetente, EmailRemetente, Imagem, Texto , fundo , musica , data) 
        Values('" & codigo & "','" & session("destinatario") & "','" & session("destinatario_email") & "','" _
       & session("remetente") & "','" & session("remetente_email") & "','" & session("img") & "','" & session("texto") & "','" _
       & session("corfundo") & "','" &  session("musica") & "'," & FormatDateTime(final,2) & ")"
Conexao.execute sql
Set objEmail = Server.CreateObject("CDONTS.NewMail")
objEmail.From = session("remetente")
objEmail.To = session("destinatario_email")
objEmail.Subject = "Cartão Postal para você..."
assunto = "Olá, " & session("destinatario") & VbCrLf & _
              "Você acabou de receber um Cartão Postal Virtual de : " & session("remetente") & VbCrLf & VbCrLf & _
              "Para visualizar o seu cartão , clique no link abaixo: " & VbCrLf & _
              "http://www.macoratti.net/macoratti/cartao/ver.asp?id=" & codigo & VbCrLf & VbCrLf & _
              "Seu cartão estará disponível no site até o dia : " & FormatDateTime(final,2) & VbCrLf & _
              "Obrigado !"
objEmail.Body = assunto
objEmail.Send
set ObjEmail = nothing
%>

O CDONTS (Collaboration Data Objects for NT Server) é uma alternativa robusta e fácil de usar para enviar emails em páginas ASP , além disto muitos servidores web dão suporte ao CDONTS .

Nota : Leia o artigo ASP - Usando o componente AspEmail.  para saber como usar outro componente para enviar email com ASP.

O código abaixo mostra como criar preparar os objetos para enviar um email:

Set objEmail = Server.CreateObject("CDONTS.NewMail")
objEmail.From = session("remetente")
objEmail.To = session("destinatario_email")
objEmail.Subject = "Cartão Postal para você..."
Criamos um objeto do tipo CDONTS e atribuímos os valores para o remetente, email do destinatário e o título do cartão.
assunto = "Olá, " & session("destinatario") & VbCrLf & _
              "Você acabou de receber um Cartão Postal Virtual de : " & session("remetente") & VbCrLf & VbCrLf & _
              "Para visualizar o seu cartão , clique no link abaixo: " & VbCrLf & _
              "http://www.macoratti.net/macoratti/cartao/ver.asp?id=" & codigo & VbCrLf & VbCrLf & _
              "Seu cartão estará disponível no site até o dia : " & FormatDateTime(final,2) & VbCrLf & _
              "Obrigado !"

 

a variável assunto recebe o corpo do texto e a url que o usuário deverá clicar para ver o cartão postal.

Observe que o cartão tem uma data de disponibilidade que indica no texto.

objEmail.Body = assunto
objEmail.Send
set ObjEmail = nothing
Atribui o texto do assunto ao objeto e envia o email .

limpa a variável objeto da memória.

Gostaria de chamar a atenção para a url que o destinatário recebe no email afim de ter acesso ao cartão. O código da url é montado assim :

"http://www.macoratti.net/macoratti/cartao/ver.asp?id=" & codigo & VbCrLf & VbCrLf

Aqui a variável codigo é gerada aleatoriamente pelo seguinte código:

Randomize()
Codigo = Int((999999 - 1) * RND +1)

Abaixo um exemplo de um email de teste que eu enviei para mim mesmo:

Exibir código do arquivo:

enviar.asp

 

Observe a url :  http://www.macoratti.net/macoratti/cartao/ver.asp?id=859324

O número atribuído ao parâmetro id é a variável codigo que foi gerada. Este código será também gravado na tabela cartoes afim de identificar o cartão gerado. A instrução SQL INSERT INTO insere os dados referente ao cartão e atribui o código a coluna codigo da tabela cartoes.

Assim quando o usuário clicar na URL o arquivo ver.asp será processado com o valor do parâmetro informado e poderá recuperar o cartão da tabela cartoes. Este é uma das razões do número ser aleatório: evitar que alguém veja o cartão de outra pessoa.

Nota : Para efeito de testes tente recuperar o cartão a URL : http://www.macoratti.net/macoratti/cartao/ver.asp?id=842158

Para encerrar só falta falar do código do arquivo ver.asp. Abaixo temos a parte do script ASP do arquivo ver.asp. Ele faz o seguinte :

<%
id = request.QueryString("id")
if id="" then
    response.redirect "index.asp"
end if
acessoDB="dados/CartaoPostal.mdb"
conn="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath(acessoDB)
Set rs = Server.CreateObject("ADODB.Recordset")
hoje = now()
hoje = FormatDateTime(hoje,2)
strSQL = "SELECT * FROM cartoes WHERE codigo = '" & id & "' AND data >= #" & hoje & "#"
rs.open strSQL,conn
if rs.EOF and rs.BOF then
    rs.close
    set rs = nothing
    response.redirect "erro.asp"
end if
session("destinatario") = rs("destinatario")
session("destinatario_email") = rs("emaildestinatario")
session("remetente") = rs("remetente")
session("remetente_email") = rs("emailremetente")
session("texto") = rs("texto")
session("texto") =CStr(Replace(session("texto"),str,"<br>"))
session("texto") =CStr(Replace(session("texto"),vbcr,"<br>"))
session("corfundo") = rs("fundo")
session("musica") = rs("musica")
session("img") = rs("imagem")
%>

Exibir código do arquivo:

ver.asp

 

O código da página erro.asp é o seguinte :

<html>
<head>
<title>erro.asp</title>
</head>
<body>
<p align="center">
<img border="0" src="imagens/maco10.gif" width="233" height="32">
</p>
<hr>
<p align="center"><font face="Trebuchet MS" size="6" color="#FF0000">Este Cartão
Postal não esta mais disponível</font></p>
<p align="center"><font face="Trebuchet MS" size="6" color="#FF0000">na base de
Cartões</font></p>
<form method="POST" action="index.asp">
	<p align="center">
	<input type="submit" value="Retornar para página de Cartões Postais" name="B1"></p>
</form>
<p align="center">&nbsp;</p>
<p align="center">&nbsp;</p>
</body>
</html>

Para ver o exemplo funcionando clique aqui : Cartões Postais do Macoratti

Nota : Afim de evitar problemas com os metidos a engraçadinhos de plantão o código que envia o email não esta ativo.

Até mais ver...

Referências:


José Carlos Macoratti