What's up with Custom Data?


During your time working with Kentico, you may have stumbled upon a field whose name includes “CustomData.” These fields can be found in many of the E-commerce related objects, such as ShoppingCarts, Orders, and CalculationRequests. In some cases, such fields can come in handy, storing additional E-commerce information that the objects don’t already contain. Their utility is furthered by the fact that in many cases, CustomData fields are automatically transferred to related objects.

CustomData fields are stored in the database with the NVARCHAR data type. In our code, they’re made up of ContainerCustomData objects, which implement IDataContainer. These objects provide methods to easily save and access data based on key/value pairs.

You can use the GetValue, SetValue, and Remove methods to perform basic CRUD operations for data stored in these fields.

Imagine we have some products associated with a charity, which provides dynamically calculated data about the results of new funds. For example, each purchase of a specific shirt enables the charity to provide some amount of clean water to third-world areas through the installation of filtration systems. You may want to tell your customer how many liters of clean water their purchase helped provide, how many machines have been set up, etc.

We can make a web service call for each shopping cart item to determine the number of liters of clean water it corresponds with, and store the result in custom data.

cartItem.CustomData.SetValue(“CleanWater”, MyService.GetCleanWater(CartItem));

Later on during the checkout, we can retrieve this value for display.

You can add it when constructing a view model inside of your controller like this:

List<CartItemViewModel> items = new List<CartItemViewModel>(); foreach(ShoppingCartItemInfo cartItem in EcommerceContext.CurrentShoppingCart.CartItems) { items.Add(new CartItemViewModel { //… CleanWater = cartItem.CustomData.GetDoubleValue(“CleanWater”, 0.0) } ); } return new ShoppingCartViewModel { //… CartItems = items }

Alternatively, you could use something like

ValidationHelper.GetDouble(cartItem.CustomData.GetValue(“CleanWater”), 0.0)

How does this data travel between different objects throughout the checkout process?

Custom data saved to a SKUInfo object will be accessible in pretty much every step of the way. ShoppingCartItems, CalculationRequestItems, and OrderItems all contain the SKUInfo of the products being purchased, so those objects and their custom data can be accessed.

Custom data saved to a ShoppingCartInfo object is automatically transferred to the CalculationRequest, and later onward to the resulting OrderInfo. Likewise, custom data from a ShoppingCartItemInfo is transferred to the corresponding CalculationRequestItem, and then to the resulting OrderItemInfo.

This should cover most scenarios in the checkout process, but if you need to access custom data during shipping calculation using Delivery and DeliveryItem objects, some extra steps are required. To transfer custom data from the CalculationRequest to the Delivery, override the InitCustomData method in a class that inherits from DefaultDeliveryBuilder like this:

protected override void InitCustomData(CalculationRequest request) { base.InitCustomData(request); // Single value SetCustomData("RegisteredCustomer", request.Customer.CustomerIsRegistered); // Add complete calculation requests custom data to delivery AddContainerToCustomData(request.RequestCustomData); }

Similarly, copying custom data from CalculationRequestItem objects to DeliveryItem objects can be done by overriding GetItemCustomDataContainers from the same class.

protected override void GetItemCustomDataContainers(List<IDataContainer> containers, CalculationRequestItem requestItem) {       base.GetItemCustomDataContainers(containers, requestItem);     containers.Add(requestItem.ItemCustomData); }

Custom data unlocks a lot of potential for your checkout process. It can help to display extra info to the customer, pass data to additional calculations, store the results of calls to external services, and probably do other things I haven’t even thought of… all without the need to modify the default classes! Can you find a use for it in your project?

Share this article on   LinkedIn

Matthew Sandstrom

Hello! I'm a Technical Training Specialist here at Kentico.