Searching for a channel is a common task in CMS. There are a few different ways to search in CMS.
- CmsHttpContext.Current.Searches.GetByGuid
- CmsHttpContext.Current.Searches.GetByPath
- CmsHttpContext.Current.Searches.GetByUrl
- CmsHttpContext.Current.Searches.GetChannelsByCustomProperty
One of the ways that you cannot search for a channel is by the channel’s name. This is because multiple channels can exist with the same name. The best way to search for a channel is by using CmsHttpContext.Current.Searches.GetByGuid. However, there are occasions when none of these options will work. (....Current.Searches can be used to search for more than just channels. Click here for more info)
Scenario
- The existing production environment’s architecture cannot change. The new CMS application must co-exist peacefully without any impact to the existing web applications.
- The database that drives the business will be used by both environments.
- The existing system has a way of linking a site to an ID. This is how customer accounts are associated with each site in the database. One database for all sites.
- There will be several CMS sites. Each new site will map the channel name to the host header name (the sites “main” channel in CMS). This will allow each CMS aware site to use the same code base and the same set of templates.
- The site’s ID must be known upfront in order to perform essential business functions.
The problem that arises is this; what is the best way to find the site’s ID? A mapping table in a database that maps the URL to an ID is one possibility. But using a custom channel property is another. Each site can now have a SiteID and since the method walks up the hierarchy, it will always stop when the root channel is reached and the main channel is found. This will prevent ID's from being mixed-up.
Since each site will have an ID, we can create a custom property at the top level channel (just below the root) called “SiteID” as shown below.

The SiteID is not known when the customer first visits. The customer could potentially enter the site at any point in the hierarchy (if allowed by bookmarking, linking, etc.). How can the site’s ID be found? Since there will be many sites within CMS that have a custom property called “SiteID”, searching by the custom property name is not an option. This would cause each site’s main channel to be returned with the results.
Solution:
Create a class that encapsulates the channel and its properties and look for the site’s main channel by iterating up the hierarchy. Place the following code in the class in the appropriate places:
using
Microsoft.ContentManagement.Publishing;
//The context:
protected CmsHttpContext _cmsContext;
//The constructor:
public CustomChannelProperties()
{
//Set the current context
_cmsContext = CmsHttpContext.Current;
}
//This method will return the site’s ID. Pass in the property that is being searched for. In this case its "SiteID."
//A call to GetSiteMainChannelPropertyValue is made to retrieve the channel’s custom property collection.
public string GetSiteMainChannelPropertyValue(string propertyName)
{
return GetSiteMainChannelProperties()[propertyName].Value;
}
//GetSiteMainChannelProperties will walk up the hierarchy until the site’s main channel is found.
//Scope this method as public. You may want to reuse this method later to retrieve the entire custom property collection.
public CustomPropertyCollection GetSiteMainChannelProperties()
{
CustomPropertyCollection siteMainCustomProperties;
//Make sure the current channel is not the root.
if(_cmsContext.Channel.IsRoot)
{
//If this is the root channel, which it should never be, throw an error.
throw new ApplicationException("Custom properties of the root channel is not permitted.");
}
else
{
//Begin the search, if successful, return the custom properties, else return null.
Channel siteMainChannel = MainSiteChannelSearch(_cmsContext.Channel);
if(siteMainChannel != null)
siteMainCustomProperties = siteMainChannel.CustomProperties;
else
siteMainCustomProperties = null;
}
return siteMainCustomProperties;
}
//This method will walk the hierarchy until the parent is found.
private Channel MainSiteChannelSearch(Channel parentChannel)
{
if(parentChannel.Parent.IsRoot)
//site's main channel has been found. Return
return parentChannel;
else
//The parent of this channel is not the root so this channel cannot be the site's main channel.
//Make a recursive call to continue the search up the hierarchy.
return MainSiteChannelSearch(parentChannel.Parent);
}
The value of “SiteID“ is returned to the calling method once the main channel is found.
This solution does not require the channel’s name nor does it require anything specific other than the property’s name to retrieve the value. The current channel is known because it is kept in the CmsHttpContext object.
For more information: CMS 2002, Channel, Searches, CustomPropertyCollection, Newsgroup, MCMS 2002 FAQ
--Mark