Outcome Data classes

Current version: 10.2

The Outcome Data classes are very similar in construct to the Analytics Data classes.

The Outcome Data classes expose two methods when data is being serialized into the interaction and one method to rehydrate the content.

Name

Description

Initialize

In the context of triggering an outcome, call this method and pass in the arguments passed into the service request. It is the responsibility of the specific Outcome Data object to know how to parse the Request and Result objects to extract the data to be serialized.

Serialize

Call this method to serialize the content into the given dictionary, which is then written into the interaction’s page event or goal custom values.

Deserialize

Call this method to rehydrate the content of the data class. Currently used by the Connect Experience Profile and Experience Analytics reporting components

When data is being serialized, the following utility methods are available:

Name

Description

AddEntityToSimpleValues<T>

This templated method is used when adding Connect entities to the custom values dictionary.

Note

It is very important to use this method instead of adding Connect entities directly.

This method does a few things. First, it saves the base entity values only, stripped out of any extension that might have been made by ECS. This because in a distributed environment, the ECS specific data types might not be available and would cause problems on the reporting and processing servers during the deserialization phase.

In the case where both these servers are in your own domain and control, having the original “custom” ECS entity might be desirable. In this case, the following setting is available in the Sitecore.Commerce.config file:

RequestResponse
<setting name="Commerce.Analytics.EntitiesIncludedInXDB" value="Base"/>

Valid values are:

  • Base

  • Custome

  • Both

Base saves the base entity only.

Custom saves the original given entity.

Both saves the base entity and original version.

By default, Base is configured.

The outcome custom data is always a string and is handled by this method call.

For more information, see the Experience Profile Commerce tab topic.  

When data is being rehydrated, use the following utility methods:

The above methods allow you to retrieve a value from the serialized list for any type that you require. The GetMandatoryValueAsString method adds some extra error handling code in case the mandatory parameter is not found, such as adding proper null checks and logging.

The GetOptionalValueAsObject method is the same as the GetMandatory* methods except no error logging will occur if the key is not present.

The following shows the Connect implementation of the visitor order created outcome that is registered when a new visitor order is created:

RequestResponse
public class SubmittedOrderOutcomeData : BaseOutcomeData
{
public string ExternalId { get; set; }
   public string ShopName { get; set; }
   public Order Order { get; set; }
   public override void Initialize(Pipelines.ServicePipelineArgs args)
   {
   base.Initialize(args);
       this.Order = this.GetOrderFromArgs();
       if (this.Order != null)
       {
       this.ExternalId = this.Order.ExternalId;
           this.ShopName = this.Order.ShopName;
       }
   }
public void Initialize(Order order)
{
this.ServicePipelineArgs = null;
       this.Order = order;
       if (this.Order != null)
       {
       this.ExternalId = this.Order.ExternalId;
           this.ShopName = this.Order.ShopName;
       }
   }
public override void Serialize(Dictionary<string, string> values)
   {
   if (this.Order != null)
       {
       values[Constants.KnownPageEventDataNames.ExternalId] = this.ExternalId;
           values[Constants.KnownPageEventDataNames.ShopName] = this.ShopName;
           this.AddEntityToSimpleValues<Order>(this.Order, values, Constants.KnownPageEventDataNames.Order);
       }
   }
public override void Deserialize(Dictionary<string, string> values)
   {
   this.ExternalId = this.GetMandatoryValueAsString(Constants.KnownPageEventDataNames.ExternalId, values);
       this.ShopName = this.GetMandatoryValueAsString(Constants.KnownPageEventDataNames.ShopName, values);
       this.Order = this.GetOptionalValueAsObject<Order>(Constants.KnownPageEventDataNames.Order, values);
       base.Deserialize(values);
   }
public override decimal GetMonetaryValue()
   {
   return this.Order.Total == null ? 0m : this.Order.Total.Amount;
   }
public virtual bool? IsOfflineOrder()
   {
   bool? isOfflineOrder = false;
       if (this.Order != null)
       {
       isOfflineOrder = this.Order.IsOfflineOrder;
       }
       return isOfflineOrder;
   }
protected virtual Order GetOrderFromArgs()
   {
   if (this.ServicePipelineArgs != null && this.ServicePipelineArgs.Result is SubmitVisitorOrderResult)
       {
       return ((SubmitVisitorOrderResult)this.ServicePipelineArgs.Result).Order;
       }
       return null;
   }
}

There are a few things worth mentioning:

  • Two Initialize methods exist. The first takes the ServicePipelineArgs as it is being called by the trigger outcome mechanism. The second one takes an Order as it is used during the registering of the off-line orders process.

  • The Serialize method makes use of the AddEntityToSimpleValues() template method to add the order to the outcome.

The following code snippet demonstrates how you would consume the outcome custom data:

RequestResponse
Dictionary<string, string> customValues = 
JsonConvert.DeserializeObject<Dictionary<string, string>>
(contactOutcome.CustomValues[Constants.KnownAnalyticsKeys.SitecoreCommerceOutcomeKey]);
var outcomeData = OutcomeDataFactory.Create<SubmittedOrderOutcomeData>();
outcomeData.Deserialize(customValues);

The above assumes you have the Sitecore outcome for the contact. The ContactOutcome class contains the custom value information in a serialized format. This means you must deserialize the custom value dictionary prior to calling the SubmittedOrderOutcomeData deserialize method. In the near future, we will encapsulate this functionality in the BaseOutcomeData class.

Do you have some feedback for us?

If you have suggestions for improving this article,