Enviando e-mail com Flex e .net
[Atualizado em 05/04/2010]
Quando criei esse tutorial pela primeira vez, fiz apenas a parte de envio de e-mail não expliquei como se faz a integração com a aplicação .net pois não achei necessário explicar novamente sendo que já tinha postada links a respeito. Decidi adicionar a esse artigo essa parte da integração também para que não fique muito confuso.
Utilizarei para esse tutorial: Visual Studio 2008, Adobe Flex 3 e FluorineFx.dll.
Parte 1: Criando aplicação de envio de e-mail com o Visual Studio, e preparando a aplicação .net para a integração.
1.1 – Para fazer a integração de uma aplicação .net com uma aplicação Flex, utilizaremos o framework FluorineFx que é open source. Faça o download do FluorineFx aqui, não tem mistério a instalação é o básico de sempre: “Next, Next e Finish”.
1.2 – Após instalar o FlourineFx vamos criar nossa estrutura de pastas, crie uma pasta em um diretoria qualquer chamada “FlexEnviarEmail”, dentro dessa pasta crie outras três pastas chamadas: “FlexFonte”, “AspNetFonte” e “publicado”. As pastas “FlexFonte” e “AspNetFonte” serão os diretorias das aplicações do Flex e do AspNet, a pasta “publicado” será a pasta onde publicaremos a aplicação.

1.3 – Abra o VS e vá em File > New > Web Site…, escolha a pasta que você criou chamada “AspNetFonte” e “Language” C#. Renome-e o arquivo “Default.aspx” para “Gateway.aspx”. Ainda no projeto do .net, vamos agora adicionar a referencia ao framework FluorineFx, clique com o botão direito em cima da solução e em seguida clique em “Add reference…”.

Se você instalou corretamente o framework FlourineFx, você vai ver na lista de referencias na aba .Net o framework.

