posted on Friday, October 26, 2007 6:03 PM | Filed Under [ DotNetNuke ]

Welcome back! This is part III of the Making Your DotNetNuke Module Do More For You series. Last time I brought you some ways to have your module interact with the DotNetNuke page that it lives on: Utilizing Your DotNetNuke Module's Data Access Layer.

Amongst other things, I showed you how to read and write settings for your module instance. Today I will show you how to read and write unique values for each DotNetNuke user of your module.

The Personalization Namespace

To store and retrieve values that are unique to one particular user you can use classes from the DotNetNuke.Services.Personalization namespace. We will first be interested in the Personalization class within this namepace. The DotNetNuke.Services.Personalization.Personalization class contains a number of static (aka shared) methods that will get, set, and remove custom key-value pairs of data for an authenticated user.

Storing Personalization Data

SetProfile(ByVal NamingContainer As String, ByVal Key As String, ByVal Value As Object)

This version of SetProfile will store an object in the profile of the current authenticated user. If there is no authenticated user, this method does nothing. The first parameter NamingContainer is exactly what it sounds like, a naming container. In this context the NamingContainer string represents some entity with which you wish to associate the data. As a rule of thumb a module developer will use the current module instance for the naming container, unless it makes sense to make the naming container a different scope, like the PortalId or a constant name used between related modules.

The second parameter is a string type that is used to create a key for retrieving the data you are storing. You should use a meaningful name here. For instance, if you are storing the date of the user’s last visit, you could use the string “last_visit” as a key. You might also consider using your module or company name here to help you identify that data if it is ever seen by human eyes at the DAL layer.

The final parameter of the SetProfile() method is the data you wish to store. The parameter is of type object, so you could in theory specify anything here. However, this data gets serialized to xml behind the scenes, so you might keep in mind that the object you specify needs to play well with an XmlSerializer. It might help to implement the IXmlSerializable interface if you want control over how your custom class gets serialized and de-serialized.

In this example we store the string value “Purple” under the key “Favorite Color”, using the current module as the naming container:

    1 DotNetNuke.Services.Personalization.Personalization.SetProfile(

    2    ModuleId.ToString(), "Favorite Color", "Purple");

The second method that the Personalization class has for storing data is an overloaded version of SetProfile() that takes an extra parameter in the front.

    1 SetProfile(ByVal objPersonalization As PersonalizationInfo, ByVal NamingContainer As String, ByVal Key As String, ByVal Value As Object)

This method does the same thing that the original SetProfile() method does, except it allows you to specify a PersonalizationInfo object that contains the profile of the user that you want to store personalization data for.

This can be very useful if you need to initialize personalization info for all the users in a portal:

    1 // save some blog space, in all examples

    2 using DotNetNuke.Services.Personalization;

    3 using DotNetNuke.Entities.Users;

...

    1 // Instantiate a PersonalizationController

    2 // to use for loading profiles

    3 PersonalizationController persController

    4    = new PersonalizationController();

    5 

    6 // Get array of UserInfo,

    7 // containing all users in portal

    8 ArrayList array = UserController.GetUsers(PortalId);

    9 

   10 // Process each UserInfo

   11 // to set profile data

   12 foreach (object userInfo in array)

   13 {

   14    // get PersonalizationInfo object for user

   15    PersonalizationInfo persInfo

   16         = persController.LoadProfile(

   17             ((UserInfo)userInfo).UserID, PortalId);

   18    if (persInfo != null)

   19    {

   20         // initialize personalization information

   21         Personalization.SetProfile(

   22             persInfo,

   23             ModuleId.ToString(),

   24             "Favorite Color",

   25             "Purple");

   26    }

   27 }

The code above retrieves an array of UserInfo type, one UserInfo object for each user in the portal. A PersonalizationInfo object is retrieved using data from each UserInfo object. Then the PersonalizationInfo object is used to call the overloaded SetProfile method.

Retrieving Personalization Data

GetProfile(ByVal NamingContainer As String, ByVal Key As String)

The GetProfile() method retrieves the data you stored using the SetProfile() method. The first parameter is the naming container you used when you called SetProfile() to store the data. The second parameter is the key you used to store the data using the SetProfile() method.

The GetProfile() method returns the requested data as a simple object type, so you must re-box the object to its original type. GetProfile() will return an empty string if no user is authenticated.

    1 string favColor =

    2    (string)Personalization.GetProfile(

    3         ModuleId.ToString(),

    4         "Favorite Color");

