In SiteCore xDB, if you want to extend contact attributes with your own organization specific data then you can create custom contact facets.
A Facet is a group of hierarchically organized related attibutes that describe certain aspect of a Contact.
For example, say you are a Pictures product company and you want to collect additional information about customers as they browse your website and you want to track a custom and unique identity like MediaName as well as a MediaURL property for each of your customers. These two pieces of information are related into a collection called “Marketing Analytics Data”. This is what we say Sitecore xDB Facet.
A contact is made up of facets. Here are all the facets Sitecore uses (you will find the facets in \App_Config\Include\Sitecore.Analytics.Model.Config):
<facets>
<facet name=”Personal” contract=”Sitecore.Analytics.Model.Entities.IContactPersonalInfo, Sitecore.Analytics.Model” />
<facet name=”Addresses” contract=”Sitecore.Analytics.Model.Entities.IContactAddresses, Sitecore.Analytics.Model” />
<facet name=”Emails” contract=”Sitecore.Analytics.Model.Entities.IContactEmailAddresses, Sitecore.Analytics.Model” />
<facet name=”Phone Numbers” contract=”Sitecore.Analytics.Model.Entities.IContactPhoneNumbers, Sitecore.Analytics.Model” />
<facet name=”Picture” contract=”Sitecore.Analytics.Model.Entities.IContactPicture, Sitecore.Analytics.Model” />
<facet name=”Communication Profile” contract=”Sitecore.Analytics.Model.Entities.IContactCommunicationProfile, Sitecore.Analytics.Model” />
<facet name=”Preferences” contract=”Sitecore.Analytics.Model.Entities.IContactPreferences, Sitecore.Analytics.Model” />
</facets>
In this example I will add facet that consists of MediaName and MediaURL of type strings, I will call it “MediaDownloads” facet – this is my custom facet.
Follow below mentioned Steps to create custom Facets:
Step1 : The “MediaDownloads” is a Facet, the list below consists of Elements. So I need to create a IFacet interface and a IElement interface.
using Sitecore.Analytics.Model.Framework;
public interface IMediaElement : IElement
{
string MediaName { get; set; }
string MediaURL { get; set; }
}
public interface IMediaFacet: IFacet
{
IElementCollection<IMediaElement> Downloads { get; }
}
Step2 : Now, we need to create concrete classes implementing IMediaFacet and IMediaElement:
Below is MediaFacets concrete class:
[Serializable]
public class MediaFacet : Facet, IMediaFacet
{
private const string DOWNLOADS = “Downloads”;
private const string UPLOADS = “Uploads”;
public IElementCollection<IMediaElement> Downloads
{
get { return GetCollection<IMediaElement>(DOWNLOADS); }
}
public IElementCollection<IMediaElement> Uploads
{
get { return GetCollection<IMediaElement>(UPLOADS); }
}
public MediaFacet()
{
EnsureCollection<IMediaElement>(DOWNLOADS);
EnsureCollection<IMediaElement>(UPLOADS);
}
}
Below is the MediaElement concrete class:
[Serializable]
public class MediaElement : Element, IMediaElement
{
private const string MEDIANAME = “MediaName”;
private const string MEDIAURL = “MediaURL”;
public string MediaName
{
get
{
return GetAttribute<string>(MEDIANAME);
}
set
{
this.SetAttribute(MEDIANAME, value);
}
}
public string MediaURL
{
get {
return GetAttribute<string>(MEDIAURL);
}
set
{
this.SetAttribute(MEDIAURL, value);
}
}
public MediaElement()
{
EnsureAttribute<string>(MEDIANAME);
EnsureAttribute<string>(MEDIAURL);
}
Getting and setting properties are done using GetAttribute and SetAttribute methods retrieved from Sitecore.Analytics.Model.Framework.Element and Sitecore.Analytics.Model.Framework.Facet.
Step 3: Register Facet in Sitecore configuration file that includes Elements as shown below :
<model>
<elements>
<element patch:after=”element[@interface=’Sitecore.Analytics.Model.Entities.IContactPreferences, Sitecore.Analytics.Model’]” interface=”AppWeb.Controllers.Renderers.Composite.IMediaElement, AppWeb” implementation=”AppWeb.Controllers.Renderers.Composite.MediaElement, AppWeb”>
<element patch:after=”element[@interface=’Sitecore.Analytics.Model.Entities.IContactPreferences, Sitecore.Analytics.Model’]” interface=”AppWeb.Controllers.Renderers.Composite.IMediaFacet, AppWeb” implementation=”AppWeb.Controllers.Renderers.Composite.MediaFacet, AppWeb”></element>
</elements>
<entities>
<contact>
<facets>
<facet patch:after=”facet[@name=’Preferences’]” name=”MediaDownloads” contract=”AppWeb.Controllers.Renderers.Composite.IMediaFacet, AppWeb”></facet>
</facets>
</contact>
</entities>
</model>
So as you can see, both my interfaces are defined in <elements/>. The <elements/> describes the implementation of the interface.
The facet is defined in <facets/> with a unique name. This unique name is the name you use to find the facet when you need to access it.
Validate Your configuration by checking /sitecore/admin/showconfig.aspx
Step 4:
var mediaDownloads = Tracker.Current.Contact.GetFacet<IMediaFacet>(“MediaDownloads”);
var download = mediaDownloads.Downloads.Create();
download.MediaName = “Sukesh”;
download.MediaURL = “https://google.com”;
Notice the contact.GetFacet<>() method. Here you specify the name of the facet you defined in the <facets/> section of the config file.
Remember that facets are not written to MongoDB before your session ends.
Below the data that gets stored in Mongo DB for Facets: