Importing products using the API

You can import products from an external source of data into Xperience using the API. As a source of data, you can use, for example, a CSV (comma-separated values) file.

Note: Before you start the import process, make sure you have a back up of your Xperience database for recovery purposes in case any issues arise during the import process.

Preparing your product source data

Prepare your external source of data. Make sure that all product properties required for import into the Xperience database are included.

This example uses a CSV file containing the following records:

  • Field 1 - specifies the name of the product.
  • Field 2 - specifies the description of the product.
  • Field 3 - specifies the price of the product. Use a dot (.) to separate decimal places, e.g. 849.99.
  • Field 4 - specifies the department where the product will be placed after import. You need to enter the department code name, e.g. DancingGoatMvc.Brewers. If you leave the record empty or enter an invalid department code name, no department will be assigned to the product after import.

The sample file is available for download here.

Creating a console application for product imports

To import the products, create a new console application. The following sample console application allows you to import products specified in a CSV file into the Store -> Brewers section of the sample Dancing Goat MVC site as Brewers

  1. Create a new Console application project in Visual Studio

  2. Add the connection string of your Xperience instance to the application as described in: Using the Xperience API externally.

  3. Add the Kentico.Xperience.Libraries NuGet package to the project. The package version needs to match the hotfix version of the target Xperience project (and database).

  4. Copy the following code into the default Program.cs file.

    
    
    
     using System;
     using System.Globalization;
     using System.IO;
    
     using CMS.DataEngine;
     using CMS.DocumentEngine;
     using CMS.Ecommerce;
     using CMS.Membership;
     using CMS.SiteProvider;
    
     namespace ProductImport
     {
         public class ProductImport
         {
             // Contains the relative path of the file with product data to import
             // By default expects the file to be located in the same directory as the compiled console application
             private const string IMPORT_FILE_PATH = "products.csv";
    
             // Sets the page creator
             private const string CREATOR_USERNAME = "administrator";
    
             // Contains the code name of the site under which the products get imported 
             private const string TARGET_SITE_CODENAME = "DancingGoatMvc";
    
             // Class name of the page type associated with the imported products
             private const string PRODUCT_CLASSNAME = "DancingGoatMvc.Brewer";
    
             // Alias path to the desired parent page type in the product tree
             private const string PARENT_PAGE_ALIAS_PATH = "/Store/Brewers";
    
             // Desired document culture
             private const string DOCUMENT_CULTURE = "en-US";
    
             // The following members are initialized based on the information provided above
             private int siteId;
             private TreeProvider tree;
             private TreeNode parentPage;
             private DataClassInfo productPageType;
    
             // The main entry point of the application
             public static void Main(string[] args)
             {            
                 if (File.Exists(IMPORT_FILE_PATH))
                 {
                     // Initializes Xperience for use in an external application
                     CMSApplication.Init();
    
                     ProductImport importer = new ProductImport();
    
                     importer.Import();
                 }
                 else
                 {
                     Console.WriteLine($"The file \"{IMPORT_FILE_PATH}\" does not exist.");
                     Console.ReadKey();
                     Environment.Exit(1);
                 }            
    
                 Console.WriteLine($"Import process completed. Press any key to exit.");
                 Console.ReadKey();           
             }
    
             /// <summary>
             /// Parses the provided file and imports product data to Xperience.
             /// </summary>
             public void Import()
             {
                 // Retrieves contextual information necessary for the import process from the specified Xperience instance 
                 InitializeContextualInformation();
    
                 foreach (string line in File.ReadLines(IMPORT_FILE_PATH))
                 {
                     ProcessLine(line);
                 }
             }
    
             /// <summary>
             /// Retrieves and initializes Xperience objects and providers based on the provided configuration.
             /// </summary>
             private void InitializeContextualInformation()
             {
                 siteId = SiteInfoProvider.GetSiteID(TARGET_SITE_CODENAME);
    
                 UserInfo ui = UserInfo.Provider.Get(CREATOR_USERNAME);
    
                 if (ui != null)
                 {
                     tree = new TreeProvider(ui);
                 }
                 else
                 {
                     tree = new TreeProvider();
                 }
    
                 // Gets product parent page
                 parentPage = GetProductParentPage(tree);
    
                 // Gets the default product page type
                 productPageType = GetProductPageType();
             }
    
             /// <summary>
             /// Processes one line of the input file
             /// </summary>
             private void ProcessLine(string line)
             {
                 if (line != null && line.Trim() != String.Empty)
                 {
                     // Gets product data
                     string[] productData = line.Trim().Split(',');
    
                     ImportProduct(productData);
                 }
             }
    
             /// <summary>
             /// Imports products from the specified file in *.csv format
             /// </summary>
             private void ImportProduct(string[] productData)
             {
                 var sku = new SKUInfo
                 {
                     SKUName = productData[0],
                     SKUDescription = productData[1].Trim(),
                     SKUPrice = Decimal.Parse(productData[2].Trim(), CultureInfo.InvariantCulture),
                     SKUEnabled = true,
                     SKUSiteID = siteId,
                     SKUProductType = SKUProductTypeEnum.Product
                 };
    
                 DepartmentInfo department = DepartmentInfo.Provider.Get(productData[3], siteId);
                 if (department != null)
                 {
                     // Assigns the product to its department
                     sku.SKUDepartmentID = department.DepartmentID;
                 }
    
                 try
                 {
                     // Saves the created product to the database
                     SKUInfo.Provider.Set(sku);
                 }
                 catch (Exception ex)
                 {
                     Console.WriteLine($"Unable to create product '{sku.SKUName}'. See errors.txt for exception details.");
                     File.AppendAllText("errors.txt", ex.ToString());
                 }
    
                 // If the product was created successfully
                 if (sku.SKUID > 0)
                 {
                     // Creates a product page and assigns the SKU
                     var productDoc = (SKUTreeNode)TreeNode.New(productPageType.ClassName, tree);
    
                     productDoc.DocumentName = sku.SKUName;
                     productDoc.DocumentSKUName = sku.SKUName;
                     productDoc.DocumentSKUDescription = sku.SKUDescription;
                     productDoc.NodeSKUID = sku.SKUID;
                     productDoc.DocumentCulture = DOCUMENT_CULTURE;
    
                     try
                     {
                         productDoc.Insert(parentPage, true);
                         Console.WriteLine($"Imported {sku.SKUName}.");
                     }
                     catch (Exception ex)
                     {
                         Console.WriteLine($"Unable to create page '{sku.SKUName}'. See errors.txt for exception details.");
                         SKUInfo.Provider.Delete(sku);
                         File.AppendAllText("errors.txt", ex.ToString());
                     }
                 }
             }
    
             /// <summary>
             /// Ensures a parent page for product pages exists.
             /// </summary>
             private TreeNode GetProductParentPage(TreeProvider tree)
             {
                 // Attempts to get the product parent page
                 TreeNode parent = new DocumentQuery()
                                         .Path(PARENT_PAGE_ALIAS_PATH, PathTypeEnum.Single)
                                         .OnSite(TARGET_SITE_CODENAME)
                                         .AllCultures()
                                         .FirstOrDefault();      
    
                 // Parent not found
                 if (parent == null)
                 {
                     Console.WriteLine($"Unable to obtain a parent page type based on the provided alias path.");
                     Console.ReadKey();
                     Environment.Exit(1);               
                 }
    
                 return parent;
             }
    
             /// <summary>
             /// Ensures a default product page type exists.
             /// </summary>   
             private DataClassInfo GetProductPageType()
             {
                 DataClassInfo defaultProductType = DataClassInfoProvider.GetDataClassInfo(PRODUCT_CLASSNAME);
    
                 if (defaultProductType == null)
                 {
                     Console.WriteLine($"Unable to obtain a product page type from the provided codename.");
                     Environment.Exit(1);
                 }
    
                 return defaultProductType;
             }
         }
     }
    
    
    
     
  5. Modify the IMPORT_FILE_PATH constant to point to the location of the CSV file containing the product data to import.

  6. Build and run the application.

