Profiles II

Tras nuestro primer artículo de introducción a los profiles, ahora veremos alguna de las características más avanzadas de los profiles. Éstas hacen de los profiles no sólo una herramienta útil y cómoda de usar, sino una herramienta muy potente y prácticamente imprescindible para las aplicaciones Web.

Tipos de datos
En el primer artículo sobre profiles, vimos que en el XML que las definía contenía el tipo de datos de la variable profile. Pues bien, no sólo se puede hacer uso de los tipos de básicos, sino que podemos usar cualquiera, desde listados genéricos hasta nuestras propias clases. siguiendo el ejemplo del primer artículo:

        <profile enabled="true">
                <properties>
                    <add name="Sexo" defaultValue=""/>
                    <add name="Visitas" type="int" defaultValue="1"/>
                    <add name="Cumple" type="System.DateTime"/>
                    <add name="misAmigos" type="System.Collections.Specialized.StringCollection"/>
                   
<add name="referido" type="Subgurim.Persona"/>
                </properties>
        </profile>


Como vemos, hemos añadido dos variables profile:
- "misAmigos": que no es más que un StringCollection.
- "referido", que identificará a la persona que nos ha aconsejado esta Web y que será de la clase Persona que hemos creado nosotros.

Groups
Dando otra vuelta de tuerca a los profiles, tenemos los groups. Con ellos podemos agrupar varios profiles en un mismo grupo. Por ejemplo, imaginemos que queremos guardar en variables profile la cantidad noticias por página que mostraremos al usuario, así como cantidad de respuestas por página en un post del foro. Obviamente las podríamos guardar como dos variables profile distintas... pero no hay duda de que conceptualmente responden a "items por página".

De modo que usaremos los groups:

        <profile enabled="true">
                <properties>
                    <add name="Sexo" defaultValue=""/>
                    <add name="Visitas" type="int" defaultValue="1"/>
                    <add name="Cumple" type="System.DateTime"/>
                    <add name="misAmigos" type="System.Collections.Specialized.StringCollection"/>
                   
<add name="referido" type="Subgurim.Persona"/>
                    <group name="Mostrar">
                        <add name="General" type="System.Int16" defaultValue="25" />
                        <add name="Noticias" type="System.Int16" defaultValue="8" />
                        <add name="Foro" type="System.Int16" defaultValue="15" />
                    </group>

                </properties>
        </profile>


Y para ello no hay más que abrir otro elemento XML llamado "group", dentro del cual estarán los elementos "add" que ya conocemos.

A la hora de usarlo en código, que es realmente lo que nos interesa, vemos que sigue siendo intuitivo y sencillo:

        Profile.Mostrar.Foro = 13;
        Profile.Mostrar.Noticias = Profile.Mostrar.General;



allowAnonymous
Hagamos un pequeño inciso para recordar que los Profiles funcionan conjuntamente con el sistema de autenticación integrado en ASP.NET. Es decir, que cuando un usuario se autentica con su nombre y contraseña, éste tiene almacenado en la Base de Datos (transparente a los programadores) las características del profile.

¿Pero qué ocurre cuando queremos usar los profiles con usuarios que no es autentican (anónimos)? El modo de proceder de ASP.NET en estos casos es asignar una clave al visitante anónimo (en una cookie) que se corresponda con una entrada en la tabla de profiles. De ese modo, el usuario anónimo puede disfrutar de los profiles, aunque sea dependiendo de una cookie .