The code above retrieves the string “Purple” (assuming you first initialized the “Favorite Color” entry using the first SetProfile() example above).

Just like the SetProfile() method, the GetProfile() method also has an overloaded version which allows you to specify a PersonalizationInfo object, so you can read a value from the profile of a particular user that isn’t necessarily authenticated.

GetProfile(ByVal objPersonalization As PersonalizationInfo, ByVal NamingContainer As String, ByVal Key As String)

The overloaded GetProfile() method might be useful if your module needs to perform different actions for different users, based on a particular piece of data in the profile of the user. For instance the following code could be used to contact all the users, each using the method they prefer:

    1 // Instantiate a PersonalizationController

    2 // to use for loading profiles

    3 PersonalizationController persController

    4    = new PersonalizationController();

    5 

    6 // Get array of UserInfo,

    7 // containing all users in portal

    8 ArrayList array = UserController.GetUsers(PortalId);

    9 

   10 // Process each UserInfo

   11 // to set profile data

   12 foreach (object userInfo in array)

   13 {

   14    // get PersonalizationInfo object for user

   15    PersonalizationInfo persInfo

   16         = persController.LoadProfile(

   17             ((UserInfo)userInfo).UserID, PortalId);

   18    if (persInfo != null)

   19    {

   20         switch (

   21             (string)Personalization.GetProfile(

   22                persInfo,

   23                ModuleId.ToString(),

   24                "Contact Method"))

   25         {

   26             case "email":

   27                // call email method

   28                break;

   29             case "sms":

   30                // call sms service

   31                break;

   32         }

   33    }

   34 }

The code above loops through the profiles of every user in the portal and contacts them based on the personalization data stored with the key "Contact Method".

Removing Personalization Data

RemoveProfile(ByVal NamingContainer As String, ByVal Key As String)

The RemoveProfile() method does the reverse of the SetProfile() method. That is, it will remove the personalization entry for the authenticated user. If there is no authenticated user, this method does nothing.

This method takes the same parameters as the GetProfile() method. The first parameter is the naming container you used to store data. The second parameter is the key you used to store the data.

    1 Personalization.RemoveProfile(

    2    ModuleId.ToString(),

    3    "Favorite Color");

Like both SetProfile() and GetProfile(), this method has an overload that allows you to specify a PersonalizationInfo object containing the user profile you wish to remove a value from.

RemoveProfile(ByVal objPersonalization As PersonalizationInfo, ByVal NamingContainer As String, ByVal Key As String)

This could be used to remove a personalization setting for all the users in a portal:

    1 // Instantiate a PersonalizationController

    2 // to use for loading profiles

    3 PersonalizationController persController

    4    = new PersonalizationController();

    5 

    6 // Get array of UserInfo,

    7 // containing all users in portal

    8 ArrayList array = UserController.GetUsers(PortalId);

    9 

   10 // Process each UserInfo

   11 // to set profile data

   12 foreach (object userInfo in array)

   13 {

   14    // get PersonalizationInfo object for user

   15    PersonalizationInfo persInfo

   16         = persController.LoadProfile(

   17             ((UserInfo)userInfo).UserID, PortalId);

   18    if (persInfo != null)

   19    {

   20         // remove personalization information

   21         Personalization.RemoveProfile(

   22             ModuleId.ToString(),

   23             "Favorite Color");

   24    }

   25 }

The code above loops through the profiles of every user in the portal and removes the personalization data stored in the current module's naming container with the key "Favorite Color".

To Summarize

  1. You can store custom data for each user without creating custom DAL code by leveraging the DotNetNuke framework's Personalization namespace and Personalization class.
  2. The Personalization class has methods SetProfile(), GetProfile(), and RemoveProfile(), which can (respectively) store, retrieve, and delete custom user data.
  3. SetProfile(), GetProfile(), and RemoveProfile() each have an overload that allows you to specify a PersonalizationInfo object that contains the profile of a particular user that you wish to read or modify.

I hope you find the information in this article useful. Stay tuned for upcoming segments where I will show you how to dynamically create DotNetNuke pages (tabs) from within a module. I also hope to bring you a more detailed overview of the DotNetNuke user infrastructure.

Thanks for reading!

Comments Leave Yours...
Joe Craig
11/3/2007 2:21 PM
# re: Let’s Talk DotNetNuke User Personalization

Rafe,

This is a wonderful blog. I'll see you Vegas!

Vadim
2/11/2008 3:51 PM
# re: Let’s Talk DotNetNuke User Personalization