The applications imports the product into the target site (Dancing Goat MVC by default).

Modifying the console application

Adjust the code as required to:

Changing the target site

If you need to change the target site, adjust TARGET_SITE_CODENAME to the code name of the desired site. Site code names can be found in: Sites application -> edit () a site -> General tab.




// Contains the code name of the site under which the products get imported 
private const string TARGET_SITE_CODENAME = "DancingGoatMvc";


Changing the import location

If you need to change the import location, adjust the value of PARENT_PAGE_ALIAS_PATH.




// Alias path to the desired parent page type in the product tree
private const string PARENT_PAGE_ALIAS_PATH = "/Store/Brewers";


For example, if you want to import your products directly into the Store section, change the path to “/Store”. The system then adds the imported products under this parent page.

Changing the product type

If you need to change the product type, adjust the value of PRODUCT_CLASSNAME:




// Class name of the page type associated with the imported products
private const string PRODUCT_CLASSNAME = "DancingGoatMvc.Brewer";


For example, if you want to import your products as Coffee, change the value to “DancingGoatMvc.Coffee”.

To be able to perform the import, your website must have product types with the corresponding code names defined.

Changing the page culture

If you need to change the culture of the created pages, adjust the value of DOCUMENT_CULTURE:




// Desired document culture
private const string DOCUMENT_CULTURE = "en-US";


Changing the user account

If you need to change the user the pages associated with the imported products get created under, adjust the value of CREATOR_USERNAME:




// Sets the page creator
private const string CREATOR_USERNAME = "administrator";


Running the product import

Run the console application. The system runs the application’s code and informs you about the import result.

If you open the Products application, you can see the imported products listed under Store -> Brewers.