Desenvolvimento - ASP. NET

Objeto Profile - ASP.NET 2.0 (parte 1)

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.

por Israel Aéce



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:

1
2
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:

1
2
3
4
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

Israel Aéce

Israel Aéce - Especialista em tecnologias de desenvolvimento Microsoft, atua como desenvolvedor de aplicações para o mercado financeiro utilizando a plataforma .NET. Como instrutor Microsoft, leciona sobre o desenvolvimento de aplicações .NET. É palestrante em diversos eventos Microsoft no Brasil e autor de diversos artigos que podem ser lidos a partir de seu site http://www.israelaece.com/. Possui as seguintes credenciais: MVP (Connected System Developer), MCP, MCAD, MCTS (Web, Windows, Distributed, ASP.NET 3.5, ADO.NET 3.5, Windows Forms 3.5 e WCF), MCPD (Web, Windows, Enterprise, ASP.NET 3.5 e Windows 3.5) e MCT.