Commerce Server 2007: Accessing multi-valued custom properties in UserObject of Profile System

The MSDN's Managing Profiles section of the commerce server gives an in-depth view of the working of the profile system and the steps needed to create custom properties for the UserObject. The Extending the Profile System section gives out detailed steps to extend the profile system.

A frequently searched topic is to create, save and access Multi-Valued properties for the UserObject in the profile system.

1. Create Multi-valued profile properties
This is a straightforward profile editing activity on the commerce server, so would not go into it!

2. Saving into Multi-valued property
The below code snippet would do the trick for you. The key here is to set the new property value into an array and then assign the array to the Commerce Server Property.

 //create a GUID if not present
         emailToAdd.Id = Guid.NewGuid();
         //create the custom profile
         Profile emailProfile =
                 commerceContext.CreateProfile(emailToAdd.IdString, 
CommerceConstants.SAVED_EMAIL_PROFILE);
         //save properties first
         emailProfile.Properties[SavedEmailProfilePropertyNames.EmailId].Value 
             = emailToAdd.IdString;
         emailProfile.Properties[SavedEmailProfilePropertyNames.EmailName].Value 
             = emailToAdd.Name;
         //update back to the store
         emailProfile.Update();
         //refresh the cache
         emailProfile.Refresh();
         
         //get the owner profle
         using (Profile custProfile =
            commerceContext.GetProfile(CustProfilePropertyNames.Id, this.IdString,
            CommerceConstants.CUST_PROFILE))
         {              
             //if found, proceed for update
             if (custProfile != null)
             {

                 string[] additionalData;
                 //get preexisting multi values
                 object[] savedEmails = 
(object[])custProfile.Properties[CustProfilePropertyNames.ContactEmails].Value;
                 if (savedEmails != null)
                 {
                     //expand by 1
                     additionalData = new string[savedEmails.Length + 1];
                     int i = 0;
                     //assign back the current data to a new array
                     foreach (object item in savedEmails)
                     {

                         if (item != null && !(item as string).Equals("NULL"))
                         {
                             additionalData[i++] = item as string;
                         }
                     }
                     //add the item
                     additionalData[i] = emailToAdd.IdString;

                 }
                 else
                 {
                     //if no items preexist, add
                     additionalData = new string[1];
                     additionalData[0] = emailToAdd.IdString;
                 }
                 //save the multi valued items
                 custProfile.Properties[CustProfilePropertyNames.ContactEmails].Value = 
additionalData;
                 //update
                 custProfile.Update();
                 //refresh
                 custProfile.Refresh();
                 
             }
             else
             {
                 //no profile found, something not right!
                 throw new Exception("No profile found for user");
             }
         }
     }

3. Modifying Multi-valued property

The modifying the multi valued property is quite straight forward. If you are storing the profile Ids as done in the above example, you need to update the real/child profile rather than the multi-valued property. If you are directly consuming the multi-valued property, then you need to pass on the previous value, get the list of values as shown above, modify the required one and assign back the array and update.

4. Deleting Multi-valued property

Again, on the lines above, if you are using profile Ids, then delete the child profile, remove the Id from the array and save it back. If you are using the property itself, skip the item when assigning to the temporary array and save it back. One "GOTCHA" is when the multi-valued property has only one element - in this case use DBNull.Value to assign:

 custProfile.Properties[CustProfilePropertyNames.ContactEmails].Value = DBNull.Value;