Por defecto los profiles no están habilitados para los visitantes anónimos, y debemos explicitarlo cuando definamos el profile. En nuestro ejemplo, sólo vamos a querer que el visitante anónimo pueda usar los profiles del grupo mostrar", pues el resto nos es inútil si no se registra. Por tanto, quedaría:

        <profile enabled="true">
                <properties>
                    <add name="Sexo" defaultValue=""/>
                    <add name="Visitas" type="int" defaultValue="1"/>
                    <add name="Cumple" type="System.DateTime"/>
                    <add name="misAmigos" type="System.Collections.Specialized.StringCollection"/>
                    <add name="referido" type="Subgurim.Persona"/>
                    <group name="Mostrar">
                        <add name="General" type="System.Int16" defaultValue="25" allowAnonymous="true" />
                        <add name="Noticias" type="System.Int16" defaultValue="8" allowAnonymous="true" />
                        <add name="Foro" type="System.Int16" defaultValue="15" allowAnonymous="true" />
                    </group>
                </properties>
        </profile>


Acceder al profile de un usuario que no sea el activo.
Hasta ahora hemos visto cómo accedíamos a la variables profile del usuario que estaba activo, pero podríamos querer acceder a las variables profile de otros usuarios.

Por ejemplo imaginemos que queremos hacer una ficha de usuario pública de todos nuestros usuarios; el usuario A acceder a la ficha del usuario B, si usáramos:

        Label1.Text = Profile.Sexo;

La Label nos mostraría el sexo del usuario A... ¿cómo lo hacemos entonces?

Pues es bien sencillo, no hay más que hacer:

        ProfileCommon prof = Profile.GetProfile("usuarioB");
        prof.Sexo;


Se coge el profile del usuario que queramos con el GetProfile y la asignamos a una variable del tipo ProfileCommon. Esta variable (prof) puede acceder -intellisense incluído- a todas las propiedades profile del usuario especificado.


Tu propia clase profile.
Si ya te has convencido del enorme poder de los profile... ¿qué pensarías si te dijera que puedes crearte tu propia clase profile sin necesidad de usar el XML del web.config?

Para entenderlo mejor, veamos un ejemplo. A las propiedades profile que ya tenemos vamos a añadir otro StringCollection de usuariosIgnorados (listado de usuarios que nos caen mal)... pero no lo vamos a añadir en el XML, sino que vamos a crear esta clase:

    public class myProfileClass : ProfileBase
    {
        public myProfileClass()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        public StringCollection usuariosIgnorados
        {
            get
            {
                return (StringCollection)base["Ignorados"];
            }
            set
            {
                base["Ignorados"] = value;
            }
        }
    }


Que no es más que una clase que hereda de ProfileBase y a la que le hemos añadido una propiedad (usuariosIgnorados) que acceder a base["ignorados"] para devolver o grabar valores.

Esto no es más que un ejemplo con una única propiedad, pero podríamos extenderlo tanto como quisiéramos.

Pero ojo, de algún modo le tenemos que decir al XML que tenemos una clase que extiende a ProfileClass... cosa que conseguimos con solo añadir un atributo:

        <profile enabled="true" inherits="myProfileClass">
                <properties>
                    <add name="Sexo" defaultValue=""/>
                    <add name="Visitas" type="int" defaultValue="1"/>
                    <add name="Cumple" type="System.DateTime"/>
                    <add name="misAmigos" type="System.Collections.Specialized.StringCollection"/>
                    <add name="referido" type="Subgurim.Persona"/>
                    <group name="Mostrar">
                        <add name="General" type="System.Int16" defaultValue="25" allowAnonymous="true" />
                        <add name="Noticias" type="System.Int16" defaultValue="8" allowAnonymous="true" />
                        <add name="Foro" type="System.Int16" defaultValue="15" allowAnonymous="true" />
                    </group>
                </properties>
        </profile>



Conclusión
Ya hemos visto bastante sobre los profiles (siempre hablando a nivel práctico). Como en todo, su uso es muy recomendable, pero su abuso no.

La tabla de los profiles de la base de datos que se crea ASP.NET supone un registro por cada usuario. Cada registro tiene un campo donde se guardan los datos en XML. Os podréis imaginar que a mayor complejidad, mayor es el XML... y cuantos más son los usuarios, más grande es la base de datos... supongo que no hace falta que os diga más