Episerver Personalization with persistent anonymous profiles

Episerver Personalization is a powerful feature to ensure your website displays relevant content to your visitors. At Luminary we needed a way to persist an anonymous visitor's personalisation profile across sessions without using Episerver Insight or custom cookies. Here's how we did it...

Darren Stahlhut
Darren Stahlhut

12 October 2018

5 minute read

In this blog post, I'll explain how you can get the most out of Episerver's native Personalization features, when your client doesn't have a licence for Episerver Insight to track visitor activities. We combined native Microsoft ASP.NET features with Episerver's out-of-the-box Personalization Profile to implement a persistent anonymous profile (without using custom cookies) to deliver Visitor Group Personalization across sessions.

What exactly will you find in this blog?

  • Use  case scenarios
  • How to enable AnonymousIdentification in Episerver
  • How to add custom properties to an Episerver Personalization Profile
  • How to associate an AnonymousID with an Episerver Personalization Profile
  • How to set and get custom property values on an Episerver Personalization Profile
  • How to create Visitor Group Personalization criteria based on custom profile property values
  • Considerations for anonymous profile data maintenance

Use case scenarios

  • Active or explicit personalisation – this is when a visitor has interacted with your website and explicitly identified themselves as being interested in a particular location, product or service, for example, by submitting a form.
  • Passive or implicit personalisation – this is where a visitor's behaviour implies what they are interested in, for example visiting a particular product page.

Both of these scenarios are covered by Episerver's native Visitor Group Personalization at runtime, but it doesn't persist across sessions. This means when the visitor returns to the website, we had no ability to personalise content based on their previous behaviour.

The following sections explain how we overcame this, and saved data to custom properties in the anonymous visitor's Episerver Personalization Profile to personalise content in future visits.

How to enable AnonymousIdentification in Episerver

Firstly, we need a way to persist an AnonymousID for the visitor. This is actually a very simple Web.Config setting which is native to ASP.NET.

  <system.web>
    <anonymousIdentification enabled="true" />
  </system.web>

By default, this will add a cookie to the visitor's browser called .ASPXANONYMOUS that is valid for 100,000 minutes (around 70 days). This is not a custom cookie, it's a Microsoft ASP.Net cookie which includes an AnonymousID which we can associate with a User in Episerver and an Episerver Personalization Profile. 

ASPXANONYMOUS Cookie

If you're like me, you might need to know where in the cookie's Content the AnonymousID is defined. It turns out the Content is an encrypted string which includes the AnonymousID. You could decrypt it, but the easiest way to get it is via Request.AnonymousID which we will use a little later.

The official documentation explains how you could override the default values to set cookie name, expiration (the maximum is 2 years), etc.

How to add custom properties to an Episerver Personalization Profile

Also in your Web.Config inside <system.web> in the <profile> <properties> section you can add custom fields to the profile .

<profile defaultProvider="DefaultProfileProvider">
      <properties>
        <add name="Address" type="System.String" />
        <add name="ZipCode" type="System.String" />
        <add name="Locality" type="System.String" />
        <add name="Email" type="System.String" />
        <add name="FirstName" type="System.String" />
        <add name="LastName" type="System.String" />
        <add name="Language" type="System.String" />
        <add name="Country" type="System.String" />
        <add name="Company" type="System.String" />
        <add name="Title" type="System.String" />
        <add name="CustomExplorerTreePanel" type="System.String" />
        <add name="FileManagerFavourites" type="System.Collections.Generic.List`1[System.String]" />
        <add name="EditTreeSettings" type="EPiServer.Personalization.GuiSettings, EPiServer.Cms.AspNet" />
        <add name="ClientToolsActivationKey" type="System.String" />
        <add name="FrameworkName" type="System.String" />
        <!--custom fields-->
        <add name="CustomField1" type="System.String"/>
        <add name="CustomField2" type="System.String"/>
      </properties>
      <providers>
        <add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="EPiServerDB" applicationName="/" />
      </providers>
</profile>

A little later, I will demonstrate how to use Episerver API to set and get data from custom Profile Properties, and then establish Visitor Group Personalization based on the value of these properties. 

References: https://msdn.microsoft.com/en-us/library/2y3fs9xs.aspx

