The following post shows functionality on mapping a Kentico CMS TreeNode object to a strong type .NET model class. These functions use reflection to map a property in a class to a Kentico document type field.
The examples below assumes your Document Types in Kentico have a corresponding .NET model class.
Below is the base class BaseModel that all model classes inherit from:
using CMS.PortalControls;
using CMS.DocumentEngine;
using CMS.CMSHelper;
using CMS.SettingsProvider;
public abstract class BaseModel
{
// define document id
public int id
{
get { return Document == null ? 0 : Document.DocumentID; }
}
// define node id
public int NodeId
{
get { return Document != null ? Document.NodeID : 0; }
}
// define name
public string DocumentName
{
get { return Document != null ? Document.DocumentName : “”; }
}
// define url
public string URL
{
get { return Document == null ? “” : Document.RelativeURL.Replace(“~”,“”); }
}
// define url with extension
public string URLWithExtension
{
get { return URL + (Document == null ? “” : Document.DocumentExtensions); }
}
// external url
public string ExternalURL
{
get { return Document == null ? “” : Document.AbsoluteURL; }
}
// path for searching
public string Path
{
get { return Document == null ? “” : URL + (!URL.EndsWith(“/”) ? “/” : “”) + “%”; }
}
// define document
public TreeNode Document { get; set; }
// define function that maps extra properties
public abstract void MapExtras();
}
The following are helper types to define an Image and a Generic Document:
public class Image
{
// fields
public string Guid { get; set; }
// function that checks if an image
public bool HasImage { get { return !String.IsNullOrEmpty(Guid); } }
// define path for the image
public string Path
{
get { return String.Format(“/getfile/{0}/img/”, Guid); }
}
// function that returns the html tag for this image
public string ToHtml(string alt)
{
// check if no guid
if (String.IsNullOrEmpty(Guid))
return “”;
// return the html tag for this image
return String.Format(”
”, Path, alt);
}
}
public class GenericDocument : BaseModel
{
public override void MapExtras() { }
}
Below is a generic mapper function to map a given TreeNode and return the requested type:
public static T MapTo(TreeNode document) where T : BaseModel, new() { // init item T item = new T(); // check if a document passed if (document != null) { // set the document item.Document = document; // go through each of this model’s properties foreach (var p in item.GetType().GetProperties()) { // check if a writeable property if (p.CanWrite) { // check primitive types if (p.PropertyType == typeof(string)) { p.SetValue(item, document.GetStringValue(p.Name, “”), null); } else if (p.PropertyType == typeof(int)) { p.SetValue(item, document.GetIntegerValue(p.Name, 0), null); } else if (p.PropertyType == typeof(bool)) { p.SetValue(item, document.GetBooleanValue(p.Name, false), null); } else if (p.PropertyType == typeof(double)) { p.SetValue(item, document.GetDoubleValue(p.Name, 0), null); } else if (p.PropertyType == typeof(Guid)) { p.SetValue(item, document.GetGuidValue(p.Name, new Guid()), null); } else if (p.PropertyType == typeof(DateTime)) { p.SetValue(item, document.GetDateTimeValue(p.Name, DateTime.Parse(“1/1/1900”).Date), null); } // check complex types else if (p.PropertyType == typeof(Image)) { p.SetValue(item, new Image { Guid = document.GetStringValue(p.Name, “”) }, null); } else if (p.PropertyType == typeof(GenericDocument)) { p.SetValue(item, MapTo (GetDocumentFromGUID(document.GetStringValue(p.Name, “”))), null); } } } // map extras item.MapExtras(); } // return the item return item; }
Below is a generic mapper function to map a given TreeNodeDataSet and return a list of the requested type:
public static ListMapToList (TreeNodeDataSet documentList) where T : BaseModel, new() { // define return list List list = new List (); // check if a document list if (documentList != null) { // go through each foreach (var n in documentList) { list.Add(MapTo (n)); } } // return return list; }
Below are helper functions needed for mapping:
// function that gets a tree node from guid
public static TreeNode GetDocumentFromGUID(string guidStr)
{
// check if no guid
Guid guid;
if (Guid.TryParse(guidStr, out guid))
{
// get a tree provider
var th = new TreeProvider();
// find the node
var n = th.SelectSingleNode(guid, CultureCode, CMSContext.CurrentSiteName);
// check if a node
if (n != null)
{
return DocumentHelper.GetDocument(n, th);
}
}
// if here, return nothing
return null;
}
// function that gets a tree node from id
public static TreeNode GetDocumentFromID(int id)
{
// check if no id
if (id > 0)
{
// get a tree provider
var th = new TreeProvider();
return DocumentHelper.GetDocument(id, th);
}
// if here, return nothing
return null;
}
// function that trys to find the current culture, falls back to default
public static string CultureCode
{
get
{
// return nothing if blank
return CMSContext.CurrentDocumentCulture == null ? “en-US”
: CMSContext.CurrentDocumentCulture.CultureCode;
}
}
Below is an example on using this functionality:
// blog post model
public class BlogPost : BaseModel
{
// fields
public int BlogPostID { get; set; }
public string Title { get; set; }
public DateTime PostDate { get; set; }
public string PostURL { get; set; }
public Image Photo { get; set; }
public string Author { get; set; }
public string AuthorURL { get; set; }
public string ReadMoreText { get; set; }
public override void MapExtras()
{
}
}
// example
public class Example
{
public static void GetSinglePost()
{
// get a single post from the current document
BlogPost post = Mapper.MapTo(CurrentDocument);
}
public static void GetPostList()
{
// get a list of blog posts in the path
var th = new TreeProvider();
// find the nodes
var nodes = th.SelectNodes(
CMSContext.CurrentSiteName, “/%”,
Globals.CultureCode, false,
“EXAMPLE.BlogPost”, “”, “NodeOrder”, -1, true, -1);
// get the list
List posts = Mapper.MapToList(nodes).OrderBy(x => x.Document.NodeOrder).ToList();
}
}