Migrate page attributes to custom fields
IMPORTANT: Custom pages attributes is no longer the recommended approach to add dynamic fields to pages. Sitefinity CMS since version 7.0 provides the Custom fields feature, which you should use instead.
Custom fields differ from page attributes in that they provide more extensibility in storing different types of data. They are easier to use for developers, because they mimic static properties better.
Use the following code sample to migrate attributes to custom fields:
PREREQUISITES: Before the migration you must create custom field for Pages. Follow the procedure Create custom fields. After you create the custom field, to set the attribute value, use
pageNode.SetValue("{CustomFieldName}", value)where theCustomFieldNamecorresponds to the name of your custom field.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Telerik.Sitefinity.Abstractions;
using Telerik.Sitefinity.Modules.Pages;
using Telerik.Sitefinity.Model;
using ServiceStack.Text;
namespace Telerik.Sitefinity.Documentation.CodeSnippets.DevGuide.SitefinityEssentials.Pages.CustomFields
{
public partial class PagesCustomFieldsSnippets
{
public void MigrateAttributes()
{
var manager = PageManager.GetManager();
var pageIds = manager.GetPageNodes().Where(x => x.RootNodeId != SiteInitializer.BackendRootNodeId).Select(x => x.Id).ToList();
int commitCounter = 0;
foreach (var id in pageIds)
{
var pageNode = manager.GetPageNode(id);
if (pageNode.Attributes.Count > 0)
{
foreach (var attr in pageNode.Attributes)
{
var type = GetEntryType(attr.Key, attr.Value);
if (type == typeof(Boolean))
{
var value = Boolean.Parse(attr.Value);
pageNode.SetValue("MigratedBool", value);
}
else if (type == typeof(Int32))
{
var value = Int32.Parse(attr.Value);
pageNode.SetValue("MigratedInt", value);
}
else if (type == typeof(Object[]))
{
var value = JsonSerializer.DeserializeFromString<Object[]>(attr.Value);
//here you should see if this property is a choice field or a guid array
//and appropriately handle the parsing of the objects
//set the guids
pageNode.Organizer.AddTaxa("Tags", value.Select(x => Guid.Parse(x.ToString())).ToArray());
//or set the choices
//pageNode.SetValue("MigratedChoices", value.Select(x => x.ToString()).ToArray());
}
else if (type == typeof(Lstring))
{
var value = attr.Value;
pageNode.SetString("MigratedString", value);
}
}
commitCounter++;
}
if (commitCounter == 10)
{
manager.SaveChanges();
commitCounter = 0;
}
manager.SaveChanges();
}
}
private Type GetEntryType(string key, string value)
{
if (!string.IsNullOrEmpty(value) && value.StartsWith("[") && value.EndsWith("]"))
return typeof(Object[]);
string typeSufix = null;
var underscoreLocation = key.LastIndexOf('_');
if (underscoreLocation > 0 && underscoreLocation < (key.Length - 2))
{
typeSufix = key.Substring(underscoreLocation + 1);
}
if (!string.IsNullOrEmpty(typeSufix))
{
switch (typeSufix.ToLowerInvariant())
{
case "boolean":
return typeof(Boolean);
case "integer":
return typeof(Int32);
}
}
return typeof(Lstring);
}
}
}
NOTE: After the migration is completed you must change the configuration of the
FieldControlsin the backend. In theDataFieldNameproperty, replaceAttributeswithCustomFields. For example, replaceAttributes.SampleTextwithCustomFields.SampleText.