Well, fine. What about per-user personalization? It seems that DNN community doesn't and won't support that. What I mean is not the "color" but the ability of the user to configure his/her home page with a set of modules (admin like functionality but per the user). In practical terms it means that you cannot create something like My Yahoo! using DNN framework. The guy who attempted to do this on his own gave up (http://www.smart-thinker.com/DotNetNuke/HomePage/tabid/159/Default.aspx).

Rafe Kemmis
2/11/2008 6:07 PM
# re: Let’s Talk DotNetNuke User Personalization

Vadim,

One of the main features of the upcoming Cambrian release is a set of features centered around social networking. Hopefully this means that users will have their own customizable profiles pages... think myspace, facebook, etc...

Here is Shaun's keynote from back in November, which includes general information about the Cambrian release: http://www.openforce07.com/Portals/0/OpenForce%20Keynote.pdf

Dan Berkich
3/19/2008 3:51 PM
# re: Let’s Talk DotNetNuke User Personalization

I am using Michael Washington's IWeb module to perform secure webservice access. When the page is loaded a personalization key is set with an encryption value. As I step through the code I can see that the key/value pair is created in the profile hash table. A call is then made to save the profile. When I make an ajax call to the webservice and attempt to read the key the value no longer exists although I can see all the other personalization info in the hash table that existed when the value is set. Is there some kind of caching problem going on here?

Using DNN 4.71

Rafe Kemmis
3/28/2008 6:38 AM
# re: Let’s Talk DotNetNuke User Personalization

Dan, I bet Michael can help you out with this. Give him a shout over on the dnn forums @ dotnetnuke.com.

River
5/28/2008 9:31 PM
# re: Let’s Talk DotNetNuke User Personalization

I know personalization allows me to store "objects". How complex can these objects be? Lets say I have a list box filled with color options, and the list box allows multiple selections. Once a user has selected all his favorite colors, and hits "Save", Can I grab the List box object and store it with personalization? And then the next time he visits I'll load his personalized list box instead of the default one?
I've tried it and DNN doesnt seem to like that idea.

Any thoughts?

Rafe
5/29/2008 8:15 AM
# re: Let’s Talk DotNetNuke User Personalization

River,

There are two things to keep in mind. First, the DNN framework eventually serializes the object into xml using the System.Xml.Serialization.XmlSerializer class. In order for a complicated class to serialize and deserialize correctly you may need to tweak the class using special attributes. See the "Controlling Generated XML" section here:

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx

Rather than trying to serialize the entire list box, you really should just store the information that you need. So grab the selected values like this, then store those using personalization:

List<string> selectedIndexes = new List<string>();
foreach (ListItem item in ListBox1.Items)
{
if (item.Selected)
{
selectedIndexes.Add(item.Value);
}
}
A list of strings will probably serialize better than a ListBox.

The second thing you should keep in mind is that you might need to manually save the profile using the personalizationcontroller. I don't recall if I left this out of the article intentionally. So try saving the profile like this:

perController.SaveProfile(persInfo);

perController is an instance of PersonalizationController and persInfo is the PersonalizationInfo object that you passed to SetProfile().

Good luck—I hope this helps you!

Rafe

Baldwin's DNN
7/7/2008 8:10 PM
# 如何在DNN创建类IGoogle效果的模块

如果你开发过DNN模块,你应该知道DNN每个模块都存在一个模块设置,在此你可以设置某一模块实例的相关信息,比如:模块名称,模块权限,模块容器皮肤等等。而有时你如果想扩展模块设置,增加自己的设置项,那你可以继承ModuleSettingsBase,该基类主要存在两个方法LoadSettings和UpdateSettings:<br /><br /><br /><br />&#160;<br /><br /> '''&#160;&lt;sum ...

Baldwin's DNN
7/8/2008 10:12 AM
# 如何在DNN创建类IGoogle效果的模块

借助Blog的一个扩展模块展示如何在DNN实现类IGoogle模块?算是抛砖引玉,为大家提供一种新的思路,感兴趣着不妨看看... ...

Post Your Comment

Title
Required
Name
Required
Email
Optional
Url
Optional
Comment  
Please add 8 and 4 and type the answer here:

Who Is Rafe

rafe

I Am Rafe Kemmis

I am an audacious entrepreneur with a double bachelor of science in Computer Science and Mathematics. I specialize in Microsoft ASP.Net web application development as well as accredited information systems auditing.

Questions?

Always a thoughtful response. You may post your question on an article, or contact me directly.

Hire Me.

I provide custom solutions to complex problems. I can help your business no matter how large or small.

Contact me now.

Subscribe