Selecione o “FlourineFx for .NET Framwork 2.0”, caso sua aplicação não tenha a pasta BIN, a mesma será criada para ser adicionada essas dll’s.
Precisamos também registrar o framework FluorineFx no web.config. Então abra o web.config e adicione o seguinte código dentro do nod “configSections”:
<sectionGroup name="fluorinefx">
<section name="settings" type="FluorineFx.Configuration.XmlConfigurator, FluorineFx"/>
</sectionGroup>
Agora dentro do nod “httpModules”:
<httpModules> <add name="FluorineGateway" type="FluorineFx.FluorineGateway, FluorineFx"/> </httpModules>
Muito bem, a parte de configuração do framework FluorineFx já está pronta, agora vamos fazer a aplicação para enviar o e-mail.
1.4 – Crie uma Classe chamada Email.cs (botão direito em cima do projeto > Add new item…), se o VS 2008 perguntar se você deseja criar a pasta App_Code e colocar a Classe dentro dela clique em sim. Adicione o código abaixo:
using FluorineFx;
using System.Net.Mail;
[RemotingService]
public class Email
{
#region --- ATRIBUTOS ---
private String nome;
public String Nome
{
get { return nome; }
set { nome = value; }
}
private String userMail;
public String UserMail
{
get { return userMail; }
set { userMail = value; }
}
private String assunto;
public String Assunto
{
get { return assunto; }
set { assunto = value; }
}
private String mensagem;
public String Mensagem
{
get { return mensagem; }
set { mensagem = value; }
}
#endregion
public Email()
{ }
#region --- MÉTODOS ---
/// <summary>
/// Envia o email.
/// </summary>
/// <returns>Retorna True caso dê tudo certo e false caso gere algum erro.</returns>
public void EnviarEmail(Email _email)
{
MailMessage message = new MailMessage();
SmtpClient client = new SmtpClient();
//E-mail do rementente
message.From = new MailAddress("email-remetente", "Remetente");
message.IsBodyHtml = true;
message.Body = "Nome: " + _email.nome + "<br />E-mail: " + _email.userMail + "<br />Assunto: " + _email.assunto + "<br />Mesagem: " + _email.mensagem;
message.Subject = _email.assunto;
//E-mail do destinatário
message.To.Add(new MailAddress("email-destinatario", "Destinatário"));
//E-mail e senha para enviar a mensagem
client.Credentials = new System.Net.NetworkCredential("email-remetente/envio", "senha-email");
//Número da porta:
client.Port = 25;
//Seu host para envio do e-mail
client.Host = "host";
client.Send(message);
message.Dispose();
message = null;
client = null;
}
#endregion
}
As configurações de para envio de e-mail (host, porta, e-mail de envio e senha) são configurações de cada um, então não quer dizer, por exemplo, que a porta é a 25 como está no código acima, isso depende das suas configurações. Precisamos importar a FluorineFx para usar o “[RemoteService]”. O [RemoteService] que se encontra em cima da declaração da classe, serve para dizermos para o FluorineFx que essa classe será acessada remotamente pelo Flex. Criamos as propriedades nome, mail, assunto e mensagem, que são informações que pegaremos no formulário da aplicação Flex e enviaremos por e-mail. O método EnviarEmail recebe um parâmetro que é um objeto da própria classe Email (Isso ficara mais claro na aplicação Flex) e envia o e-mail.
1.5 – Agora configure a pasta “AspNetFonte” no IIS, para isso basta você clicar com o botão direito na pasta “AspNetFonte” e na aba “Compartilhamento web” escolher a opção “Compartilhar essa pasta”, na opção “alias” (apelido) coloque flexmail. Caso não tenha a aba “Compartilhamento web”, significa que seu IIS não está instalado, veja como você pode instalá-lo por esse tutorial (aconselho a trabalhar com o IIS), se você não tiver o IIS instalado, pode fazer o seguinte: O VS tem tipo um IIS interno para rodar as suas aplicações, então quando você roda uma aplicação pelo VS (apertando o F5, por exemplo) ele gera um número de porta aleatório e roda aplicação nesse servidor próprio, então a url fica mais ou menos algo assim: “http://localhost:3845/AspNetFonte/Gateway.aspx”, então rode sua aplicação e anote a url gerado no browser pois vamos precisar dela na aplicação Flex.
Pronto, já criamos nossa classe que enviara o e-mail, agora vamos para o Flex.
Parte 2: Criando formulário para envio de e-mail no Flex.
2.1 – Abra o Flex, vá em File > New > Flex Project e selecione a pasta FlexFonte que você criou anteriormente, coloque um nome qualquer para o projeto (no caso eu coloquei o mesmo nome da pasta) e clique em finish. Crie uma pasta dentro da pasta src com o nome de classes, agora adicionamos uma arquivo ActionScript Class com o nome de Email dentro dessa pasta (botão direito na pasta classes > new > actionscript class). Essa classe precisa ter exatamente o mesmo nome da classe na aplicação .net (no caso Email), então ela deve se chamar “Email.as”. Adicione o código abaixo nessa classe:
package classes{
[RemoteClass(alias="Email")]
public class Email{
private var nome:String;
public function get Nome():String{
return nome;
}
public function set Nome(n:String):void{
this.nome = n;
}
private var mail:String;
public function get Mail():String{
return mail;
}
public function set Mail(m:String):void{
this.mail = m;
}
private var assunto:String;
public function get Assunto():String{
return assunto;
}
public function set Assunto(a:String):void{
this.assunto = a;
}
private var mensagem:String;
public function get Mensagem():String{
return mensagem;
}
public function set Mensagem(msg:String):void{
this.mensagem = msg;
}
public function Email(){
}
}
}
Assim como na classe da aplicação .net, no Flex também precisamos dizer qual é a classe remota que ele irá acessar, por isso inserimos o [RemoteClass(alias=”Email”)] no começo da classe. A classe “Email” que está setado no “alias=”, é a classe “Email.cs” da aplição .net. Note que até mesmo o nome das propriedades tem que ser o mesmo do que a classe “Email.cs”. O get e set do actionscript 3.0 é bem semelhando ao do .net como podemos reparar.
2.2 – Dentro do arquivo principal do Flex, adicione o código abaixo:
<mx:RemoteObject id="roMail" source="Email" destination="fluorine" showBusyCursor="true">
<mx:method name="EnviarEmail" result="{resultadoEnviar(event)}" fault="{falhaEnviar(event)}"/>
</mx:RemoteObject>
<mx:VBox height="384" width="300" horizontalCenter="0" verticalCenter="0">
<mx:TextInput id="txtNome" focusIn="removeTextoPadrao(this.txtNome)" focusOut="addTextoPadrao(this.txtNome)" text="Nome"/>
<mx:TextInput id="txtEmail" width="280" focusIn="removeTextoPadrao(this.txtEmail)" focusOut="addTextoPadrao(this.txtEmail)" text="E-mail"/>
<mx:ComboBox id="comboAssunto" creationComplete="preencheCombo()"></mx:ComboBox>
<mx:TextArea width="300" height="120" id="txtMensagem" focusIn="removeTextoPadraoTextArea(this.txtMensagem)" focusOut="addTextoPadraoTextArea(this.txtMensagem)" text="Mensagem"/>
<mx:Button label="Enviar" id="btnEnviar" click="enviarEmail(event)"/>
</mx:VBox>
O “mx:RemoteObject” serve para se conectar remotamente com a classe “Email.cs”, especificamos qual classe ele ira se conectar através da propriedade “source”. A propriedade “showBusyCursor=true” serve para que enquanto o RemoteObject estiver sendo executado será exibido um cursor de carregando (tipo a ampulheta do windows).
Na tag mx:Method dizemos qual o método iremos usar da classe “Email.cs” pela propriedade “name” (pode se ter varias tags mx:Method para os métodos da classe), a propriedade “result” indica qual função será executada caso dê tudo certo na execução do método da classe “Email.cs”, caso dê algo errado, será executada a função que está registrada na propriedade “fault” (criaremos essas funções mais a frente). Em alguns controles pode-se observar que existem funções ligadas aos eventos focusIn (evento disparado quando o focu está no controle) e focusOut (evento disparado quando o focu sai do controle), que veremos no próximo passo.
2.3 – Crie um bloco “mx:Script” logo acima do código que você adicionou anteriormente, depois adicione esse código ao script:
import mx.rpc.remoting.mxml.RemoteObject;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
import mx.controls.Alert;
import classes.Email;
import mx.collections.ArrayCollection;
/********** EVENTOS DOS CONTROLES DO FORMULÁRIO **********/
//Preenche o combo box com as opções de assunto
private function preencheCombo():void{
var lista:ArrayCollection = new ArrayCollection();
lista.addItem("Selecione --");
lista.addItem("Dúvida");
lista.addItem("Sugestão");
lista.addItem("Reclamação");
comboAssunto.dataProvider = lista;
}
//Retira o texto padrão dos inputs nome e email
private function removeTextoPadrao(t:TextInput):void{
if (t.text == "Nome" || t.text == "E-mail")
t.text = "";
}
//Adiciona o texto padrão dos inputs nome e email
private function addTextoPadrao(t:TextInput):void{
if (t.id == "txtNome" && t.text == "")
t.text = "Nome";
else if (t.id == "txtEmail" && t.text == "")
t.text = "E-mail";
}
//Remove texto padrão do textarea
private function removeTextoPadraoTextArea(ta:TextArea):void{
if (ta.text == "Mensagem")
ta.text = "";
}
//Adiciona texto padrão do textarea
private function addTextoPadraoTextArea(ta:TextArea):void{
if (ta.text == "")
ta.text = "Mensagem";
}
//Volta com todos os textos padrões
private function textoPadrao():void{
txtNome.text = "Nome";
txtEmail.text = "E-mail";
txtMensagem.text = "Mensagem";
comboAssunto.selectedIndex = 0;
}
/********** FUNÇÕES DE CONECXÃO COM A APLICAÇÃO .NET **********/
//Função que é executada se ocorreu algum erro ao enviar o e-mail
private function falhaEnviar(evt:FaultEvent):void{
Alert.show("Ocorreu o seguinte erro ao tentar executar o método:\n" + evt.fault.message, "Erro");
}
//Função que é executada se não ocorreu erros no envio de e-mail
private function resultadoEnviar(evt:ResultEvent):void{
textoPadrao();
Alert.show("E-mail enviado com sucesso!");
}
//Função que é acionado com o clique do mouse
private function enviarEmail(evt:MouseEvent):void{
if (evt.type == MouseEvent.CLICK){
var email:Email = new Email;
email.Nome = txtNome.text;
email.Mail = txtEmail.text;
email.Assunto = comboAssunto.selectedLabel;
email.Mensagem = txtMensagem.text;
roMail.getOperation("EnviarEmail").send(email);
}
}
A função “preencheCombo” serve para preencher o comboBox assunto, com informações de um arrayCollection. As funções que seguem abaixo da função “preencheCombo” servem somente para retirar ou adicionar texto padrão nos inputs. A função “textoPadrao” serve para retornar os textos padrões para os inputs depois que o e-mail for enviado. A função “falhaEnviar” que recebe como parâmetro um “FaultEvet” é a função que será executada caso ocorra algum erro na execução do RemoteObject, e a função “resultadoEnviar” será disparada caso ocorra tudo bem, perceba que as duas funções simplesmente executam um “Alert” informando o que aconteceu.
A função “enviarEmail” é executada quando clicamos no botão “btnEnviar” (o evento clique chama a função enviarEmail) e dentro dessa função, criamos um objeto da classe “Email.as” e preenchemos os atributos com os valores do formulário. Para executar o método que está registrado no “roMail” (id do mx:RemoteObject), executamos o “getOperation” do “roMail” e passamos como parâmetro o nome do método registrado, em seguida executamos o send(). Como já sabemos, o método “EnviarEmail” da classe “Email.cs” espera um parâmetro do tipo “Email”, então no “send()” do “getOperation” passamos o objeto da classe “Email.as” que criamos com os dados do formulário(“.send(email)”). Caso o método “EnviarEmail” da classe “Email.cs” não esperasse nenhum parâmetro, bastava executar o “send()” sem parâmetros mesmo.
Parte 3: Configurando a aplicação Flex para se conectar com a aplicação .net.
3.1 – Clique com o botão direito na pasta src e selecione File > New > File, coloque o nome do arquivo de “services-config.xml”, é com esse arquivo que faremos o mapeamento das classes ActioScript com .Net/C#. Adicione o código abaixo nesse arquivo:
<?xml version="1.0" encoding="UTF-8"?>
<services-config>
<services>
<service id="remoting-service"
class="flex.messaging.services.RemotingService"
messageTypes="flex.messaging.messages.RemotingMessage">
<destination id="fluorine">
<channels>
<channel ref="my-amf"/>
</channels>
<properties>
<source>*</source>
</properties>
</destination>
</service>
</services>
<channels>
<channel-definition id="my-amf"
class="mx.messaging.channels.AMFChannel">
<endpoint uri="http://localhost/flexmail/Gateway.aspx"
class="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>
</channels>
</services-config>
Se você configurou a aplicação .net no IIS, coloque a url da aplicação na opção “uri” do nod “endpoint” (como você pode observar, a url que está no código acima é uma url de uma aplicação que está configurada no IIS), caso você não esteja usando o IIS e sim o VS, então coloque a url gerada pelo VS (passo 1.5) e adicione no “uri” do nod “endpoint”. Agora clique com o botão direito em cima da aplicação Flex e clique em properties:

