Immediate Answer
While I have never used the Extended Contact Repository you linked, I have it on good authority that the methods FlushToXdb()
and SaveAndReleaseContacttoXdb()
are not the methods you want to use in Sitecore 8.2.
I believe the method you want to call is ContactManager.SaveAndReleaseContact(updatedContact);
Background Info on modifying and creating Contacts
Here is my full example, which works, again, not using the Extended Contact Repository:
Referencing Repository and Manager
This is used in the below examples where XdbContactRepository
and XdbContactManager
are used.
For full explanation, I've created a Factory for Contacts, that has an
XdbContactFactory, so that in the event Sitecore changes up contacts
again, I can just create a new factory and it'll work. I didn't expose the whole factory below. Just the relevant pieces.
private ContactManager _manager = Sitecore.Configuration.Factory.CreateObject("tracking/contactManager", true) as ContactManager;
private ContactRepository _repository = Sitecore.Configuration.Factory.CreateObject("tracking/contactRepository", true) as ContactRepository;
public ContactManager XdbContactManager
{
get { return _manager; }
}
public ContactRepository XdbContactRepository
{
get { return _repository; }
}
Creating/Loading the Contact
public override Contact GetXdbContact(string identifier)
{
var contact = XdbContactRepository.LoadContactReadOnly(identifier);
if (contact != null) return contact;
var leaseOwner = new LeaseOwner(GetType() + Guid.NewGuid().ToString(),LeaseOwnerType.OutOfRequestWorker);
contact = XdbContactRepository.CreateContact(Guid.NewGuid());
if (contact == null) return null;
contact.Identifiers.Identifier = identifier;
//Setting these values allows processing and aggregation to process this contact without erroring.
contact.System.Value = 0;
contact.System.VisitCount = 0;
//MAKE OTHER Contact Changes here too if you need to on Create.
XdbContactRepository.SaveContact(contact, new ContactSaveOptions(true,leaseOwner));
return contact;
}
Modifing the Contact
//Above Method
var currentContact = GetXdbContact(contactIfo.EmailAddress);
if (currentContact == null)
return;
var lockResult = XdbContactManager.TryLoadContact(currentContact.ContactId);
Contact updatedContact = currentContact;
switch (lockResult.Status)
{
case LockAttemptStatus.Success:
var lockedContact = lockResult.Object;
lockedContact.ContactSaveMode = ContactSaveMode.AlwaysSave;
updatedContact = SomeCustomMethod(lockedContact); //this method should do work on lockedContact and return lockedContact. this then saves it as updatedContact.
break;
case LockAttemptStatus.NotFound:
updatedContact = currentContact;
break;
default:
var exception = new Exception(GetType() + " Contact could not be locked - " + currentContact.ContactId);
Logger.Error(string.Format("[{1}:SaveContactInfoToXdb] Can't Lock or Find xDB Contact {0}", currentContact.ContactId, GetType()), exception);
break;
}
//Save Contact Information - This is the ContactManager method to use
XdbContactManager.SaveAndReleaseContact(updatedContact);
Contact Factets
I have found it WAY easier to create extension methods for accessing Contact facets.
public static IEmailAddress GetPreferredEmailAddress(this Contact contact)
{
var emailFacet = contact.GetFacet<IContactEmailAddresses>("Emails");
if (emailFacet.IsEmpty) return null;
var preferredEmail = emailFacet.Entries[emailFacet.Preferred];
return preferredEmail.IsEmpty ? null : preferredEmail;
}
public static IMarketingData GetMarketingData(this Contact contact)
{
// THIS IS A CUSTOM FACET THAT I CREATED FOR DEMO PURPOSE
var marketingFacet = contact.GetFacet<IMarketingData>("Marketing Data");
return marketingFacet;
}
public static IContactPersonalInfo GetPersonalProfile(this Contact contact)
{
var facet = contact.GetFacet<IContactPersonalInfo>("Personal");
return facet;
}
public static IContactAddresses GetAddressProfile(this Contact contact)
{
var facet = contact.GetFacet<IContactAddresses>("Addresses");
return facet;
}
public static IContactEmailAddresses GetEmailsProfile(this Contact contact)
{
var facet = contact.GetFacet<IContactEmailAddresses>("Emails");
return facet;
}
public static IContactPhoneNumbers GetPhoneProfile(this Contact contact)
{
var facet = contact.GetFacet<IContactPhoneNumbers>("Phone Numbers");
return facet;
}