Atualmente nas aplicações ASP.NET utilizamos Cookies e variáveis de sessão
(Session) para armazenar informações específicas de um determinado usuário. Um
cenário bastante comum é quando queremos armazenar informação para a
customização do Site, Nome e Email do usuário e até mesmo um Carrinho de
Compras.
Neste artigo apresentarei um overview do novo objeto do ASP.NET
2.0, chamado Profile qual tem a finalidade específica de armazenar informações
de um determinado usuário em seu contexto.
O Profile é bem semelhante ao
objeto Session atual, onde para cada usuário que temos em nossa aplicação Web é
criado um Profile para ele. Até então funciona da mesma forma que o objeto
Session. Mas o mais interessante está por vir, ou seja, quando fechamos o
browser, a Session é perdida. Já utilizando o Profile ele se mantém persistente
mesmo depois do usuário fechar o browser.
Isso se deve graças ao uso,
por default, do Microsoft Access, onde são armazenadas estas informações, que
fica dentro de uma pasta chamada
Data, dentro da sua aplicação. Vale
lembrar que é perfeitamente possível o uso de uma outra Base de Dados para
termos uma melhor performance, como por exemplo SQL Server ou Oracle. Veremos
este tópico um pouco mais adiante, em um futuro artigo.
Além da vantagem
de se manter persistente mesmo depois de fechado o Browser, o Profile ainda tem
uma vantagem, que particularmente considero fantástica, que é fortemente tipado
(strongly typed), ao contrário da Session, que por sua vez aceitava um
Object. Além disso, o IntelliSense já reconhece as propriedades, tornando
assim o desenvolvimento mais rápido e menos propício a erros.
Definindo o Profile Você deve utilizar o arquivo
Web.Config para gerar a estrutura que o teu objeto Profile irá ter. Temos à
nossa disposição o elemento
profile, onde definimos as propriedades que
vamos disponibilizar. O cenário é termos dentro do Profile, o Nome e Email do
Usuário. Abaixo o código do arquivo Web.Config que define o Profile:
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
|
|
<configuration> |
<system.web> |
<authentication
mode="Forms" /> |
<anonymousIdentification
enabled="true" /> |
|
<profile> |
<properties> |
<add
name="Nome" defaultValue="" allowAnonymous="true" /> |
<add
name="Email" defaultValue="" allowAnonymous="true" /> |
</properties> |
</profile> |
</system.web> |
</configuration> |
| |
Código 1 - Definindo a
estrutura do Profile no arquivo Web.Config.
|
Analisando o código acima, vemos o elemento
anonymousIdentification que especificará que o Profile será criado para
usuários anônimos ou autenticados. Se definí-lo com False e tentar atribuir
algum valor as propriedades em runtime e o usuário não estiver autenticado, uma
Exception será lançada. Já o atributo
allowAnonymous é requerido quando
as propriedades são usadas com usuários anônimos.
O código para atribuir
um valor as propriedades, fica da seguinte forma:
|
|
Profile.Email =
"israel@projetando.net" |
Profile.Nome = "Israel
Aéce" |
| |
Código 2 - Acessando as
propriedades do Profile. |
Como já
podemos ver na Figura 1 logo abaixo, o Intellisense já passa a interpretar as
propriedades que definimos no Web.Config:
|
Figura 1 - Intellisense já
reconhecendo as propriedades definidas no
Web.Config. |
Repare que o tipo do dado não é definido. Isso porque o
default, quando não informamos é System.String. Caso queria definir um
tipo Inteiro ou qualquer outro tipo, tem o atributo type, onde define-se
o tipo de dado que queira para aquela propriedade.
Profile Groups
Quando começamos a criar várias propriedades dentro do arquivo
Web.Config para utilizarmos no Profile, começamos a ter a necessidade de separar
algumas delas em grupos para que facilite a compreensão e organização. Para isso
temos o elemento group, onde dentro dele colocamos as propriedades
pertinentes ao mesmo. Se quisermos adicionar um grupo chamando Endereco,
contendo Rua, Cidade, Estado, fazemos:
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
|
|
<configuration> |
<system.web> |
<authentication
mode="Forms" /> |
<anonymousIdentification
enabled="true" /> |
|
<profile> |
<properties> |
<add
name="Nome" defaultValue="" allowAnonymous="true" /> |
<add
name="Email" defaultValue="" allowAnonymous="true" /> |
<group
name="Endereco" /> |
<add
name="Rua" defaultValue="" allowAnonymous="true" /> |
<add
name="Cidade" defaultValue="" allowAnonymous="true" /> |
</group> |
</properties> |
</profile> |
</system.web> |
</configuration> |
| |
Código 3 - Definindo grupos do
Profile no arquivo Web.Config. |
E para
acessá-los, o código fica:
|
|
Profile.Email =
"israel@projetando.net" |
Profile.Nome = "Israel Aéce" |
Profile.Endereco.Rua = "Magnólias,
das" |
Profile.Endereco.Cidade =
"Valinhos" |
| |
Código 4 - Acessando as
propriedades com grupos do Profile.
|
Tipos Complexos Muitas vezes,
criamos objetos complexos que encapsulam alguma lógica e funcionalidades
específicas. Um exemplo prático disso é quando criamos um objeto do tipo
Carrinho de Compras para aplicações de comércio eletrônico. Neste caso, o ideal
é colocarmos este tipo de objeto no Profile e assim fazer o uso destas
funcionalidades. O Profile permite definir estes tipos complexos para ser
gerenciado/armazenado, como por exemplo uma classe.
Para exemplificar
como isso funciona realmente, criaremos uma classe (que é um tipo complexo) onde
teremos um objeto que será o Carrinho de Compras do nosso Cliente. Esta classe
armazenará os produtos que o cliente desejar incluir no Carrinho além de nos
retornar o valor total do produtos e claro, podemos dar muito mais
funcionalidades a ela se desejarmos. Primeiramente o código da classe que contém
as propriedades para a estrutura do Produto:
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
|
|
<Serializable()> Public
Class Produto |
|
Private _nome As
String |
Private _valor As
Double |
Private _qtde As
Integer |
|
Public
Property Nome() As String |
Get |
Return Me._nome |
End
Get |
Set(ByVal value As
String) |
Me._nome = value |
End
Set |
End
Property |
|
Public
Property Valor() As Double |
Get |
Return Me._valor |
End
Get |
Set(ByVal value As
Double) |
Me._valor = value |
End
Set |
End
Property |
|
Public
Property Qtde() As Integer |
Get |
Return Me._qtde |
End
Get |
Set(ByVal value As
Integer) |
Me._qtde = value |
End
Set |
End
Property |
|
End
Class |
| |
Código 5 - Classe
Produto. |
Depois de criada a classe que
tem a estrutura do nosso Produto, criaremos a seguir a classe que conterá as
funcionalidades do nosso Carrinho de Compras, incluindo dentro dela também a
capacidade de armazenar os produtos que são adicionados ao carrinho pelo
usuário:
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
|
|
<Serializable()> Public
Class CarrinhoCompras |
|
Private _items As New
Generic.List(Of Produto) |
|
Public
ReadOnly Property Total() As
Double |
Get |
Dim tot As Double |
For Each prod As Produto In _items |
tot
+= prod.Valor * prod.Qtde |
Next |
Return tot |
End
Get |
End
Property |
|
Public
ReadOnly Property Produtos() As
Generic.List(Of Produto) |
Get |
Return Me._items |
End
Get |
End
Property |
|
Public
Sub AdicionarProduto(ByVal p As Produto) |
Me._items.Add(p) |
End
Sub |
|
End
Class |
| |
Código 6 - Carrinho de
Compras. |
Como podemos ver, é um código
simples, onde temos um método chamado
AdicionarProduto que é responsável
por adicionar um novo produto a coleção de produtos. Uma propriedade que nos
retorna o valor total dos Produtos e outra para resgatar a coleção de produtos
que o usuário selecionou.
O que é importante reparar é que as duas
classes necessitam do atributo
Serializable, que se faz necessário para o
armazenamento/persistência do objeto pelo Profile.
Da mesma forma que
criamos, um pouco mais acima, as simples propriedades e seus grupos no arquivo
Web.Config, devemos fazer o mesmo neste caso de tipos complexos. A forma com
qual é declarada muda um pouco, tendo que definir alguns atributos como é
mostrado abaixo:
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
|
|
<configuration> |
<system.web> |
<authentication
mode="Forms" /> |
|
<anonymousIdentification
enabled="true" /> |
|
<profile> |
<properties> |
<add |
name="CarrinhoCompras" |
type="CarrinhoCompras" |
serializeAs="Binary" |
allowAnonymous="true"
/> |
</properties> |
</profile> |
</system.web> |
</configuration> |
| |
Código 7 - Definindo tipos
complexos no Web.Config. |
O que notamos
de novidade na declaração de tipos complexos no Web.Config é o elemento
serializeAs que define qual o tipo de serialização do objeto. Feito isso,
agora já poderemos utilizar o nosso Carrinho de Compras pelo site, apenas tendo
o cuidado de, quando for utilizá-lo pela primeira vez, instanciá-lo para poder
inicializá-lo. Veremos abaixo um simples exemplo de como adicionar novos
produtos ao Carrinho e como exibir o seu conteúdo em um controle ASP.NET
qualquer:
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
|
|
Sub Button1_Click(ByVal sender As Object, ByVal e As
System.EventArgs) |
If
(Profile.CarrinhoCompras Is Nothing) Then |
Profile.CarrinhoCompras =
New CarrinhoCompras |
End
If |
|
Dim p As New Produto |
p.Nome = "Produto
1" |
p.Qtde =
2 |
p.Valor =
2.9 |
Profile.CarrinhoCompras.AdicionarProduto(p) |
|
Dim p1 As New Produto |
p1.Nome = "Produto
44" |
p1.Qtde =
3 |
p1.Valor =
14 |
Profile.CarrinhoCompras.AdicionarProduto(p1) |
|
Me.Label1.Text = "Total: " &
Profile.CarrinhoCompras.Total.ToString("C2") |
Me.GridView1.DataSource =
Profile.CarrinhoCompras.Produtos |
Me.GridView1.DataBind() |
End
Sub |
| |
Código 8 - Utilizando o
Carrinho de Compras. |
Como vemos,
verificamos se existe alguma instância do nosso objeto
CarrinhoCompras em
nosso Profile. Em seguida, criamos dois produtos e adicionamos neste carrinho.
Através da propriedade
Produtos resgatamos todos os produtos que estão
dentro do Carrinho e preenchemos nosso controle GridView e um Label com a
propriedade
Total, assim como é ilustrado na figura abaixo:
|
Figura 2 - Carrinho de Compras
sendo exibido. |
CONCLUSÃO: Vimos aqui a nova forma de armazenarmos
objetos pertencentes à um determinado usuário que chamamos de Profile. Há ainda
outras funcionalidades como por exemplo a configuração e utilização de outros
Providers e também como gerenciar e exibir (relatórios) de Profiles.
Funcionalidades quais veremos em um futuro artigo desta série para não ficar
muito desgastante.
Artigo desenvolvido utilizando:
* Visual Studio .NET 2005 - Beta 1
* .NET Framework 2.0
* Windows XP Professional