How to associate an AnonymousID with an Episerver Personalization Profile

As explained above, Microsoft has provided us with a persistent AnonymousID for the current user; we just need to associate that with an EPiServer.Personalization.Profile so that the system can later retrieve the Profile for Visitor Group Personalization.

We can achieve this by setting the System.Web.HttpContext.Current.Request.AnonymousID as the EPiServerProfile's Username and saving it as shown in the following snippet.

var username = System.Web.HttpContext.Current.Request.AnonymousID;
if (!string.IsNullOrEmpty(username))
{
    var currentProfile = EPiServerProfile.Get(username);
    if (currentProfile != null)
    {
        currentProfile.Save();
    }
}

The Save() method inserts (or updates) the User and Profile tables in the database.

If you want to confirm everything is working, you can pretty easily check the User and Profile tables with a simple SQL Query.

select * from Users
select * from Profiles

At this point you should be able to see your custom EPiServer.Personalization.Profile properties in the PropertyNames field and PropertyValueStrings field (which is stored as an XML string) in the Profile table.

Episerver User Profile tables

How to get and set custom property values on an Episever Personalization Profile

Now that we have the Visitor's AnonymousID associated an EPiServer.Personalization.Profile we can explicitly set and get the custom Profile Properties by using the TrySetProfileValue() combined with the Save() method, and the TryGetProfileValue() method.

TrySetProfileValue

var username = System.Web.HttpContext.Current.Request.AnonymousID;
if (!string.IsNullOrEmpty(username))
{
    var currentProfile = EPiServerProfile.Get(username);
    if (currentProfile != null)
    {
        currentProfile.TrySetProfileValue("customProperty1", "foo");
        currentProfile.TrySetProfileValue("customProperty2", "bar");
        currentProfile.Save();
    }
}

TryGetProfileValue

object customProperty1;
if (currentProfile.TryGetProfileValue("customProperty1", out customProperty1))
{
      //do something more cool than this with your custom profile property
      ViewData["customProperty1"] = customProperty1;
}

Depending on how the visitor interacts with your website, in a Controller's Action for example, you can now explicitly set or get their Profile Properties. In the next step we will explain how you can configure Visitor Groups to deliver personalised content based on these values.

How to create Visitor Group Personalization criteria based on custom Profile Property values

The final thing we need to do is to configure a Visitor Group based on the value of the Profile's custom properties, and confirm the website is serving personalised content for our anonymous visitors.

Create a new Visitor Group in the CMS > Visitor Groups > Create user interface. You should be able to drag in the Site Criteria > User Profile Visitor Group Criteria object, and select the custom property from the select list.

Episerver Visitor Group Profile Fields

Then in the CMS > Edit user interface, inside a Content Area, personalise a Block

Episerver Block Personalization

Set the Personalized Group to display a different Block if the visitor is a member of your new Visitor Group.

Episerver Block Personalized for Foo

In CMS > Edit > Preview mode, you can now select to preview as the Visitor Group and confirm its displaying correctly before you publish the page.

Episerver Block Preview Foo

And as a final test, you can now load the website in a clean browser to confirm that your anonymous visitor is getting a new cookie, an Episerver Profile with their custom profile properties set, and is being presented with Visitor Group personalised content.

Episerver Personlization Foo

Considerations for anonymous profile data maintenance

At Luminary, I have worked on some large scale enterprise marketing systems and have seen how quickly anonymous visitor profiles can grow. If you are planning to persist anonymous profiles in your Episerver database, I recommend you consider implementing a Scheduled Job to regularly tidy up this data. 

You can do this based on the LastUpdatedDate or LastActivityDate property in the EPiServer.Personalization.Profile class and delete profiles that haven't interacted with the website for a given period of time.

Wrapping it up

In this blog I've covered how we implemented a persistent anonymous Episerver Personalization Profile and used Visitor Groups to deliver personalised content across sessions.

In a follow-up blog post targeted at Episerver CMS editors, I will be discussing how editors can get the most out of Visitor Group Personalization and how to deal with complex scenarios like multiple nested Visitor Groups.


Need an agency with Episerver expertise?

Contact Us

Keep Reading

Want more? Here are some other blog posts you might be interested in.