Take the community feedback survey now.

PuneetGarg
Apr 26, 2022
  2701
(4 votes)

Content Migration from one to another property for live site

In one of my projects I recently faced an issue where we have to change all the standard category properties to IList<ContentReference> and the site was live so we just couldn't take the field and get it over with.

So I create new IList<ContentReference> properties and migrate the data and change the logic. Here are the steps that I followed.

Step To follow:-

    • Create new fields -- for all categories while don't remove old ones once
    • Create a scheduled job that migrates data from the old field to the new field
    • Switch the logic from old to new fields as new fields have multiple categories
    • remove old fields (only after running the migration job)

Step-1:-

We create new Ilist<contentreference> properties for every standard category property.

 

 [Display(
            Name = "Something",
            GroupName = SystemTabNames.Content,
            Order = 10)]
        [Categories]
        public virtual IList<ContentReference> Something { get; set; }

Step-2:-

Here we have to write the code so that content that is already existing on the live site migrates from old to new properties.

Few things that I did while creating a scheduled job:

        • Get all the pages where I changed the property, So for that, I created a generic method.
 private IEnumerable<T> GetDataList<T>()
            where T : ContentData
        {
            var objectType = _contentTypeRepository.Load<T>();
            var usages = _contentModelUsage.ListContentOfContentType(objectType)
                .Select(x => x.ContentLink.ToReferenceWithoutVersion())
                .Distinct()
                .Select(x => _contentLoader.Get<IContentData>(x))
                .OfType<T>()
                .ToList();
            return (IEnumerable<T>)usages;
        }

 

        • After this method call loop through all the pages and create a writeable clone so that we change the data
        • invoke the list and then assign the value to it.
 OnStatusChanged($"Migration start for ChapterDetailPage");

            var chapterDetailPages = GetDataList<ChapterDetailPage>();
            if (chapterDetailPages != null)
            {
                foreach (var cdp in chapterDetailPages)
                {
                    //migrate data
                    var page = (ChapterDetailPage)cdp.CreateWritableClone();
                    page.LocationIdNew = new List<ContentReference>();

                    var hit = _getaCatRep.TryGet(new ContentReference(page.LocationID), out stdCat) ? stdCat : null;
                    if (hit != null)
                    {
                        page.LocationIdNew.Add(hit.ContentLink);
                        _contentRepository.Save(page, SaveAction.Publish, AccessLevel.NoAccess);
                    }
                }
            }

            OnStatusChanged($"Migration end for ChapterDetailPage");
        • Then Save the page using the Content Repository.

Step-3

Change all the existing logic so that pages don't error.

Step-4

The last step will be to remove all old properties.

Apr 26, 2022

Comments

Please login to comment.
Latest blogs
Optimizely CMS Mixed Auth - Okta + ASP.NET Identity

Configuring mixed authentication and authorization in Optimizely CMS using Okta and ASP.NET Identity.

Damian Smutek | Oct 27, 2025 |

Optimizely: Multi-Step Form Creation Through Submission

I have been exploring Optimizely Forms recently and created a multi-step Customer Support Request Form with File Upload Functionality.  Let’s get...

Madhu | Oct 25, 2025 |

How to Add Multiple Authentication Providers to an Optimizely CMS 12 Site (Entra ID, Google, Facebook, and Local Identity)

Modern websites often need to let users sign in with their corporate account (Entra ID), their social identity (Google, Facebook), or a simple...

Francisco Quintanilla | Oct 22, 2025 |

Connecting the Dots Between Research and Specification to Implementation using NotebookLM

Overview As part of my day to day role as a solution architect I overlap with many clients, partners, solutions and technologies. I am often...

Scott Reed | Oct 22, 2025