One way to import pages from Episerver 4 to 7

I was given the task to import pages from Episerver 4.6 to a new Episerver 7 site. Access was limited and I had no possibility to modify the code or configuration of the 4.6 project. I went for a solution where an export package was used.

First I needed the XML of the decrypted export package.

  1. Exported pages from Episerver 4 and ran Fredrik Haglund's Decryption tool for Episerver 4 Export Packages on my .epi4 file.
  2. Unzip the decrypted file and open the Data file in text program to see if have some XML there, I also added .xml to the name.

I was only interested in some of the page types and only a selected few other properties so I created a generic class to put in between a XML RawPage and my new EPi 7 Page. This also helped me to keep track of the parent/child relationships in the Data file.

private class ImportItem
{
    public int ID { get; set; }

    public int ParentID { get; set; }

    public int PageTypeID { get; set; }

    public DateTime StartPublish { get; set; }

    public string PageName { get; set; }

    public Dictionary OtherProperties { get; set; }

    public ContentReference NewContentReference { get; set; }
}

My Data XML file was massive in file size so I needed to use a XmlTextReader, to still be able to use XElement niceness I use ReadSubtree() for one page element at a time. In my case Import() is called from a Episerver Scheduled Task.

private string Import()
{
    var all = new List<ImportItem>();

    // TODO: Path to your Data file needs to be set
    using (var reader = new XmlTextReader("file:///C:/Data.xml"))
    {
        while (reader.Read())
        {
            switch (reader.NodeType)
            {
                case XmlNodeType.Element:
                    if (reader.Name.Equals("RawPage"))
                    {
                        using (var pageReader = reader.ReadSubtree())
                        {
                            var rawPage = XElement.Load(pageReader);
                            var properties = rawPage.Descendants("RawProperty").ToList();
                            var otherProperties = new Dictionary();

                            foreach (var p in properties)
                            {
                                switch (p.Element("Name").Value)
                                {
                                    case MetaDataProperties.PageChildOrderRule:
                                    case MetaDataProperties.PagePeerOrder:

                                    // Office
                                    case "Name":
                                    case "Address":
                                    case "LegalName":
                                    case "Phone":
                                    case "Email":
                                    case "OfficeID":

                                    // Person
                                    case "FirstName":
                                    case "LastName":
                                    case "Title":
                                    case "WorkPhone":
                                    case "WorkMobile":
                                    case "PersonalPhone":
                                    case "PersonalMobile":
                                    case "Email":
                                        if (p.Element("Value") != null
                                           && p.Element("Value").Value != null)
                                        {
                                            otherProperties.Add(
                                               p.Element("Name").Value,
                                               p.Element("Value").Value);
                                        }

                                        break;
                                }
                            }

                            all.Add(new ImportItem
                            {
                                PageTypeID = properties.Single(x => x.Element("Name")
                                     .Value.Equals("PageTypeID")).Element("Value")
                                     .Value.ToInt(),
                                ID = properties.Single(x => x.Element("Name")
                                  .Value.Equals("PageLink")).Element("Value").Value.ToInt(),
                                ParentID = properties.Single(x => x.Element("Name")
                                   .Value.Equals("PageParentLink")).Element("Value")
                                     .Value.ToInt(),
                                StartPublish = properties.Single(x => x.Element("Name")
                                  .Value.Equals("PageStartPublish")).Element("Value")
                                  .Value.ToDateTime(),
                                PageName = properties.Single(x => x.Element("Name")
                                  .Value.Equals("PageName")).Element("Value").Value,
                                OtherProperties = otherProperties
                            });
                        }
                    }

                    break;
            }
        }
    }

    var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();

    // TODO: Put the Export package starting point PageLink.ID here
    var root = all.SingleOrDefault(x => x.ID == 318);

    if (root != null)
    {
        // My EPi 7 starting point is added below the start page
        var page = contentRepository.GetDefault(PageReference.StartPage);
        page.PageName = root.PageName + " " + DateTime.Now;
        page[MetaDataProperties.PageChildOrderRule] =
          root.OtherProperties[MetaDataProperties.PageChildOrderRule];
        page[MetaDataProperties.PagePeerOrder] =
          root.OtherProperties[MetaDataProperties.PagePeerOrder];
        root.NewContentReference = contentRepository.Save(
          page, SaveAction.Publish, AccessLevel.NoAccess);
        this.SaveChildren(ref contentRepository, root.ID, ref all);
    }

    return "Done.";
}

private void SaveChildren(ref IContentRepository contentRepository, int parentID, ref List all)
{
    foreach (var ii in all.ToList().Where(x => x.ParentID == parentID))
    {
        // Fixed id's
        var parent = this.GetParentReference(ii.ParentID, ref all);

        if (parent != null)
        {
            // TODO: Your ID
            if (ii.PageTypeID == 20)
            {
                // Office
                var page = contentRepository.GetDefault<Office.Models.OfficePage>(parent);
                page.PageName = ii.PageName;
                page.VisibleInMenu = true;
                page[MetaDataProperties.PageChildOrderRule] =
                  ii.OtherProperties[MetaDataProperties.PageChildOrderRule];
                page[MetaDataProperties.PagePeerOrder] =
                  ii.OtherProperties[MetaDataProperties.PagePeerOrder];

                // One example of other properties
                if (ii.OtherProperties.ContainsKey("OfficeID"))
                {
                    page.OfficeID = ii.OtherProperties["OfficeID"].ToInt();
                }

                ii.NewContentReference = contentRepository.Save(
                  page, SaveAction.Publish, AccessLevel.NoAccess);
            }

            // TODO: Your ID
            if (ii.PageTypeID == 22)
            {
                // Person
                var page = contentRepository.GetDefault<Models.AddressBookPersonPage>(parent);
                page.PageName = ii.PageName;
                page.VisibleInMenu = false;
                page[MetaDataProperties.PageChildOrderRule] =
                  ii.OtherProperties[MetaDataProperties.PageChildOrderRule];
                page[MetaDataProperties.PagePeerOrder] =
                  ii.OtherProperties[MetaDataProperties.PagePeerOrder];

                // One example of other properties
                if (ii.OtherProperties.ContainsKey("Title"))
                {
                    page.Title = ii.OtherProperties["Title"];
                }

                ii.NewContentReference = contentRepository.Save(
                  page, SaveAction.Publish, AccessLevel.NoAccess);
            }

            if (ii.NewContentReference != null)
            {
                this.SaveChildren(ref contentRepository, ii.ID, ref all);
            }
        }
    }
}

private ContentReference GetParentReference(int oldParentId, ref List all)
{
    var list = all.ToList().Where(x => x.ID == oldParentId);

    if (list.Any())
    {
        return list.First().NewContentReference;
    }

    return PageReference.WasteBasket;
}

Worked great in my case (30 000+ pages) and hopefully this way could be an option for someone else as well.

Published and tagged with these categories: Episerver, ASP.NET, Development