Upgrade Script: ConvertUsersToContact.aspx
This script utilizes the standard Task Manager in Sitecore in order to process contacts. If for some reason, you have the
processing\taskManager disabled, stopped, or otherwise not activated, the ConvertUsersToContact.aspx will hang on
Task is waiting for processing.
private string GetStatusString(ProcessingTaskStatus status)
return "Task is waiting for processing";
return "Failure. See log file for details";
With the advent of xDB in Sitecore 8, there are now two repositories that contain user/contact/visitor information.
In Sitecore, one is the User profiles
- These are the actual user accounts that Sitecore uses stored via the Membership provider mechanism.
- These are identified via a domain/ and can have custom profile information stored with them.
- And they have an email address.
In xDB, they are called Contacts.
- Contacts are identified by usually an email address and monitor and track interactions and page visits.
- Contacts contain a unique ID (GUID) that are key associated to the Interactions. (Note: this means that you could have multiple contacts with the same Email Address, but different Contact ID's. Out of scope of this answer)
- xDB can have custom facets for storing additional information.
- In Legacy ECM, there was no such thing as xDB, so the only user profile was from the membership provider.
- When ECM would create the user (say if you imported through CSV file), the User Name was in the manner of domain/emailaddress_at_somedomain_dot_com
- In EXM, EXM now uses xDB Contacts as the main contact record. Generally (OOTB) the email address is considered the primary identifier, especially when using the List Manager CSV upload (it can be changed though).
ONE BIG NOTE ABOUT IDENTIFIERS
When using the conversion tool above, notice the create user logic below:
public class UserToContactConvertor
public ProcessingResult Convert(Guid itemId)
User user = this.GetUser(itemId);
if ((Account) user == (Account) null)
ContactRepositoryBase contactRepositoryBase = Factory.CreateObject("tracking/contactRepository", true) as ContactRepositoryBase;
Assert.IsNotNull((object) contactRepositoryBase, "tracking/contactRepository");
LeaseOwner owner = new LeaseOwner("UserToContactConvertor", LeaseOwnerType.OutOfRequestWorker);
LockAttemptResult<Contact> lockAttemptResult = contactRepositoryBase.TryLoadContact(user.Name, owner, TimeSpan.FromMinutes(1.0));
contact = lockAttemptResult.Object;
contact = contactRepositoryBase.CreateContact(itemId);
Notice here that, if the contact is not found
LockAttemptStatus.NotFound, the creates a Contact and sets the identifier as the User.Name.
I bring this up, because if at any point in time in the future, you
load up a List from List Manager's CSV upload using the email address
as the identifier, or you utilize the
Tracker.Current.Session.Identify(string identifier) from the website
using email address as the identifier, you will effectively have two
distinct contacts with different identifiers.