Deploying objects with custom ID fields

When transferring data between instances of Kentico (via import/export or staging), the IDs of objects can differ between the environments. Kentico automatically “translates” the ID values for system objects, but not for custom objects. For example, when you stage a custom table or page type that contains a custom field storing object IDs, the values may not match the IDs of the objects on the target server.

You can ensure that the system correctly translates custom ID fields by handling the events in the ColumnsTranslationEvents class:

  • RegisterRecords - occurs on the source application when exporting objects. Handle this event to provide information for custom field translation.
  • TranslateColumns - occurs on the target application when importing objects. Handle this event to translate field values using the provided information.

Important

Handle the RegisterRecords event on the source application, and the TranslateColumns event on the target application. Add the handlers to both applications to ensure correct ID translation for both directions (for example bi-directional staging).

Example

The following example demonstrates how to implement custom ID translation for the UserID field of a custom table. The field stores the IDs of the users who own individual records in the custom table.

  1. Assign handlers to the ColumnsTranslationEvents.RegisterRecords.Execute and ColumnsTranslationEvents.TranslateColumns.Execute events. The example uses a custom class in the App_Code folder:

    
    
    
     using CMS.Base;
     using CMS.DataEngine;
     using CMS.CustomTables;
     using CMS.Helpers;
     using CMS.Membership;
    
     [ColumnTranslationHandlers]
     public partial class CMSModuleLoader
     {
         /// <summary>
         /// Custom attribute class.
         /// </summary>
         private class ColumnTranslationHandlers : CMSLoaderAttribute
         {
             /// <summary>
             /// Called automatically when the application starts
             /// </summary>
             public override void Init()
             {
                 // Add this code on the SOURCE application from which you are exporting the objects
                 // Assigns a handler method to the RegisterRecords event
                 ColumnsTranslationEvents.RegisterRecords.Execute += RegisterRecords_Execute;
    
                 // Add this code on the TARGET application where you are importing the objects
                 // Assigns a handler method to the TranslateColumns event
                 ColumnsTranslationEvents.TranslateColumns.Execute += TranslateColumns_Execute;
             }
         }
     }
    
    
     
  2. Define the handler methods (inside the custom CMSLoaderAttribute class):

    
    
    
     // Provides the ID translation data when exporting objects
     private void RegisterRecords_Execute(object sender, ColumnsTranslationEventArgs e)
     {
         // Registers custom column translation data for "customtable.sampletable"
         if (e.ObjectType == CustomTableItemProvider.GetObjectType("customtable.sampletable"))
         {
             // Gets the user ID from the custom table's data
             int userId = ValidationHelper.GetInteger(e.Data.GetValue("UserID"), 0);
    
             // Maps the user ID value to the corresponding username for every record in the custom table's data
             // Adds the mapping information into the export package
             e.TranslationHelper.RegisterRecord(PredefinedObjectType.USER, userId, UserInfoProvider.GetUserNameById(userId), 0);
         }
     }
    
     // Handles ID translation when importing objects
     private void TranslateColumns_Execute(object sender, ColumnsTranslationEventArgs e)
     {
         // Performs column translation for "customtable.sampletable"
         if (e.ObjectType == CustomTableItemProvider.GetObjectType("customtable.sampletable"))
         {
             // Translates the values of the UserID field in the table's data
             // Uses the mapping information in the import package to find the correct IDs based on the usernames
             e.TranslationHelper.TranslateColumn(e.Data, "UserID", PredefinedObjectType.USER, 0, true, true);
         }
     }
    
    
     
  3. Save the class.

When you transfer the custom table’s data between the applications using import/export or content staging, the handlers ensure correct translation of ID values for the UserID field.