Na opção “Flex Compiler” adicione o texto “-services services-config.xml” no “Additional compiler arguments”:

Deixe um espaço em branco entre o “-locale en_US” e o “-services services-config.xml”. Agora já está tudo ok, já da para testar a aplicação, se você conseguiu configurar a aplicação no IIS, basta executar a aplicação no Flex e já estará tudo funcionando. Caso você tenha usado a url gerado pelo VS, você terá que executar a aplicação .net primeiro, e depois executar a aplicação Flex, é preciso fazer isso para que o VS inicie o seu servidor interno.
Parte 4: Publicando as aplicações.
4.1 – Para isso você precisara do IIS instalado, primeiro vamos publicar a aplicação .net, abra o VS e abra a aplicação que esta na pasta “AspNetFonte”, clique com o botão direito na solução e clique em “Publish Web Site”:

clique no botão “…” e selecione a pasta que você criou chamada “publicado”, deixe apenas a opção “Allow this precompiled site to be updatable” marcada e clique em ok.

Pronto, a aplicação .net está publicada, agora vamos publicar a aplicação Flex. Abra a aplicação Flex, depois abra o arquivo services-config.xml, e na opção “uri” do nod “endpoint”, deixe assim:
<endpoint uri="Gateway.aspx" class="flex.messaging.endpoints.AMFEndpoint"/>
Isso por que toda a pasta publicado será uma aplicação, e a aplicação Flex e .net estarão na mesma pasta, então não é preciso colocar o caminho completo da aplicação. Agora selecione o projeto Flex, clique no botão superior Project > Export Release Build…:

Na opção “Browser” selecione a pasta “publicado” e clique em Finish. Agora configure a pasta “publicado” no IIS, agora é só acessar a aplicação no seu localhost e pronto.
Baixe o projeto aqui, até a próxima!