HomeDev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideLegal TermsDev CommunityOptimizely AcademySubmit a ticketLog In
Dev Guide

Personalization.Commerce 3 breaking changes for Recommendations

Describes the changes from Personalization Commerce version 2 to version 3.

In version 3.0, the integration with the Personalization Service version 1.4 is updated with improved GDPR support. This update removes the user email and IP addresses from a tracking request.

This release introduces two configuration settings for controlling the tracking of user email and IP addresses.

📘

Note

If your site has existing tracking data, you must coordinate the switch from email to pseudonymous user identifier (by configuration or customization) with the Personalization Service team. Otherwise, existing tracking data and profiles built from user email address are lost when the user identifier changes.

Public interface changes

EPiServer.Tracking.Commerce namespace

  • RequestData
    Version 3.0 introduces the RequestData class, which represents basic data to be included in the tracking request, including all user information.
    /// <summary>
                /// Represents basic data to be included in the tracking request.
                /// </summary>
                public class RequestData
                {
                    /// <summary>
                    /// The client host (IP) address.
                    /// </summary>
                    public string UserHostAddress { get; set; }
            
                    /// <summary>
                    /// The current request URL.
                    /// </summary>
                    public string Url { get; set; }
            
                    /// <summary>
                    /// The referrer URL.
                    /// </summary>
                    public string UrlReferrer { get; set; }
            
                    /// <summary>
                    /// The user agent.
                    /// </summary>
                    public string UserAgent { get; set; }
                }
    
  • IRequestTrackingDataService
    Version 3.0 introduces the IRequestTrackingDataService, which gets basic data from the request, to include in the tracking data. To include/exclude IP address, register a custom implementation of the IRequestTrackingDataService interface. The default implementation of this interface uses the episerver:personalization.SkipUserHostTracking setting (mentioned above). A custom implementation could vary the setting based on user preference, cookies, and so on.
    public interface IRequestTrackingDataService
                {
                    /// <summary>
                    /// Gets basic data to be included in the tracking request.
                    /// </summary>
                    /// <param name="context">The http context.</param>
                    /// <returns>
                    /// A <see cref="RequestData"/> instance with the basic data to include in the tracking request.
                    /// </returns>
                    RequestData GetRequestData(HttpContextBase context);
            
                    /// <summary>
                    /// Gets user data to be included in the tracking request. 
                    /// </summary>
                    /// <param name="httpContext">The http context.</param>
                    /// <returns>An instance of <see cref="CommerceUserData"/>.</returns>
                    CommerceUserData GetUser(HttpContextBase httpContext);
                }
    

EPiServer.Tracking.Commerce.Data namespace

  • CommerceUserData
    To support GDPR, version 3.0 makes the Email property is obsolete, and introduces the Id property. The user Id should be pseudonymous, so it cannot be used to identify the person behind the user without combining the user ID with additional information.
    public class CommerceUserData
                {
                    /// <summary>
                    /// The name of the user.
                    /// </summary>
                    /// <remarks>
                    /// This information is not used, but is included for backwards compatibility. Will always be set to the same value as the Email property.
                    /// </remarks>
                    [Obsolete("This is no longer used. Will remain at least until July 2019.")]
                    [JsonIgnore]
                    public string Name { get; set; }
            
                    /// <summary>
                    /// The email address of the user.
                    /// </summary>
                    [Obsolete("This is no longer used. Set Id to a pseudonymous user ID instead. Will remain at least until July 2019.")]
                    [JsonIgnore]
                    public string Email { get; set; }
            
                    /// <summary>
                    /// The pseudonymous ID of the user.
                    /// </summary>
                    /// <remarks>
                    /// The user ID should be pseudonymous, so that it cannot be used to
                    /// identify the person behind the user without combining the user ID
                    /// with more information. E.g. an internal (random) numeric is OK,
                    /// a user name or email address is not.
                    /// </remarks>
                    public string Id { get; set; }
                }
    

You should make the constructor of XXXTrackingData obsolete (AttributeTrackingData, BrandTrackingData, CartTrackingData…) with HttpContextBase, and introduce a new constructor with the RequestData parameter. For example:

public class AttributeTrackingData : CommerceTrackingData
            {
                /// <summary>
                /// Data about the attribute.
                /// </summary>
                public AttributeData Attribute { get; }
        
                /// <summary>
                /// Initializes a new instance of the <see cref="AttributeTrackingData"/> class.
                /// </summary>
                /// <param name="attributeName">The name of the attribute.</param>
                /// <param name="attributeValue">The value of the attribute.</param>
                /// <param name="lang">The code for the language in which the content is viewed.</param>
                /// <param name="context">The current <see cref="HttpContextBase"/>.</param>
                /// <param name="user">The user.</param>
                [Obsolete("Use constructor with RequestData parameter. Will remain at least until July 2019.")]
                public AttributeTrackingData(string attributeName, string attributeValue, string lang, HttpContextBase context,
                    CommerceUserData user)
                    : this(attributeName, attributeValue, lang,
                        ServiceLocator.Current.GetInstance<IRequestTrackingDataService>().GetRequestData(context), user)
                {
                }
        
                /// <summary>
                /// Initializes a new instance of the <see cref="AttributeTrackingData"/> class.
                /// </summary>
                /// <param name="attributeName">The name of the attribute.</param>
                /// <param name="attributeValue">The value of the attribute.</param>
                /// <param name="lang">The code for the language in which the content is viewed.</param>
                /// <param name="requestData">The request data.</param>
                /// <param name="user">The user.</param>
                public AttributeTrackingData(string attributeName, string attributeValue, string lang, RequestData requestData,
                    CommerceUserData user)
                    : base(TrackingType.Attribute, lang, requestData, user)
                {
                    Attribute = new AttributeData(attributeName, attributeValue);
                }
            }